使用 JSP 和 Servlet 处理多个提交按钮
Handling multiple submit buttons with JSP and Servlets
我有一个从数据库生成的 table。此 table 将附在表格中。以下是浏览器上的结果:
http://i.imgur.com/NLZzgwP.png(低代表问题)
下面是JSP/JSTL代码:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Issues</title>
<style type="text/css">
table {
border-collapse: collapse;
}
table, th, td {
border: 1px solid black;
}
td {
padding: 10px;
}
</style>
</head>
<body>
<sql:setDataSource
var="myDS"
driver="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/pdfdb"
user="user" password="*******"
/>
<sql:query var="listIssues" dataSource="${myDS}">
SELECT BookId from Book;
</sql:query>
<form method="get" action="fileDownload">
<div align="center">
<table>
<caption>List of Issues</caption>
<tr>
<th>Magazine Issue #</th>
<th>Download</th>
</tr>
<c:forEach var="issue" items="${listIssues.rows}">
<tr>
<td><c:out value="${issue.BookId}" /></td>
<td><input name='<c:out value="${issue.BookId}" />' type="submit" value="Download"></td>
</tr>
</c:forEach>
</table>
</div>
</form>
</body>
</html>
现在,我想要的是将下载按钮链接到与按钮位于同一行的 id/Issue 数字,这样,当用户单击下载按钮时,它将 id/magazine 期号传递给 url 告诉浏览器用户想要下载所点击按钮对应的杂志期号。下面是我用来实现这个的 servlet:
package com.mypackage.fileDownload;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class FileDownloadServlet
*/
@WebServlet("/fileDownload")
public class FileDownloadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
//size of byte buffer to send file
private static final int BUFFER_SIZE = 4096;
//database connection settings
private String dbUrl = "jdbc:mysql://localhost:3306/pdfdb";
private String dbUser = "user";
private String dbPass = "******";
/**
* @see HttpServlet#doGet(HttpServletRequesrequest,HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//get upload id from URL's parameters
String uploadId = request.getParameter("name");
Connection con = null; //connects to the database
try {
//connects to the database
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection(dbUrl, dbUser, dbPass);
//queries the database
String sql = "SELECT * FROM Book WHERE BookId = ?";
PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setString(1, uploadId);
ResultSet result = pstmt.executeQuery();
if(result.next()) {
//gets file name and file blob data
String fileId = result.getString("BookId");
Blob blob = result.getBlob("BookContent");
InputStream inputStream = blob.getBinaryStream();
int fileLength = inputStream.available();
System.out.println("File length = " + fileLength);
ServletContext context = getServletContext();
//Sets MIME type for the file download
String mimeType = context.getMimeType(fileId);
if(mimeType == null) {
mimeType = "application/octet-stream";
}
//set content properties and header attributes for the response
response.setContentType(mimeType);
response.setContentLength(fileLength);
String headerKey = "Content-Disposition";
String headerValue = String.format("attachment; filename=\"%s\"", fileId);
response.setHeader(headerKey, headerValue);
//writes the file to the client
OutputStream outStream = response.getOutputStream();
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = -1;
while((bytesRead = inputStream.read(buffer)) != -1) {
outStream.write(buffer, 0, bytesRead);
}
inputStream.close();
outStream.close();
} else {
//no file found
response.getWriter().print("File not found for the id: " + uploadId);
}
} catch(SQLException ex) {
ex.printStackTrace();
response.getWriter().print("SQL Error: " + ex.getMessage());
} catch(IOException ex) {
ex.printStackTrace();
response.getWriter().print("IO Error: " + ex.getMessage());
} catch(ClassNotFoundException ex) {
ex.printStackTrace();
response.getWriter().print("Class Missing Error: " + ex.getMessage());
}
finally {
if(con != null) {
//closes the database connection
try {
con.close();
} catch(SQLException ex) {
ex.printStackTrace();
}
}
}
}
}
好吧,从我这样做的方式来看,它没有按照我想要的方式工作。例如,如果您 运行 服务器上的此代码并单击任何下载按钮, url 将类似于
issue.jsp?1=Download
即weird.It也会显示在浏览器上
File not found for the id: null
我希望(在 url 上)
issue.jsp?Download=1
其中 1 是正在下载的问题。我的数据库有两列:IssueId 和 fileContent(存储在 BLOB 中的文件内容)。
我觉得我解释的够多了,概念也清楚了。任何帮助将不胜感激,这是我的代码和研究所能达到的最大程度。谢谢!
最简单的方法是将表格移动到 table 中并做多个表格:
<div align="center">
<table>
<caption>List of Issues</caption>
<tr>
<th>Magazine Issue #</th>
<th>Download</th>
</tr>
<c:forEach var="issue" items="${listIssues.rows}">
<tr>
<td><c:out value="${issue.BookId}" /></td>
<td>
<form method="get" action="fileDownload">
<input type='hidden' name='bookid' value='<c:out value="${issue.BookId}" />' />
<input type="submit" value="Download">
</form>
</td>
</tr>
</c:forEach>
</table>
</div>
您还需要将值从按钮的 name
属性中移出并移到隐藏输入的 value
属性中。该隐藏输入需要一个 name
,您将使用它来获取 servlet 中的值:request.getParameter("bookid");
我有一个从数据库生成的 table。此 table 将附在表格中。以下是浏览器上的结果:
http://i.imgur.com/NLZzgwP.png(低代表问题)
下面是JSP/JSTL代码:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Issues</title>
<style type="text/css">
table {
border-collapse: collapse;
}
table, th, td {
border: 1px solid black;
}
td {
padding: 10px;
}
</style>
</head>
<body>
<sql:setDataSource
var="myDS"
driver="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/pdfdb"
user="user" password="*******"
/>
<sql:query var="listIssues" dataSource="${myDS}">
SELECT BookId from Book;
</sql:query>
<form method="get" action="fileDownload">
<div align="center">
<table>
<caption>List of Issues</caption>
<tr>
<th>Magazine Issue #</th>
<th>Download</th>
</tr>
<c:forEach var="issue" items="${listIssues.rows}">
<tr>
<td><c:out value="${issue.BookId}" /></td>
<td><input name='<c:out value="${issue.BookId}" />' type="submit" value="Download"></td>
</tr>
</c:forEach>
</table>
</div>
</form>
</body>
</html>
现在,我想要的是将下载按钮链接到与按钮位于同一行的 id/Issue 数字,这样,当用户单击下载按钮时,它将 id/magazine 期号传递给 url 告诉浏览器用户想要下载所点击按钮对应的杂志期号。下面是我用来实现这个的 servlet:
package com.mypackage.fileDownload;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class FileDownloadServlet
*/
@WebServlet("/fileDownload")
public class FileDownloadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
//size of byte buffer to send file
private static final int BUFFER_SIZE = 4096;
//database connection settings
private String dbUrl = "jdbc:mysql://localhost:3306/pdfdb";
private String dbUser = "user";
private String dbPass = "******";
/**
* @see HttpServlet#doGet(HttpServletRequesrequest,HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//get upload id from URL's parameters
String uploadId = request.getParameter("name");
Connection con = null; //connects to the database
try {
//connects to the database
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection(dbUrl, dbUser, dbPass);
//queries the database
String sql = "SELECT * FROM Book WHERE BookId = ?";
PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setString(1, uploadId);
ResultSet result = pstmt.executeQuery();
if(result.next()) {
//gets file name and file blob data
String fileId = result.getString("BookId");
Blob blob = result.getBlob("BookContent");
InputStream inputStream = blob.getBinaryStream();
int fileLength = inputStream.available();
System.out.println("File length = " + fileLength);
ServletContext context = getServletContext();
//Sets MIME type for the file download
String mimeType = context.getMimeType(fileId);
if(mimeType == null) {
mimeType = "application/octet-stream";
}
//set content properties and header attributes for the response
response.setContentType(mimeType);
response.setContentLength(fileLength);
String headerKey = "Content-Disposition";
String headerValue = String.format("attachment; filename=\"%s\"", fileId);
response.setHeader(headerKey, headerValue);
//writes the file to the client
OutputStream outStream = response.getOutputStream();
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = -1;
while((bytesRead = inputStream.read(buffer)) != -1) {
outStream.write(buffer, 0, bytesRead);
}
inputStream.close();
outStream.close();
} else {
//no file found
response.getWriter().print("File not found for the id: " + uploadId);
}
} catch(SQLException ex) {
ex.printStackTrace();
response.getWriter().print("SQL Error: " + ex.getMessage());
} catch(IOException ex) {
ex.printStackTrace();
response.getWriter().print("IO Error: " + ex.getMessage());
} catch(ClassNotFoundException ex) {
ex.printStackTrace();
response.getWriter().print("Class Missing Error: " + ex.getMessage());
}
finally {
if(con != null) {
//closes the database connection
try {
con.close();
} catch(SQLException ex) {
ex.printStackTrace();
}
}
}
}
}
好吧,从我这样做的方式来看,它没有按照我想要的方式工作。例如,如果您 运行 服务器上的此代码并单击任何下载按钮, url 将类似于
issue.jsp?1=Download
即weird.It也会显示在浏览器上
File not found for the id: null
我希望(在 url 上)
issue.jsp?Download=1
其中 1 是正在下载的问题。我的数据库有两列:IssueId 和 fileContent(存储在 BLOB 中的文件内容)。
我觉得我解释的够多了,概念也清楚了。任何帮助将不胜感激,这是我的代码和研究所能达到的最大程度。谢谢!
最简单的方法是将表格移动到 table 中并做多个表格:
<div align="center">
<table>
<caption>List of Issues</caption>
<tr>
<th>Magazine Issue #</th>
<th>Download</th>
</tr>
<c:forEach var="issue" items="${listIssues.rows}">
<tr>
<td><c:out value="${issue.BookId}" /></td>
<td>
<form method="get" action="fileDownload">
<input type='hidden' name='bookid' value='<c:out value="${issue.BookId}" />' />
<input type="submit" value="Download">
</form>
</td>
</tr>
</c:forEach>
</table>
</div>
您还需要将值从按钮的 name
属性中移出并移到隐藏输入的 value
属性中。该隐藏输入需要一个 name
,您将使用它来获取 servlet 中的值:request.getParameter("bookid");