【问题标题】:HttpURLConnection to download file from Servlet not working, direct link works从 Servlet 下载文件的 HttpURLConnection 不起作用,直接链接有效
【发布时间】:2015-05-19 05:59:42
【问题描述】:

有一个包含 8,000 多个 HTTP 链接到 PDF 文件的列表以供下载。读取每个链接并调用我的方法 downloadFile() 并将其保存到本地 Window$ PC。遇到 2 种链接格式:

  • http://example.com/docs/pdfs/Downloadable.pdf
  • http://example.com/docs/download.do?AttchmentId=2000

    第一种类型(直接)始终有效。第二个不起作用。当它将文件保存为 pdf 时,它看起来像:

    <div id="error">
        <ul>
        </ul>
    </div>
    <form id="download" name="download" method="post" action="/careManager/DownloadFormController.do?AttachmentId=2000">
    <input type="hidden" name="attachID" value="2000" >  
    </form>
    <script language="Javascript" type="text/javascript">
     document.forms[0].submit();
    </script>
    </body>
    </div>  
    

    当我在浏览器的开发人员工具中点击无效链接时,它会被 javascript 文件重定向到 HTTPS 站点(将协议更改为 HTTPS)。

    我错过了什么?

    我尝试设置 cookiehandler,将系统属性 http.strictPostRedirect 设置为 true,将连接 setFollowRedirects 和 setInstanceFollowRedirects 设置为 true,如果转发/移动,则创建新的 URL 连接,设置连接 setReadTimeout,为 SSL 创建 HttpsURLConnection。所有这些都不适用于 servlet。

    public static void downloadFile(String downloadUrl, String fileName) throws Exception {
    
        CookieHandler.setDefault( new CookieManager( null, CookiePolicy.ACCEPT_ALL ) );
        // String cookie = CookieManager.getInstance().getCookie( downloadUrl.toString() );
        URL url  = new URL( downloadUrl );
        File file = new File( "C:\\temp\\smc1\\" + fileName );
    
        HttpURLConnection c = (HttpURLConnection) url.openConnection();
        System.setProperty("http.strictPostRedirect", "true");
    
        int responseCode = c.getResponseCode();
        InputStream is;
    
        if( responseCode == HttpURLConnection.HTTP_MOVED_PERM
                || responseCode == HttpURLConnection.HTTP_MOVED_TEMP
                || responseCode == HttpURLConnection.HTTP_SEE_OTHER ) {
    
            // Get new URL (https) from HttpURLConnection frowarding
            URL newUrl = new URL( c.getHeaderField("Location") );
            HttpURLConnection sc = (HttpURLConnection) newUrl.openConnection();
    
            sc.setFollowRedirects(true);
            sc.setInstanceFollowRedirects(true);
            responseCode = sc.getResponseCode();
            // sc.setReadTimeout(15*1000);
    
            is = sc.getInputStream();
        } else {
            c.setFollowRedirects(true);
            c.setInstanceFollowRedirects(true);
            responseCode = c.getResponseCode();
            is = c.getInputStream();
        }
        // System.out.println( " Code: " + responseCode );
    
        FileOutputStream fos = new FileOutputStream( file );
    
        int bytesRead;
        byte[] buffer = new byte[ 1024 ];
        while( ( bytesRead = is.read(buffer) ) != -1 ) {
            fos.write(buffer, 0, bytesRead);
        }
    
        if( fos != null ) {
            fos.flush();
            fos.close();
        }
        if( is != null ) {
            is.close();
        }
    }  
    

    我是 servlet 的使用者,并且只有链接作为访问权限。 提前谢谢!

  • 【问题讨论】:

      标签: java servlets pdf httpurlconnection


      【解决方案1】:

      这将永远起作用,无论您编写多少额外的代码来执行Java在重定向时默认已经执行的操作。

      HTML 页面会自动发布一个表单,当浏览器加载该表单时会导致下载。 Java 代码永远不会执行它。

      【讨论】:

      • 是的。但它看起来好像可以解析生成的 HTML 并伪造一个 HTTP 发布请求,这相当于 à 浏览器会做的事情。可能值得一试。
      • @ EJP - 关于如何完成的任何想法? @GPI - 你能提供一个链接,这样我就可以学习如何做到这一点?谢谢!
      • @GPI 当然可以。浏览器做到了。但它不是 Java 内置的。
      【解决方案2】:

      我能够通过以下方式解决我的问题:

      1. 编辑我的默认浏览器的默认下载位置
      2. 开发循环以使用 url 启动浏览器并将每个文件下载到默认位置

      我的默认浏览器是 chrome。我还观察了打开了多少个选项卡以自动关闭浏览器并启动一个新的。

      【讨论】:

        猜你喜欢
        • 2014-08-10
        • 1970-01-01
        • 1970-01-01
        • 2020-12-28
        • 2023-03-15
        • 2014-08-27
        • 2012-10-05
        • 2017-08-26
        • 2018-09-13
        相关资源
        最近更新 更多