Java工具类--通过HttpClient发送http请求

本文介绍了Java中使用HttpClient库发送HTTP请求的基本步骤,包括HttpGet和HttpPost的使用,以及如何处理带参数的HttpPost请求。HttpClient提供了模拟HTML表单提交的功能,使得数据提交变得简单。示例代码展示了HttpClient的使用,并给出了相关测试用例。
                     

在写网络程序的时候,经常会有从网址获取数据的需求,上一篇解析JSON就需要从百度获取天气数据,本文介绍一种Java发送http请求的工具–HttpClient。

##HttpClient的介绍

The most essential function of HttpClient is to execute HTTP methods. Execution of an HTTP method involves one or several HTTP request / HTTP response exchanges, usually handled internally by HttpClient. The user is expected to provide a request object to execute and HttpClient is expected to transmit the request to the target server return a corresponding response object, or throw an exception if execution was unsuccessful.

HttpClient最基本的功能就是执行http方法,执行http方法包括了一次或者几次HTTP请求和相应的变化,通常也是通过HttpClient来处理的。只要用户提供一个request的对象,HttpClient就会将用户的请求发送到目标服务器上,并且返回一个respone对象,如果没有执行成功将抛出一个异常。

通过文档的介绍我们可以知道,发送HTTP请求一般可以分为以下步骤

  1. 取得HttpClient对象
  2. 封装http请求
  3. 执行http请求
  4. 处理结果

其中可以发送的请求类型有GET, HEAD, POST, PUT, DELETE, TRACE 和 OPTIONS

HttpClient supports out of the box all HTTP methods defined in the HTTP/1.1 specification: GET, HEAD, POST, PUT, DELETE, TRACE and OPTIONS.

官方文档中的示例

//1.获得一个httpclient对象CloseableHttpClient httpclient =HttpClients.createDefault();//2.生成一个get请求HttpGet httpget =newHttpGet("http://localhost/");//3.执行get请求并返回结果CloseableHttpResponse response =httpclient.execute(httpget);try{    //4.处理结果}finally{    response.close();}

介绍一下最常用的HttpGet和HttpPost。
RESTful提倡,通过HTTP请求对应的POST、GET、PUT、DELETE来完成对应的CRUD操作。
所以本文介绍一下通过GET获取数据和POST提交数据的实现方法。

##发送HttpGet
先介绍发送HttpGet请求

 /**  * 发送HttpGet请求  * @param url  * @return  */ publicstaticString sendGet(String url){  //1.获得一个httpclient对象  CloseableHttpClient httpclient =HttpClients.createDefault();  //2.生成一个get请求  HttpGet httpget =newHttpGet(url);  CloseableHttpResponse response =null;  try{   //3.执行get请求并返回结果   response =httpclient.execute(httpget);  }catch(IOExceptione1){   e1.printStackTrace();  }  String result =null;  try{   //4.处理结果,这里将结果返回为字符串   HttpEntity entity =response.getEntity();   if(entity !=null){    result =EntityUtils.toString(entity);   }  }catch(ParseException|IOException e){   e.printStackTrace();  }finally{   try{    response.close();   }catch(IOExceptione){    e.printStackTrace();   }  }  returnresult; }

##发送HttpPost
发送HttpPost的方法和发送HttpGet很类似,只是将请求类型给位HttpPost即可。
代码如下

 /**  * 发送不带参数的HttpPost请求  * @param url  * @return  */ publicstaticString sendPost(String url){  //1.获得一个httpclient对象  CloseableHttpClient httpclient =HttpClients.createDefault();  //2.生成一个post请求  HttpPost httppost =newHttpPost(url);  CloseableHttpResponse response =null;  try{   //3.执行get请求并返回结果   response =httpclient.execute(httppost);  }catch(IOExceptione){   e.printStackTrace();  }  //4.处理结果,这里将结果返回为字符串  HttpEntity entity =response.getEntity();  String result =null;  try{   result =EntityUtils.toString(entity);  }catch(ParseException|IOException e){   e.printStackTrace();  }  returnresult; }

##带参数的HttpPost
发送带参数的HttpPost

Many applications need to simulate the process of submitting an HTML form, for instance, in order to log in to a web application or submit input data. HttpClient provides the entity class UrlEncodedFormEntity to facilitate the process.

HttpClient通过UrlEncodedFormEntity,来提交带参数的请求

将需要提交的参数放在map里
代码如下

 /**  * 发送HttpPost请求,参数为map  * @param url  * @param map  * @return  */ publicstaticString sendPost(String url,Map<String, String>map){  CloseableHttpClient httpclient =HttpClients.createDefault();  List<NameValuePair>formparams =newArrayList<NameValuePair>();  for(Map.Entry<String, String>entry :map.entrySet()){   //给参数赋值   formparams.add(newBasicNameValuePair(entry.getKey(),entry.getValue()));  }  UrlEncodedFormEntity entity =newUrlEncodedFormEntity(formparams,Consts.UTF_8);  HttpPost httppost =newHttpPost(url);  httppost.setEntity(entity);  CloseableHttpResponse response =null;  try{   response =httpclient.execute(httppost);  }catch(IOExceptione){   e.printStackTrace();  }  HttpEntity entity1 =response.getEntity();  String result =null;  try{   result =EntityUtils.toString(entity1);  }catch(ParseException|IOException e){   e.printStackTrace();  }  returnresult; }

##完整代码
完成代码如下,用到的jar包有httpclient-4.5.1.jar,httpcore-4.4.3.jar,依赖的jar有commons-logging-1.2.jar
注意是Apache HttpClient,不是commons-httpclient

importjava.io.IOException;importjava.util.ArrayList;importjava.util.List;importjava.util.Map;importorg.apache.http.Consts;importorg.apache.http.HttpEntity;importorg.apache.http.NameValuePair;importorg.apache.http.ParseException;importorg.apache.http.client.entity.UrlEncodedFormEntity;importorg.apache.http.client.methods.CloseableHttpResponse;importorg.apache.http.client.methods.HttpGet;importorg.apache.http.client.methods.HttpPost;importorg.apache.http.impl.client.CloseableHttpClient;importorg.apache.http.impl.client.HttpClients;importorg.apache.http.message.BasicNameValuePair;importorg.apache.http.util.EntityUtils;/** * @author GWCheng * */publicclassHttpUtil{ privatestaticfinalCloseableHttpClient httpclient =HttpClients.createDefault(); /**  * 发送HttpGet请求  * @param url  * @return  */ publicstaticString sendGet(String url){  HttpGet httpget =newHttpGet(url);  CloseableHttpResponse response =null;  try{   response =httpclient.execute(httpget);  }catch(IOExceptione1){   e1.printStackTrace();  }  String result =null;  try{   HttpEntity entity =response.getEntity();   if(entity !=null){    result =EntityUtils.toString(entity);   }  }catch(ParseException|IOException e){   e.printStackTrace();  }finally{   try{    response.close();   }catch(IOExceptione){    e.printStackTrace();   }  }  returnresult; } /**  * 发送HttpPost请求,参数为map  * @param url  * @param map  * @return  */ publicstaticString sendPost(String url,Map<String, String>map){  List<NameValuePair>formparams =newArrayList<NameValuePair>();  for(Map.Entry<String, String>entry :map.entrySet()){   formparams.add(newBasicNameValuePair(entry.getKey(),entry.getValue()));  }  UrlEncodedFormEntity entity =newUrlEncodedFormEntity(formparams,Consts.UTF_8);  HttpPost httppost =newHttpPost(url);  httppost.setEntity(entity);  CloseableHttpResponse response =null;  try{   response =httpclient.execute(httppost);  }catch(IOExceptione){   e.printStackTrace();  }  HttpEntity entity1 =response.getEntity();  String result =null;  try{   result =EntityUtils.toString(entity1);  }catch(ParseException|IOException e){   e.printStackTrace();  }  returnresult; } /**  * 发送不带参数的HttpPost请求  * @param url  * @return  */ publicstaticString sendPost(String url){  HttpPost httppost =newHttpPost(url);  CloseableHttpResponse response =null;  try{   response =httpclient.execute(httppost);  }catch(IOExceptione){   e.printStackTrace();  }  HttpEntity entity =response.getEntity();  String result =null;  try{   result =EntityUtils.toString(entity);  }catch(ParseException|IOException e){   e.printStackTrace();  }  returnresult; }}

##测试用例

服务器端代码

@Controller@RequestMapping("/test")// /test/**publicclassTestController{ // /test/view post 提交数据,模拟表单 @RequestMapping(value ="/view",method =RequestMethod.POST) publicvoidviewTest(PrintWriter out,HttpServletResponse response,@RequestParam("param1")String param1,   @RequestParam("param2")String param2){  response.setContentType("application/json;charset=UTF-8");  Gson gson =newGsonBuilder().create();  Map<String, Object>map =newHashMap<String, Object>();  map.put("param1",param1);  map.put("param2",param2);  System.out.println(gson.toJson(map));  out.print(gson.toJson(map)); }  // /test/view?param1=aaa&param2=bbb get   @RequestMapping(value ="/view",method =RequestMethod.GET)  publicvoidviewTest3(PrintWriter out,HttpServletResponse response,@RequestParam("param1")String param1,    @RequestParam("param2")String param2){   response.setContentType("application/json;charset=UTF-8");   Gson gson =newGsonBuilder().create();   Map<String, Object>map =newHashMap<String, Object>();   map.put("param1",param1);   map.put("param2",param2);   System.out.println(gson.toJson(map));   out.print(gson.toJson(map));  } // /test/view2/{courseId} @RequestMapping(value ="/view2/{param}",method =RequestMethod.GET) publicvoidviewTest1(PrintWriter out,HttpServletResponse response,@PathVariable("param")String param){  response.setContentType("application/json;charset=UTF-8");  Gson gson =newGsonBuilder().create();  Map<String, Object>map =newHashMap<String, Object>();  map.put("param",param);  out.print(gson.toJson(map)); } // /test/view3 @RequestMapping(value ="/view3",method =RequestMethod.POST) publicvoidviewTest2(PrintWriter out,HttpServletResponse response){  response.setContentType("application/json;charset=UTF-8");  Gson gson =newGsonBuilder().create();  Map<String, Object>map =newHashMap<String, Object>();  map.put("status","success");  out.print(gson.toJson(map)); }}

测试代码

publicclassHttpClientTest{ @Test publicvoidtestGet(){  //百度天气的api  //String url1 = "http://api.map.baidu.com/telematics/v3/weather?location=%E5%8C%97%E4%BA%AC&output=json&ak=W69oaDTCfuGwzNwmtVvgWfGH";  String url1 ="http://localhost:8080/wechat/test/view2/你好世界";  String result1 =HttpUtil.sendGet(url1);  System.out.println(result1);  //输出{"param":"你好世界"} } @Test publicvoidtestPost()throwsUnsupportedEncodingException{  String url ="http://localhost:8080/wechat/test/view";  Map<String,String>map =newHashMap<String,String>();  map.put("param1","你好世界");  map.put("param2","哈哈");  String result =HttpUtil.sendPost(url,map);  System.out.println(result);  //输出结果{"param1":"你好世界","param2":"哈哈"} }  @Test publicvoidtestPost1()throwsUnsupportedEncodingException{  String url ="http://localhost:8080/wechat/test/view3";  String result =HttpUtil.sendPost(url);  System.out.println(result);  //输出结果{"status":"success"} }}

建议通过HttpGet获取信息,HttpPost提交信息,而HttpGet获取信息时需要提交的参数一般会在url中体现,或者以?传参,或者在url中传参,所以就没写HttpGet带参数的。也希望大家能遵循Http的设计原则,通过HttpGet, HttpPost, HttpPut, HttpDelete,来实现获取数据,提交数据,修改数据,和删除数据的方法。

2018年10月25修改

依赖

        <!--apache工具类-->        <dependency>            <groupId>org.apache.commons</groupId>            <artifactId>commons-lang3</artifactId>            <version>3.1</version>        </dependency>        <dependency>            <groupId>org.apache.commons</groupId>            <artifactId>commons-collections4</artifactId>            <version>4.1</version>        </dependency>        <!--lombok-->        <dependency>            <groupId>org.projectlombok</groupId>            <artifactId>lombok</artifactId>            <version>1.18.2</version>            <scope>provided</scope>        </dependency>        <!--httpclient-->        <dependency>            <groupId>org.apache.httpcomponents</groupId>            <artifactId>httpclient</artifactId>            <version>4.5.6</version>        </dependency>        <dependency>            <groupId>org.apache.httpcomponents</groupId>            <artifactId>httpmime</artifactId>            <version>4.5.6</version>        </dependency>        <!--log-->        <dependency>            <groupId>org.slf4j</groupId>            <artifactId>slf4j-api</artifactId>            <version>1.7.10</version>        </dependency>        <dependency>            <groupId>ch.qos.logback</groupId>            <artifactId>logback-classic</artifactId>            <version>1.1.2</version>        </dependency>        <dependency>            <groupId>ch.qos.logback</groupId>            <artifactId>logback-core</artifactId>            <version>1.1.2</version>        </dependency>        <!--MultipartFile-->        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-web</artifactId>            <version>2.0.6.RELEASE</version>        </dependency>        <dependency>            <groupId>org.springframework</groupId>            <artifactId>spring-test</artifactId>            <version>5.0.6.RELEASE</version>        </dependency>

最近优化了一下这个方法,具体程序如下

packagecom.cgw.util;importcom.alibaba.fastjson.JSONObject;importlombok.extern.slf4j.Slf4j;importorg.apache.commons.collections4.CollectionUtils;importorg.apache.commons.collections4.MapUtils;importorg.apache.commons.lang3.StringUtils;importorg.apache.http.Consts;importorg.apache.http.Header;importorg.apache.http.HttpEntity;importorg.apache.http.client.config.RequestConfig;importorg.apache.http.client.methods.CloseableHttpResponse;importorg.apache.http.client.methods.HttpGet;importorg.apache.http.client.methods.HttpPost;importorg.apache.http.config.ConnectionConfig;importorg.apache.http.entity.ContentType;importorg.apache.http.entity.StringEntity;importorg.apache.http.entity.mime.HttpMultipartMode;importorg.apache.http.entity.mime.MultipartEntityBuilder;importorg.apache.http.entity.mime.content.StringBody;importorg.apache.http.impl.client.CloseableHttpClient;importorg.apache.http.impl.client.HttpClientBuilder;importorg.apache.http.impl.client.HttpClients;importorg.apache.http.message.BasicHeader;importorg.apache.http.util.EntityUtils;importorg.springframework.mock.web.MockMultipartFile;importorg.springframework.web.multipart.MultipartFile;importjava.io.File;importjava.io.FileInputStream;importjava.io.IOException;importjava.nio.charset.Charset;importjava.nio.charset.CodingErrorAction;importjava.nio.file.Files;importjava.nio.file.Path;importjava.nio.file.Paths;importjava.util.ArrayList;importjava.util.HashMap;importjava.util.List;importjava.util.Map;/** * Http工具类 * * @author 程高伟 */@Slf4jpublicclassHttpUtil{    privatestaticfinalString USER_AGENT ="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36";    // 超时设置    privatestaticfinalRequestConfig requestConfig =RequestConfig.custom()            .setConnectTimeout(5000)            .setConnectionRequestTimeout(5000)            .setSocketTimeout(10000)            .build();    // 编码设置    privatestaticfinalConnectionConfig connectionConfig =ConnectionConfig.custom()            .setMalformedInputAction(CodingErrorAction.IGNORE)            .setUnmappableInputAction(CodingErrorAction.IGNORE)            .setCharset(Consts.UTF_8)            .build();    privatestaticHttpClientBuilder getBuilder(){        List<Header>headers =newArrayList<>();        Header header =newBasicHeader("User-Agent",USER_AGENT);        headers.add(header);        returnHttpClients.custom().setDefaultConnectionConfig(connectionConfig).setDefaultHeaders(headers).setDefaultRequestConfig(requestConfig);    }    /**     * 发送HttpGet请求     *     * @param url 请求地址     * @return     */    publicstaticString sendGet(String url)throwsIOException {        String result;        HttpGet httpGet =newHttpGet(url);        try(CloseableHttpClient httpclient =getBuilder().build();             CloseableHttpResponse response =httpclient.execute(httpGet)){            HttpEntity httpEntity =response.getEntity();            result =EntityUtils.toString(httpEntity);        }        returnresult;    }    /**     * 发送HttpPost请求,参数为json字符串     *     * @param url     请求地址     * @param jsonStr json字符串     * @return     */    publicstaticString sendPost(String url,String jsonStr)throwsIOException {        String result;        // 设置entity        StringEntity stringEntity =newStringEntity(jsonStr,Consts.UTF_8);        stringEntity.setContentType("application/json");        HttpPost httpPost =newHttpPost(url);        httpPost.setEntity(stringEntity);        try(CloseableHttpClient httpclient =getBuilder().build();CloseableHttpResponse httpResponse =httpclient.execute(httpPost);){            HttpEntity httpEntity =httpResponse.getEntity();            result =EntityUtils.toString(httpEntity);        }        returnresult;    }    /**     * 发送HttpPost请求,提交表单,支持文件上传     *     * @param url    请求地址     * @param params 表单参数     * @param files  上传文件     * @return     */    publicstaticString sendPost(String url,Map<String, Object>params,List<MultipartFile>files)throwsIOException {        String result;        // 设置entity        MultipartEntityBuilder builder =MultipartEntityBuilder.create();        builder.setCharset(Charset.forName("UTF-8"));        builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);        if(CollectionUtils.isNotEmpty(files)){// 文件表单参数            for(MultipartFile file :files){                Path path =Paths.get(file.getOriginalFilename());                String contentType =Files.probeContentType(path);                if(StringUtils.isEmpty(contentType)){                    contentType ="application/octet-stream";                }                builder.addBinaryBody(file.getName(),file.getInputStream(),ContentType.create(contentType),file.getOriginalFilename());            }        }        if(MapUtils.isNotEmpty(params)){// 普通表单参数            params.forEach((k,v)->{                StringBody stringBody =newStringBody(v.toString(),ContentType.create("text/plain","UTF-8"));                builder.addPart(k,stringBody);            });        }        HttpPost httpPost =newHttpPost(url);        httpPost.setEntity(builder.build());        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值