使用Java中的HTTPClient下载文件

时间:2016-02-16 16:47:53

标签: javascript java apache-httpclient-4.x

我正在尝试编写一个登录到网站的java程序,在搜索引擎中输入,获取结果,然后下载从结果生成的excel文件。到目前为止,我可以登录确定。并发送搜索并获得结果。但是,我在下载excel文件时遇到了很多问题。

查看网站的源代码,我看到了excel文件周围的Ajax和Javascript,所以我假设它是ajax,有助于产生它。

<input id="toexcel" type="image" src="/websmart/v9.4/XLGP/images/Excel-icon.png" alt="To Excel" title="To Excel: Max 20000 Records" onclick="" />

JavaScript部分:

$( document ).ready(function() {

        $('#toexcel').click(function(e) { 
            e.preventDefault();

            setTask('toexcel');

            var ajaxForm = $("#filter-form");


            $(".spinner").show();

                var dataToSend = ajaxForm.serialize();
                $("#excelFrame").attr('src','V7BAE01R.pgm' + '?' + dataToSend);
            setTimeout(function() {
                            $(".spinner").hide();
                        }, 5000 );

使用TamperData,当我点击Excel文件导出时,它会发送一个帖子请求(我设法在代码的最后部分发送),但我不知道从哪里获取它。我确实在tamperdata中看到了Get that say Application / vnd.ms-excel

enter image description here

我不知道如何添加代码来获取excel文件。下面,我尝试使用BufferReader,但它没有得到我的文件。由于名称值对,我简化了一些代码。

import java.util.List;
import java.util.ArrayList;
import org.apache.http.*;
import java.io.*;

import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.*;
import org.apache.http.impl.client.*;
import org.apache.http.message.*;
import org.apache.http.util.EntityUtils;
import org.apache.http.client.entity.*;
public class httpClientTest {



    public static void main (String[] args) throws ClientProtocolException, IOException {
            //Set up HttpClient
            CloseableHttpClient httpclient = HttpClients.createDefault();
            HttpGet httpGet = new HttpGet("http://website");
            CloseableHttpResponse response = httpclient.execute(httpGet);

            //Create Post request to log into the AS400 website
            HttpPost httpPost = new HttpPost("http://loginwebsite");

            List <NameValuePair> nvps = new ArrayList <NameValuePair>();

            nvps.add(new BasicNameValuePair("user","username"));
            nvps.add(new BasicNameValuePair("password","password"));
            nvps.add(new BasicNameValuePair("button", "Login"));
            nvps.add(new BasicNameValuePair("task", "extlogin"));
            httpPost.setEntity(new UrlEncodedFormEntity(nvps));
            response = httpclient.execute(httpPost);

            //Get Post response to ensure we logged in, which succeeds
            try{
                System.out.println(response.getStatusLine());   
                HttpEntity entity = response.getEntity();
                EntityUtils.consume(entity);
            } finally{
                response.close();
            }

            //Sent a Post request to filters out recoreds.
            httpPost = new HttpPost("http://searchresults");
            nvps.clear();
            nvps.add(new BasicNameValuePair("ActSts", "Edit"));
            nvps.add(new BasicNameValuePair("task", "filter"));
            nvps.add(new BasicNameValuePair("Field", "Plant"));
            response = httpclient.execute(httpPost);

            //Displays in printline the html/js of the page. This looks like it DOES display the search results
            //So it IS sending the Post request and receiving a response.
            BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); 
            String line = "";
            while ((line = rd.readLine()) != null) {
                System.out.println(line);
            }

        //try to buffer to read in.
        String link = "http://website.com/uri?ActSts=Edit&task=filter&Field=Plant";
        HttpGet get = new HttpGet(link);
        response = httpclient.execute(get);

        InputStream is = response.getEntity().getContent();
        String filePath = "C:\\Users\\WindowsUserName\\Downloads\\WODETAIL_List.xls";
        FileOutputStream fos = new FileOutputStream(new File(filePath));
        int inByte;
        while((inByte = is.read()) != -1)
            fos.write(inByte);
        is.close();
        fos.close();

我很确定我正在发布数据,但我不确定如何获取excel文件。有人可以提供一些帮助吗?

编辑我可以下载文件,但它不是excel文件。这是一个网页,我认为这有点改进。 (之前,没有下载,它只是挂在那里)问题是,我想我需要发送授权密钥或cookie与此get请求下载文件。

编辑2 我发现如果我只是在登录时粘贴到新选项卡中的 http://website.com/uri?ActSts=Edit&task=filter&Field=Plant ,等待一会儿后,我会得到一个链接到excel文件。所以最初我认为只要使用相同的httpclient,HTTPClient就会保持相同的cookie,但显然它不会(?)我想我必须找到一种方法来获取cookie并发送它。

1 个答案:

答案 0 :(得分:2)

天啊,我终于得到了一些有用的东西。好。所以显然HTTPClient在开始出错之前只能处理2个响应,根据这里:Why does me use HttpClients.createDefault() as HttpClient singleton instance execute third request always hang

相反,我将代码更改为只获取登录响应,然后将excel文件作为响应然后退出。我还添加了一些超时配置,并且还更改了首先导出文件然后使用实体的顺序。我使用了单独的第二个响应和第二个实体。这似乎也有所帮助?我猜。

import java.util.List;
import java.util.ArrayList;
import org.apache.http.*;
import java.io.*;

import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.*;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.conn.ConnectionPoolTimeoutException;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.*;
import org.apache.http.message.*;
import org.apache.http.util.EntityUtils;
import org.apache.http.client.entity.*;


public class hcFeb {

public static void main (String[] args) throws ClientProtocolException, IOException {
    //Set up Cookie settings and also Timeout settings
    CookieStore cookieStore = new BasicCookieStore();
    HttpClientContext context = HttpClientContext.create();
    context.setCookieStore(cookieStore);

    int CONNECTION_TIMEOUT = 80000;
    RequestConfig requestConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.DEFAULT)
            .setConnectionRequestTimeout(CONNECTION_TIMEOUT)
            .setConnectTimeout(CONNECTION_TIMEOUT)
            .setSocketTimeout(CONNECTION_TIMEOUT)
            .build();

    //Set up HttpClient
    CloseableHttpClient httpclient = HttpClients.custom().setDefaultRequestConfig(requestConfig).setDefaultCookieStore(cookieStore).disableContentCompression().build();

    HttpGet httpGet = new HttpGet("http://website");
    CloseableHttpResponse response = httpclient.execute(httpGet);

    //Create Post request to log into the website
    HttpPost httpPost = new HttpPost("http://loginwebsite");

    //Login to website
     List <NameValuePair> nvps = new ArrayList <NameValuePair>();

        nvps.add(new BasicNameValuePair("user","username"));
        nvps.add(new BasicNameValuePair("password","password"));
        nvps.add(new BasicNameValuePair("button", "Login"));
        nvps.add(new BasicNameValuePair("task", "extlogin"));
        httpPost.setEntity(new UrlEncodedFormEntity(nvps));
        response = httpclient.execute(httpPost);


    try{
        System.out.println(response.getStatusLine());   
        HttpEntity entity = response.getEntity();
        EntityUtils.consume(entity);                
    } finally{
    }

    //Send request for Excel file and download it.
    String link = "http://website.com/uri?ActSts=Edit&task=filter&Field=Plant";
    HttpGet get = new HttpGet(link);

    //maybe create new response
    HttpResponse response2;

    try{
        response2 = httpclient.execute(get,context);
        System.out.println(response2.getStatusLine());  
        HttpEntity entity1 = response2.getEntity();


        if (entity1 != null) {
            System.out.println("Entity isn't null");

            InputStream is = entity1.getContent();
            String filePath = "C:\\Users\\windowsUserName\\Downloads\\WODETAIL_List.xls";
            FileOutputStream fos = new FileOutputStream(new File(filePath));

            byte[] buffer = new byte[5600];
            int inByte;
            while((inByte = is.read(buffer)) > 0)
                fos.write(buffer,0,inByte);
            is.close();
            fos.close();

            System.out.println("Excel File recieved");                  


            EntityUtils.toString(response2.getEntity());
            EntityUtils.consume(entity1);

        }

    } catch (ConnectionPoolTimeoutException e){
        //response.close();
        System.out.println(e.getMessage());
    } catch (IOException e){
        System.out.println(e.getMessage());
    }

}

}