我当前正在创建一个网页,该网页显示包含来自Mysql DB的数据的表。列之一是文件(在数据库中存储为BLOB)。该文件的名称是一个链接到我的download.java servlet的锚标记。我的下载servlet在本地部署时可以使用,但是现在我已经部署到AWS ElasticBeanstalk实例,该servlet无法使用。
在日志中显示以下内容:
org.apache.coyote.http11.AbstractHttp11Processor.process Error parsing HTTP request header
Note: further occurrences of HTTP header parsing errors will be logged at DEBUG level.
java.lang.IllegalArgumentException: Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986
和
/usr/share/tomcat8/Downloads/sdc.png (No such file or directory)
servlet代码:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
try {
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "dbURL?serverTimezone=" + TimeZone.getDefault().getID();
Connection conn = DriverManager.getConnection(url , "username" , "password");
String fn = request.getParameter("Id");
String selectSQL = "SELECT file FROM Requests WHERE fileID=?";
PreparedStatement pstmt = conn.prepareStatement(selectSQL);
pstmt.setString(1, fn);
ResultSet rs = pstmt.executeQuery();
// write binary stream into file
String home = System.getProperty("user.home");
File file = new File(home+"/Downloads/" + fn);
FileOutputStream output = new FileOutputStream(file);
System.out.println("Writing to file " + file.getAbsolutePath());
while (rs.next()) {
InputStream input = rs.getBinaryStream("file");
byte[] buffer = new byte[1024];
while (input.read(buffer) > 0) {
output.write(buffer);
}
}
RequestDispatcher rd = request.getRequestDispatcher("/requests.jsp");
rd.forward(request, response);
rs.close();
pstmt.close();
} catch (SQLException | IOException e) {
System.out.println(e.getMessage());
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Servlet应将文件从Mysql DB下载到用户下载文件夹。但是,这仅在本地工作,在失败的AWS服务器上。我认为这是因为:
String home = System.getProperty("user.home");
返回AWS服务器实例的主路径,而不是用户/访问者的主路径。
请帮助我调整servlet,使其在AWS服务器上正常工作
更新:经过一些研究,我认为无法获得客户端下载文件夹的路径。现在,我想让我们创建一个“另存为”对话框。任何有关如何执行此操作的提示以及可以帮助我完成此操作的资源
答案 0 :(得分:0)
我能够使用问题here
中发布的代码来使servlet工作我的工作代码现在看起来像这样:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Connection conn = null;
try {
// Get Database Connection.
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "dbURL?serverTimezone=" + TimeZone.getDefault().getID();
conn = DriverManager.getConnection(url , "username" , "password");
String fileName = request.getParameter("Id");
System.out.println("File Name: " + fileName);
// queries the database
String sql = "SELECT file FROM requests WHERE fileID= ?";
PreparedStatement statement = conn.prepareStatement(sql);
statement.setString(1, file);
ResultSet result = statement.executeQuery();
if (result.next()) {
// gets file name and file blob data
Blob blob = result.getBlob("file");
InputStream inputStream = blob.getBinaryStream();
int fileLength = inputStream.available();
System.out.println("fileLength = " + 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[1024];
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 fn: " + fileName);
}
} catch (Exception e) {
throw new ServletException(e);
}
}