如何使用 Apache Http 从另一个 GET 调用下载文件?

How to download a file from another GET call using Apache Http?

我正在尝试使用 REST 从本地 Jasper 服务器下载文件 API:

http: // : / jasperserver [-pro] / rest_v2 / reportExecutions / requestID / exports / exportID / outputResource

我的兴趣是我想阻止我的客户端在服务器上保存文件,我想使用之前的 GET 调用的输出直接下载(作为一个小桥,仅此而已)。

我一直在使用 Apache Http API 来执行此操作。以前我必须进行其他调用来进行身份验证,请求资源,现在....下载它。

我的问题是,当我下载文件时,它带有 0kb 并且浏览器报告文件已损坏(我想下载的是 pdf)。

这是我用来下载文件的代码。

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {      
    String username = request.getParameter("username");
    String pass = request.getParameter("pass");
    
    String fileType = "pdf"; // request.getParameter("type") pdf o xls
            
    CloseableHttpClient httpClient = HttpClients.createDefault();
    CookieStore cookieStore = new BasicCookieStore();
    HttpContext httpContext = new BasicHttpContext();
    httpContext.setAttribute(HttpClientContext.COOKIE_STORE, cookieStore);
    
    List<NameValuePair> urlParameters = new ArrayList<>();
    urlParameters.add(new BasicNameValuePair("j_username",username));
    urlParameters.add(new BasicNameValuePair("j_password",pass));   
    
    boolean valid = executeAuthenticationValidation(urlParameters,response,httpClient,httpContext);
    
    if(valid) {
        ReportObject repObj = requestJasperReport(request.getParameter("params"),fileType,response,httpClient,httpContext);
        
        if(repObj != null) {

            String requestId = repObj.requestId;
            String exportId = repObj.exports.get(0).id;
            HttpGet get = new HttpGet("http://localhost:8081/jasperserver/rest_v2/reportExecutions/"+requestId+"/exports/"+exportId+"/outputResource");
            
            int rescod;
            HttpEntity content;
            
            String name;
            String filetype;
            
            try (CloseableHttpResponse chres = httpClient.execute(get,httpContext);) {
                StatusLine status = chres.getStatusLine();
                rescod = status.getStatusCode();
                name = chres.getFirstHeader("Content-Disposition").getValue().split(";")[1];
                filetype = chres.getFirstHeader("Content-Type").getValue();
                content = chres.getEntity();
            }
            
            if(rescod==200) {
                
                response.setContentType(filetype);
                response.setHeader("Content-disposition", name);

                try (InputStream in = content.getContent();
                        OutputStream out = response.getOutputStream()) {

                    byte[] buffer = new byte[1024];

                    int numBytesRead;
                    while ((numBytesRead = in.read(buffer)) > 0) {
                        out.write(buffer, 0, numBytesRead);
                    }
                }
                httpClient.close();
            }
        }           
    } else {
        // Error
    }
}

好的,大声笑我的坏蛋,当您没有正确控制资源的 Try-catch 时,就会发生这种情况。只需在 Try 块中移动一些代码:

if(repObj != null) {

            String requestId = repObj.requestId;
            String exportId = repObj.exports.get(0).id;
            HttpGet get = new HttpGet("http://localhost:8081/jasperserver/rest_v2/reportExecutions/"+requestId+"/exports/"+exportId+"/outputResource");
            
            HttpEntity content;
            
            String name;
            String filetype;
            
            try (CloseableHttpResponse chres = httpClient.execute(get,httpContext);) {
                StatusLine status = chres.getStatusLine();
                name = chres.getFirstHeader("Content-Disposition").getValue().split(";")[1];
                filetype = chres.getFirstHeader("Content-Type").getValue();
                content = chres.getEntity();
                
                if(status.getStatusCode()==200) {
                    
                    response.setContentType(filetype);
                    response.setHeader("Content-disposition", name);
                    response.setHeader("Content-Length", String.valueOf(content.getContentLength()));

                    try (InputStream in = content.getContent();
                            OutputStream out = response.getOutputStream()) {

                        byte[] buffer = new byte[1024];

                        int numBytesRead;
                        while ((numBytesRead = in.read(buffer)) > 0) {
                            out.write(buffer, 0, numBytesRead);
                        }
                    }
                    httpClient.close();
                }
            }
            
        }           
    } else {
        // Error
    }

我得到了 0kb,因为 InputStream 提前关闭了它。