HttpClientUntils工具类的使用及注意事项(包括我改进的工具类和Controller端的注意事项附 Json 工具类)
Posted libin6505
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HttpClientUntils工具类的使用及注意事项(包括我改进的工具类和Controller端的注意事项附 Json 工具类)相关的知识,希望对你有一定的参考价值。
HttpClient工具类(我改过):
package com.taotao.httpclient; import java.io.IOException; import java.net.URI; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.apache.http.NameValuePair; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.utils.URIBuilder; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; public class HttpClientUtil { //带参数的get请求 public static String doGet(String url, Map<String, String> param) { // 创建Httpclient对象 CloseableHttpClient httpclient = HttpClients.createDefault(); String resultString = ""; CloseableHttpResponse response = null; try { // 创建uri URIBuilder builder = new URIBuilder(url); if (param != null) { for (String key : param.keySet()) { builder.addParameter(key, param.get(key)); } } URI uri = builder.build(); // 创建http GET请求 HttpGet httpGet = new HttpGet(uri); //注意,如果请求这里设置了 Accept 的 header,那么 服务层的 Controller 中的Mapping上就可以不用 produces属性 httpGet.setHeader(new BasicHeader("Accept", "text/plain;charset=utf-8")); // 执行请求 response = httpclient.execute(httpGet); // 判断返回状态是否为200 if (response.getStatusLine().getStatusCode() == 200) { resultString = EntityUtils.toString(response.getEntity(), "UTF-8"); } } catch (Exception e) { e.printStackTrace(); } finally { try { if (response != null) { response.close(); } httpclient.close(); } catch (IOException e) { e.printStackTrace(); } } return resultString; } //无参数的get请求 public static String doGet(String url) { return doGet(url, null); } //带参数的post请求 public static String doPost(String url, Map<String, String> param) { // 创建Httpclient对象 CloseableHttpClient httpClient = HttpClients.createDefault(); CloseableHttpResponse response = null; String resultString = ""; try { // 创建Http Post请求 HttpPost httpPost = new HttpPost(url); //注意,如果请求这里设置了 Accept 的 header,那么 服务层的 Controller 中的Mapping上就可以不用 produces属性 httpPost.setHeader(new BasicHeader("Accept", "text/plain;charset=utf-8")); // 创建参数列表 if (param != null) { List<NameValuePair> paramList = new ArrayList<>(); for (String key : param.keySet()) { paramList.add(new BasicNameValuePair(key, param.get(key))); } // 模拟表单(后面是转码,发送utf8格式的中文) StringEntity entity = new UrlEncodedFormEntity(paramList,"utf-8"); httpPost.setEntity(entity); } // 执行http请求 response = httpClient.execute(httpPost); resultString = EntityUtils.toString(response.getEntity(), "utf-8"); } catch (Exception e) { e.printStackTrace(); } finally { try { response.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return resultString; } //不带参数的post请求 public static String doPost(String url) { return doPost(url, null); } //带参数的post请求,参数是 json串 public static String doPostJson(String url, String json) { // 创建Httpclient对象 CloseableHttpClient httpClient = HttpClients.createDefault(); CloseableHttpResponse response = null; String resultString = ""; try { // 创建Http Post请求 HttpPost httpPost = new HttpPost(url); // 创建请求内容 StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON); httpPost.setEntity(entity); // 执行http请求 response = httpClient.execute(httpPost); resultString = EntityUtils.toString(response.getEntity(), "utf-8"); } catch (Exception e) { e.printStackTrace(); } finally { try { response.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return resultString; } }
工具类的使用测试代码:
package com.taotao.httpclient; import java.util.HashMap; import org.junit.Test; import com.taotao.common.utils.JsonUtils; public class HTTPClientUtilsTest { //不带参数的get请求 @Test public void doGet(){ String url = "http://localhost:8083/search/doGet/哈哈"; String doGetResult = HttpClientUtil.doGet(url); System.out.println("======结果值:"+doGetResult); } //带参数的get请求 @Test public void doGetWithParam(){ String url = "http://localhost:8083/search/doGetWithParam"; HashMap<String, String> paramMap = new HashMap<String,String>(); paramMap.put("username", "花千骨"); paramMap.put("password", "123"); String doGetResult = HttpClientUtil.doGet(url,paramMap); System.out.println("======结果值:"+doGetResult); } //不带参数的 post 请求 @Test public void doPost(){ String url = "http://localhost:8083/search/doPost/哈哈"; String doGetResult = HttpClientUtil.doPost(url); System.out.println("======结果值:"+doGetResult); } //带参数的post请求 @Test public void doPostWithParam(){ String url = "http://localhost:8083/search/doPostWithParam"; HashMap<String, String> paramMap = new HashMap<String,String>(); paramMap.put("username", "花千骨"); paramMap.put("password", "123"); String doGetResult = HttpClientUtil.doPost(url,paramMap); System.out.println("======结果值:"+doGetResult); } //带参数的post请求,返回对象【这个请求到服务器端会报错,不能返回正确的类型】 @Test //错错错错错 不要像此方法这样用 public void doPostWithParamReturnUser(){ String url = "http://localhost:8083/search/doPostWithParamReturnUser"; HashMap<String, String> paramMap = new HashMap<String,String>(); paramMap.put("username", "花千骨"); paramMap.put("password", "123"); String doGetResult = HttpClientUtil.doPost(url,paramMap); System.out.println("======结果值:"+doGetResult); } //带参数的post请求,一定要返回String类型 @Test public void doPostWithParamReturnUser2(){ String url = "http://localhost:8083/search/doPostWithParamReturnUser2"; HashMap<String, String> paramMap = new HashMap<String,String>(); paramMap.put("username", "花千骨"); paramMap.put("password", "123"); String doGetResult = HttpClientUtil.doPost(url,paramMap); System.out.println("======结果值:"+doGetResult); } //带参数的post请求,参数是json对象,返回User对象 @Test public void doPostWithJsonParam(){ String url = "http://localhost:8083/search/doPostWithJsonParam"; HashMap<String, String> paramMap = new HashMap<String,String>(); User user = new User(); user.setUsername("花千骨"); user.setPassword("123"); //把对象转为json串 String objectToJson = JsonUtils.objectToJson(user); //调用发送json对象的post方法 String doGetResult = HttpClientUtil.doPostJson(url,objectToJson); //======结果值:{"username":"花千骨","passord":"123"} System.out.println("======结果值:"+doGetResult); } //带参数的post请求,参数是json对象,返回 String 类型 @Test public void doPostWithJsonParam2(){ String url = "http://localhost:8083/search/doPostWithJsonParam2"; HashMap<String, String> paramMap = new HashMap<String,String>(); User user = new User(); user.setUsername("花千骨"); user.setPassword("123"); //把对象转为json串 String objectToJson = JsonUtils.objectToJson(user); //调用发送json对象的post方法 String doGetResult = HttpClientUtil.doPostJson(url,objectToJson); //如果Controller中的RequestMapping上没有加上 // produces=MediaType.TEXT_PLAIN_VALUE+";charset=utf-8" //就会有这个乱码返回值: ======结果值:{"username":"???","password":"123"} //正确返回值:======结果值:{"username":"花千骨","passord":"123"} System.out.println("======结果值:"+doGetResult); } }
对应的 SpringMVC Controller 层的代码:
package com.taotao.search.controller; import org.springframework.http.MediaType; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import com.taotao.common.utils.JsonUtils; import com.taotao.search.testpojo.User; @Controller public class HttpClientUtilsController { //无参数的get请求 /** * 请求方法为:HttpClientUtil.doGet(url) */ @RequestMapping(value="/doGet/{pid}") @ResponseBody public String doGet(@PathVariable String pid){ System.out.println("============== "+pid); //这里不会乱码 哈哈 String username = "张三"; String password = "123"; String result = "username: "+username+" password: "+password; return result; } //带参数的get请求响应 /** * 请求方法为:HttpClientUtil.doGet(url,paramMap) */ @RequestMapping(value="/doGetWithParam") @ResponseBody public String doGetWithParam(String username,String password) throws Exception{ //====== username: è?±???éa¨password: 123 System.out.println("====== username: "+username +"password: "+password); //为了避免乱码我们需要转码(带参数的 get 请求,必须在这里转码) username = new String(username.getBytes("iso8859-1"), "utf-8"); password = new String(password.getBytes("iso8859-1"), "utf-8"); //===转码后=== username: 花千骨password: 123 System.out.println("===转码后=== username: "+username +"password: "+password); String result = "username: "+username+" password: "+password; return result; } //不带参数的 post请求 /** * 请求方法为:HttpClientUtil.doPost(url) */ @RequestMapping(value="/doPost/{pid}") @ResponseBody public String doPost(@PathVariable String pid){ System.out.println("============== "+pid); //哈哈 String username = "张三"; String password = "123"; String result = "username: "+username+" password: "+password; return result; } //带参数的 post 请求 /** * 请求方法为:HttpClientUtil.doPost(url,paramMap) */ @RequestMapping(value="/doPostWithParam") @ResponseBody public String doPost(String username,String password){ //====== username: 张三password: 123 System.out.println("====== username: "+username +"password: "+password); String result = "username: "+username+" password: "+password; return result; } //带参数的post请求,用对象接收,并返回对象的json串 /** * 注意,如果请求端 和上面的 请求一样,用的 HttpClientUtil.doPost(url,paramMap)方法, * 则下面这种写法是会报错的 */ @RequestMapping(value="/doPostWithParamReturnUser") @ResponseBody public User doPostReturnUser(User user){ System.out.println("===u=== "+user); return user; //错错错错错 } //带参数的 post请求,用对象接收 /** * 请求方法为:HttpClientUtil.doPost(url,paramMap)) * 注意:用上面的方法发来的请求,在Controller这里只能返回String类型, * 如果返回 User对象(即:doPostReturnUser的写法)是会报错的 */ @RequestMapping(value="/doPostWithParamReturnUser2") @ResponseBody public String doPostReturnUser2(User user){ System.out.println("===u=== "+user); //将user对象转为json串 String result = JsonUtils.objectToJson(user); return result; } //带参数的post请求,参数是个json对象 /** * 请求方法为:HttpClientUtil.doPostJson(url,objectToJson) */ @RequestMapping(value="/doPostWithJsonParam") @ResponseBody public User doPostWithJsonParam(@RequestBody User user){ System.out.println("===u=== "+user); return user; } //带参数的post请求,参数是个json对象 /** * 注意:请求此方法的httpClient调用的是如下方法 * HttpClientUtil.doPostJson(url,objectToJson) * 这时,如果在Controller这里方法的返回值不是User对象而是String类型 * 那么必须在RequestMapping上加上 * produces=MediaType.TEXT_PLAIN_VALUE+";charset=utf-8" * 否则调用者返回值中的中文会乱码 * 而且,这种情况下,在请求方的HttpClientUtil.doPostJson方法中是不能设置 Accept的Header的 * 否则 用同样的方法调用上面的 doPostWithJsonParam 时就会报错,找不到匹配的返回值类型 */ @RequestMapping(value="/doPostWithJsonParam2", produces=MediaType.TEXT_PLAIN_VALUE+";charset=utf-8") @ResponseBody public String doPostWithJsonParam2(@RequestBody User user){ System.out.println("===u=== "+user); //将user对象转为json串 String result = JsonUtils.objectToJson(user); return result; } }
总结:
主要需要注意的就是下面两点(也就是上面代码中的两块注释):
1、//带参数的 post请求,用对象接收
/**
* 请求方法为:HttpClientUtil.doPost(url,paramMap))
* 注意:用上面的方法发来的请求,在Controller这里只能返回String类型,
* 如果返回 User对象(即:doPostReturnUser的写法)是会报错的
*/
2、 //带参数的post请求,参数是个json对象
/**
* 注意:请求此方法的httpClient调用的是如下方法
* HttpClientUtil.doPostJson(url,objectToJson)
* 这时,如果在Controller这里方法的返回值不是User对象而是String类型
* 那么必须在RequestMapping上加上
* produces=MediaType.TEXT_PLAIN_VALUE+";charset=utf-8"
* 否则调用者返回值中的中文会乱码
* 而且,这种情况下,在请求方的HttpClientUtil.doPostJson方法中是不能设置 Accept的Header的
* 否则 用同样的方法调用上面的 doPostWithJsonParam 时就会报错,找不到匹配的返回值类型
*/
其他附件代码:
只要保证 发送端 和 服务端 有同样的 User 对象即可:
package com.taotao.search.testpojo; public class User { private String username; private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "User [username=" + username + ", password=" + password + "]"; } }
代码中用到的 Json 工具类:
package com.taotao.common.utils; import java.util.List; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper; public class JsonUtils { // 定义jackson对象 private static final ObjectMapper MAPPER = new ObjectMapper(); /** * 将对象转换成json字符串。 * <p>Title: pojoToJson</p> * <p>Description: </p> * @param data * @return */ public static String objectToJson(Object data) { try { String string = MAPPER.writeValueAsString(data); return string; } catch (JsonProcessingException e) { e.printStackTrace(); } return null; } /** * 将json结果集转化为对象 * * @param jsonData json数据 * @param clazz 对象中的object类型 * @return */ public static <T> T jsonToPojo(String jsonData, Class<T> beanType) { try { T t = MAPPER.readValue(jsonData, beanType); return t; } catch (Exception e) { e.printStackTrace(); } return null; } /** * 将json数据转换成pojo对象list * <p>Title: jsonToList</p> * <p>Description: </p> * @param jsonData * @param beanType * @return */ public static <T>List<T> jsonToList(String jsonData, Class<T> beanType) { JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType); try { List<T> list = MAPPER.readValue(jsonData, javaType); return list; } catch (Exception e) { e.printStackTrace(); } return null; } }
以上是关于HttpClientUntils工具类的使用及注意事项(包括我改进的工具类和Controller端的注意事项附 Json 工具类)的主要内容,如果未能解决你的问题,请参考以下文章
一个基于POI的通用excel导入导出工具类的简单实现及使用方法