首页 > 解决方案 > 通过托管在 AWS 上的 servlet 从 mySQL DB 下载文件

问题描述

我目前正在创建一个网页,该网页显示包含来自 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)

小服务程序代码:

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 服务器上运行

更新:经过一些研究,我认为获取客户端下载文件夹的路径是不可能的。现在我想我需要创建一个“另存为”对话框。任何有关如何执行此操作的提示以及可以帮助我执行此操作的资源都将不胜感激

标签: mysqlamazon-web-servicesservlets

解决方案


我能够使用此处发布的问题中的代码让我的 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);
        } 
    }

推荐阅读