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;@Controllerpublic 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+"\tpassword: "+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+"\tpassword: "+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+"\tpassword: "+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+"\tpassword: "+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 工具类】)
原文地址:https://www.cnblogs.com/libin6505/p/9817925.html