HttpClient工具类(我改过):

  1. package com.taotao.httpclient;
  2.  
  3. import java.io.IOException;
  4. import java.net.URI;
  5. import java.util.ArrayList;
  6. import java.util.List;
  7. import java.util.Map;
  8.  
  9. import org.apache.http.NameValuePair;
  10. import org.apache.http.client.entity.UrlEncodedFormEntity;
  11. import org.apache.http.client.methods.CloseableHttpResponse;
  12. import org.apache.http.client.methods.HttpGet;
  13. import org.apache.http.client.methods.HttpPost;
  14. import org.apache.http.client.utils.URIBuilder;
  15. import org.apache.http.entity.ContentType;
  16. import org.apache.http.entity.StringEntity;
  17. import org.apache.http.impl.client.CloseableHttpClient;
  18. import org.apache.http.impl.client.HttpClients;
  19. import org.apache.http.message.BasicNameValuePair;
  20. import org.apache.http.util.EntityUtils;
  21.  
  22. public class HttpClientUtil {
  23.  
  24. public static String doGet(String url, Map<String, String> param) {
  25.  
  26. // 创建Httpclient对象
  27. CloseableHttpClient httpclient = HttpClients.createDefault();
  28.  
  29. String resultString = "";
  30. CloseableHttpResponse response = null;
  31. try {
  32. // 创建uri
  33. URIBuilder builder = new URIBuilder(url);
  34. if (param != null) {
  35. for (String key : param.keySet()) {
  36. builder.addParameter(key, param.get(key));
  37. }
  38. }
  39. URI uri = builder.build();
  40.  
  41. // 创建http GET请求
  42. HttpGet httpGet = new HttpGet(uri);
  43.  
  44. // 执行请求
  45. response = httpclient.execute(httpGet);
  46. // 判断返回状态是否为200
  47. if (response.getStatusLine().getStatusCode() == 200) {
  48. resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
  49. }
  50. } catch (Exception e) {
  51. e.printStackTrace();
  52. } finally {
  53. try {
  54. if (response != null) {
  55. response.close();
  56. }
  57. httpclient.close();
  58. } catch (IOException e) {
  59. e.printStackTrace();
  60. }
  61. }
  62. return resultString;
  63. }
  64.  
  65. public static String doGet(String url) {
  66. return doGet(url, null);
  67. }
  68.  
  69. public static String doPost(String url, Map<String, String> param) {
  70. // 创建Httpclient对象
  71. CloseableHttpClient httpClient = HttpClients.createDefault();
  72. CloseableHttpResponse response = null;
  73. String resultString = "";
  74. try {
  75. // 创建Http Post请求
  76. HttpPost httpPost = new HttpPost(url);
  77. // 创建参数列表
  78. if (param != null) {
  79. List<NameValuePair> paramList = new ArrayList<>();
  80. for (String key : param.keySet()) {
  81. paramList.add(new BasicNameValuePair(key, param.get(key)));
  82. }
  83. // 模拟表单
  84. // UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);
  85. // 模拟表单(后面是转码,发送utf8格式的中文)
  86. StringEntity entity = new UrlEncodedFormEntity(paramList,"utf-8");
  87. httpPost.setEntity(entity);
  88. }
  89. // 执行http请求
  90. response = httpClient.execute(httpPost);
  91. resultString = EntityUtils.toString(response.getEntity(), "utf-8");
  92. } catch (Exception e) {
  93. e.printStackTrace();
  94. } finally {
  95. try {
  96. response.close();
  97. } catch (IOException e) {
  98. // TODO Auto-generated catch block
  99. e.printStackTrace();
  100. }
  101. }
  102.  
  103. return resultString;
  104. }
  105.  
  106. public static String doPost(String url) {
  107. return doPost(url, null);
  108. }
  109.  
  110. public static String doPostJson(String url, String json) {
  111. // 创建Httpclient对象
  112. CloseableHttpClient httpClient = HttpClients.createDefault();
  113. CloseableHttpResponse response = null;
  114. String resultString = "";
  115. try {
  116. // 创建Http Post请求
  117. HttpPost httpPost = new HttpPost(url);
  118. // 创建请求内容
  119. StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
  120. httpPost.setEntity(entity);
  121. // 执行http请求
  122. response = httpClient.execute(httpPost);
  123. resultString = EntityUtils.toString(response.getEntity(), "utf-8");
  124. } catch (Exception e) {
  125. e.printStackTrace();
  126. } finally {
  127. try {
  128. response.close();
  129. } catch (IOException e) {
  130. // TODO Auto-generated catch block
  131. e.printStackTrace();
  132. }
  133. }
  134.  
  135. return resultString;
  136. }
  137. }

工具类的使用测试代码:

  1. package com.taotao.httpclient;
  2.  
  3. import java.util.HashMap;
  4.  
  5. import org.junit.Test;
  6.  
  7. import com.taotao.common.utils.JsonUtils;
  8. import com.taotao.httpclient.HttpClientUtil;
  9.  
  10. public class HTTPClientUtilsTest {
  11.  
  12. //不带参数的get请求
  13. @Test
  14. public void doGet(){
  15.  
  16. String url = "http://localhost:8083/search/doGet/哈哈";
  17. String doGetResult = HttpClientUtil.doGet(url);
  18. System.out.println("======结果值:"+doGetResult);
  19. }
  20.  
  21. //不带参数的get请求
  22. @Test
  23. public void doGet2(){
  24.  
  25. String url = "http://localhost:8083/search/doGet2/哈哈";
  26. String doGetResult = HttpClientUtil.doGet(url);
  27. System.out.println("======结果值:"+doGetResult);
  28. }
  29.  
  30. //带参数的get请求
  31. @Test
  32. public void doGetWithParam(){
  33.  
  34. String url = "http://localhost:8083/search/doGetWithParam";
  35. HashMap<String, String> paramMap = new HashMap<String,String>();
  36. paramMap.put("username", "花千骨");
  37. paramMap.put("password", "123");
  38.  
  39. String doGetResult = HttpClientUtil.doGet(url,paramMap);
  40. System.out.println("======结果值:"+doGetResult);
  41. }
  42.  
  43. //不带参数的 post 请求
  44. @Test
  45. public void doPost(){
  46.  
  47. String url = "http://localhost:8083/search/doPost/哈哈";
  48. String doGetResult = HttpClientUtil.doPost(url);
  49. System.out.println("======结果值:"+doGetResult);
  50.  
  51. }
  52.  
  53. //带参数的post请求
  54. @Test
  55. public void doPostWithParam(){
  56.  
  57. String url = "http://localhost:8083/search/doPostWithParam";
  58. HashMap<String, String> paramMap = new HashMap<String,String>();
  59. paramMap.put("username", "花千骨");
  60. paramMap.put("password", "123");
  61.  
  62. String doGetResult = HttpClientUtil.doPost(url,paramMap);
  63. System.out.println("======结果值:"+doGetResult);
  64.  
  65. }
  66.  
  67. //带参数的post请求,返回对象
  68. @Test
  69. public void doPostWithParamReturnUser(){
  70.  
  71. String url = "http://localhost:8083/search/doPostWithParamReturnUser";
  72. HashMap<String, String> paramMap = new HashMap<String,String>();
  73. paramMap.put("username", "花千骨");
  74. paramMap.put("password", "123");
  75.  
  76. String doGetResult = HttpClientUtil.doPost(url,paramMap);
  77. System.out.println("======结果值:"+doGetResult);
  78.  
  79. }
  80.  
  81. //带参数的post请求,一定要返回String类型
  82. @Test
  83. public void doPostWithParamReturnUser2(){
  84.  
  85. String url = "http://localhost:8083/search/doPostWithParamReturnUser2";
  86. HashMap<String, String> paramMap = new HashMap<String,String>();
  87. paramMap.put("username", "花千骨");
  88. paramMap.put("password", "123");
  89.  
  90. String doGetResult = HttpClientUtil.doPost(url,paramMap);
  91. System.out.println("======结果值:"+doGetResult);
  92.  
  93. }
  94.  
  95. //带参数的post请求,参数是json对象,返回User对象
  96. @Test
  97. public void doPostWithJsonParam(){
  98.  
  99. String url = "http://localhost:8083/search/doPostWithJsonParam";
  100. HashMap<String, String> paramMap = new HashMap<String,String>();
  101. User user = new User();
  102. user.setUsername("花千骨");
  103. user.setPassword("123");
  104. //把对象转为json串
  105. String objectToJson = JsonUtils.objectToJson(user);
  106. //调用发送json对象的post方法
  107. String doGetResult = HttpClientUtil.doPostJson(url,objectToJson);
  108. //======结果值:{"username":"花千骨","passord":"123"}
  109. System.out.println("======结果值:"+doGetResult);
  110.  
  111. }
  112.  
  113. //带参数的post请求,参数是json对象,返回 String 类型
  114. @Test
  115. public void doPostWithJsonParam2(){
  116.  
  117. String url = "http://localhost:8083/search/doPostWithJsonParam2";
  118. HashMap<String, String> paramMap = new HashMap<String,String>();
  119. User user = new User();
  120. user.setUsername("花千骨");
  121. user.setPassword("123");
  122. //把对象转为json串
  123. String objectToJson = JsonUtils.objectToJson(user);
  124. //调用发送json对象的post方法
  125. String doGetResult = HttpClientUtil.doPostJson(url,objectToJson);
  126. //如果Controller中的RequestMapping上没有加上
  127. // produces=MediaType.TEXT_PLAIN_VALUE+";charset=utf-8"
  128. //就会有这个乱码返回值: ======结果值:{"username":"???","password":"123"}
  129. //正确返回值:======结果值:{"username":"花千骨","passord":"123"}
  130. System.out.println("======结果值:"+doGetResult);
  131.  
  132. }
  133. }

对应的 SpringMVC Controller 层的代码:

  1. package com.taotao.search.controller;
  2.  
  3. import org.springframework.http.MediaType;
  4. import org.springframework.stereotype.Controller;
  5. import org.springframework.web.bind.annotation.PathVariable;
  6. import org.springframework.web.bind.annotation.RequestBody;
  7. import org.springframework.web.bind.annotation.RequestMapping;
  8. import org.springframework.web.bind.annotation.ResponseBody;
  9.  
  10. import com.taotao.common.utils.JsonUtils;
  11. import com.taotao.search.testpojo.User;
  12.  
  13. @Controller
  14. public class HttpClientUtilsController {
  15.  
  16. //无参数的get请求
  17. /**
  18. * 请求方法为:HttpClientUtil.doGet(url)
  19. * 返回值为String类型,requestMapping上必须加produces解决中文乱码
  20. */
  21. @RequestMapping(value="/doGet/{pid}",
  22. produces=MediaType.TEXT_PLAIN_VALUE+";charset=utf-8")
  23. @ResponseBody
  24. public String doGet(@PathVariable String pid){
  25. System.out.println("============== "+pid); //这里不会乱码 哈哈
  26. String username = "张三";
  27. String password = "123";
  28. String result = "username: "+username+"\tpassword: "+password;
  29.  
  30. return result;
  31. }
  32.  
  33. /**
  34. * 请求方法为:HttpClientUtil.doGet(url)
  35. * 返回值为 对象类型,不会乱码,而且一定不能加produces属性,否则结果封装不到调用者
  36. */
  37. @RequestMapping(value="/doGet2/{pid}")
  38. @ResponseBody
  39. public User doGet2(@PathVariable String pid){
  40. System.out.println("============== "+pid); //这里不会乱码 哈哈
  41. String username = "张三";
  42. String password = "123";
  43.  
  44. User user = new User();
  45. user.setUsername(username);
  46. user.setPassword(password);
  47. return user;
  48. }
  49.  
  50. //带参数的get请求响应
  51. /**
  52. * 请求方法为:HttpClientUtil.doGet(url,paramMap)
  53. */
  54. @RequestMapping(value="/doGetWithParam",
  55. produces=MediaType.TEXT_PLAIN_VALUE+";charset=utf-8")
  56. @ResponseBody
  57. public String doGetWithParam(String username,String password) throws Exception{
  58. //====== username: 花千骨password: 123
  59. System.out.println("====== username: "+username +"password: "+password);
  60. //为了避免乱码我们需要转码(带参数的 get 请求,必须在这里转码)
  61. username = new String(username.getBytes("iso8859-1"), "utf-8");
  62. password = new String(password.getBytes("iso8859-1"), "utf-8");
  63. //===转码后=== username: 花千骨password: 123
  64. System.out.println("===转码后=== username: "+username +"password: "+password);
  65. String result = "username: "+username+"\tpassword: "+password;
  66. return result;
  67. }
  68.  
  69. //不带参数的 post请求
  70. /**
  71. * 请求方法为:HttpClientUtil.doPost(url)
  72. */
  73. @RequestMapping(value="/doPost/{pid}",
  74. produces=MediaType.TEXT_PLAIN_VALUE+";charset=utf-8")
  75. @ResponseBody
  76. public String doPost(@PathVariable String pid){
  77. System.out.println("============== "+pid); //哈哈
  78. String username = "张三";
  79. String password = "123";
  80. String result = "username: "+username+"\tpassword: "+password;
  81. return result;
  82. }
  83.  
  84. //带参数的 post 请求
  85. /**
  86. * 请求方法为:HttpClientUtil.doPost(url,paramMap)
  87. */
  88. @RequestMapping(value="/doPostWithParam",
  89. produces=MediaType.TEXT_PLAIN_VALUE+";charset=utf-8")
  90. @ResponseBody
  91. public String doPost(String username,String password){
  92. //====== username: 张三password: 123
  93. System.out.println("====== username: "+username +"password: "+password);
  94. String result = "username: "+username+"\tpassword: "+password;
  95. return result;
  96. }
  97.  
  98. //带参数的post请求,用对象接收,并返回对象的json串
  99. /**
  100. * 请求用的 HttpClientUtil.doPost(url,paramMap)方法,
  101. * 同get请求一样,返回值为 对象类型,不会乱码,而且一定不能加produces属性,否则结果封装不到调用者
  102. */
  103. @RequestMapping(value="/doPostWithParamReturnUser")
  104. @ResponseBody
  105. public User doPostReturnUser(User user){
  106. System.out.println("===u=== "+user);
  107. return user;
  108. }
  109.  
  110. //带参数的 post请求,用对象接收
  111. /**
  112. * 请求方法为:HttpClientUtil.doPost(url,paramMap))
  113. * 返回值用的String,所以要加 produces 解决中文乱码
  114. */
  115. @RequestMapping(value="/doPostWithParamReturnUser2",
  116. produces=MediaType.TEXT_PLAIN_VALUE+";charset=utf-8")
  117. @ResponseBody
  118. public String doPostReturnUser2(User user){
  119. System.out.println("===u=== "+user);
  120. //将user对象转为json串
  121. String result = JsonUtils.objectToJson(user);
  122. return result;
  123. }
  124.  
  125. //带参数的post请求,参数是个json对象
  126. /**
  127. * 请求方法为:HttpClientUtil.doPostJson(url,objectToJson)
  128. */
  129. @RequestMapping(value="/doPostWithJsonParam")
  130. @ResponseBody
  131. public User doPostWithJsonParam(@RequestBody User user){
  132. System.out.println("===u=== "+user);
  133. return user;
  134. }
  135.  
  136. //带参数的post请求,参数是个json对象
  137. /**
  138. * 注意:请求此方法的httpClient调用的是如下方法
  139. * HttpClientUtil.doPostJson(url,objectToJson)
  140. * 这时,如果在Controller这里方法的返回值不是User对象而是String类型
  141. * 那么必须在RequestMapping上加上
  142. * produces=MediaType.TEXT_PLAIN_VALUE+";charset=utf-8"
  143. */
  144. @RequestMapping(value="/doPostWithJsonParam2",
  145. produces=MediaType.TEXT_PLAIN_VALUE+";charset=utf-8")
  146. @ResponseBody
  147. public String doPostWithJsonParam2(@RequestBody User user){
  148. System.out.println("===u=== "+user);
  149. //将user对象转为json串
  150. String result = JsonUtils.objectToJson(user);
  151. return result;
  152. }
  153.  
  154. }

总结:

主要需要注意的就是下面几点:

1、带参数的get请求,在Controller层中必须对接收到的参数进行转码

  1. //为了避免乱码我们需要转码(带参数的 get 请求,必须在这里转码)
  2. username = new String(username.getBytes("iso8859-1"), "utf-8");

2、在Controller层中,

如果方法的返回值是 String 类型,那么必须在RequestMapping上加上
      produces=MediaType.TEXT_PLAIN_VALUE+";charset=utf-8"
      否则调用者返回值中的中文会乱码;

如果方法的返回值是 对象 类型,如 User,那么接收参数一般不会乱码,且这时不能在RequestMapping上加
      produces属性,否则,结果不能正确封装到调用者的返回值response中

3、如果Controller层中的方法返回值为String类型,其实可以在请求方的HttpClientUtils工具类中,加上

httpGet.setHeader(new BasicHeader("Accept", "text/plain;charset=utf-8"));

这样在 服务层的 Controller 中的Mapping上就可以不用 produces属性,返回值的中文中也不会乱码,

但是这种方法的缺点就是,Controller层方法的返回值类型只能是 String ,如果是 对象 类型,那么就会导致结果无法封装到调用者的返回值中,所以这种方法最好不用,仅供了解(此文中提供的工具类中无此行代码,所以这里的工具类兼容性才更好)。

其他附件代码:

只要保证 发送端 和 服务端 有同样的 User 对象即可:

  1. package com.taotao.search.testpojo;
  2.  
  3. public class User {
  4.  
  5. private String username;
  6. private String password;
  7.  
  8. public String getUsername() {
  9. return username;
  10. }
  11. public void setUsername(String username) {
  12. this.username = username;
  13. }
  14. public String getPassword() {
  15. return password;
  16. }
  17. public void setPassword(String password) {
  18. this.password = password;
  19. }
  20.  
  21. @Override
  22. public String toString() {
  23. return "User [username=" + username + ", password=" + password + "]";
  24. }
  25. }

代码中用到的 Json 工具类:

  1. package com.taotao.common.utils;
  2.  
  3. import java.util.List;
  4.  
  5. import com.fasterxml.jackson.core.JsonProcessingException;
  6. import com.fasterxml.jackson.databind.JavaType;
  7. import com.fasterxml.jackson.databind.ObjectMapper;
  8.  
  9. public class JsonUtils {
  10.  
  11. // 定义jackson对象
  12. private static final ObjectMapper MAPPER = new ObjectMapper();
  13.  
  14. /**
  15. * 将对象转换成json字符串。
  16. * <p>Title: pojoToJson</p>
  17. * <p>Description: </p>
  18. * @param data
  19. * @return
  20. */
  21. public static String objectToJson(Object data) {
  22. try {
  23. String string = MAPPER.writeValueAsString(data);
  24. return string;
  25. } catch (JsonProcessingException e) {
  26. e.printStackTrace();
  27. }
  28. return null;
  29. }
  30.  
  31. /**
  32. * 将json结果集转化为对象
  33. *
  34. * @param jsonData json数据
  35. * @param clazz 对象中的object类型
  36. * @return
  37. */
  38. public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {
  39. try {
  40. T t = MAPPER.readValue(jsonData, beanType);
  41. return t;
  42. } catch (Exception e) {
  43. e.printStackTrace();
  44. }
  45. return null;
  46. }
  47.  
  48. /**
  49. * 将json数据转换成pojo对象list
  50. * <p>Title: jsonToList</p>
  51. * <p>Description: </p>
  52. * @param jsonData
  53. * @param beanType
  54. * @return
  55. */
  56. public static <T>List<T> jsonToList(String jsonData, Class<T> beanType) {
  57. JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType);
  58. try {
  59. List<T> list = MAPPER.readValue(jsonData, javaType);
  60. return list;
  61. } catch (Exception e) {
  62. e.printStackTrace();
  63. }
  64.  
  65. return null;
  66. }
  67.  
  68. }

HttpClientUntils工具类的使用测试及注意事项(包括我改进的工具类和Controller端的注意事项【附 Json 工具类】)的更多相关文章

  1. Spring统一返回Json工具类,带分页信息

    前言: 项目做前后端分离时,我们会经常提供Json数据给前端,如果有一个统一的Json格式返回工具类,那么将大大提高开发效率和减低沟通成本. 此Json响应工具类,支持带分页信息,支持泛型,支持Htt ...

  2. Spring实现类私有方法测试通用方案

    现实的业务场景中,可能需要对Spring的实现类的私有方法进行测试. 场景描述: 比如XXXService里有 两个函数a.函数b. 而实现类XXXServiceImpl中实现了函数a.函数b,还包含 ...

  3. 22.编写一个类A,该类创建的对象可以调用方法showA输出小写的英文字母表。然后再编写一个A类的子类B,子类B创建的对象不仅可以调用方法showA输出小写的英文字母表,而且可以调用子类新增的方法showB输出大写的英文字母表。最后编写主类C,在主类的main方法 中测试类A与类B。

    22.编写一个类A,该类创建的对象可以调用方法showA输出小写的英文字母表.然后再编写一个A类的子类B,子类B创建的对象不仅可以调用方法showA输出小写的英文字母表,而且可以调用子类新增的方法sh ...

  4. 用jackson封装的JSON工具类

    package hjp.smart4j.framework.util; import com.fasterxml.jackson.databind.ObjectMapper; import org.s ...

  5. Code片段 : .properties属性文件操作工具类 & JSON工具类

    摘要: 原创出处:www.bysocket.com 泥瓦匠BYSocket 希望转载,保留摘要,谢谢! “贵专” — 泥瓦匠 一.java.util.Properties API & 案例 j ...

  6. Json工具类,实现了反射将整个Object转换为Json对象的功能,支持Hibernate的延迟加

    package com.aherp.framework.util; import java.lang.reflect.Array;import java.lang.reflect.Method;imp ...

  7. Json工具类 - JsonUtils.java

    Json工具类,提供Json与对象之间的转换. 源码如下:(点击下载 - JsonUtils.java . gson-2.2.4.jar ) import java.lang.reflect.Type ...

  8. Java json工具类,jackson工具类,ObjectMapper工具类

    Java json工具类,jackson工具类,ObjectMapper工具类 >>>>>>>>>>>>>>> ...

  9. 小程序入口构造工具&二维码测试工具

    小程序入口构造工具&二维码测试工具 本文将介绍我们小程序中隐藏的两个工具页面.原理虽不复杂,收益却实实在在,或许也能给诸君带来启发. 入口构造工具 痛点 PM&运营 投放链接 PM&a ...

随机推荐

  1. Python学习:1.快速搭建python环境

    一.安装python 现在python有两个比较大的版本一个是python3.x一个是python2.x,python3.x相当于与python2.x是一个比较大的升级,但是python3.x没有向下 ...

  2. dfs Gym - 100989L

    AbdelKader enjoys math. He feels very frustrated whenever he sees an incorrect equation and so he tr ...

  3. c/c++指针传参

    首先要理解参数传递,参数传递分值传递,指针传递,引用传递.(就我自己理解,就是把实参对形参进行赋值) 值传递: 形参是实参的拷贝,改变形参的值并不会影响外部实参的值.从被调用函数的角度来说,值传递是单 ...

  4. T分布、卡方分布、F分布

    请参考: https://www.cnblogs.com/think-and-do/p/6509239.html

  5. PHP通过copy()函数来复制一个文件

    PHP通过copy()函数来复制一个文件.用法如下: bool copy(string $source, string $dest) 其中$source是源文件的路径,$dest是目的文件的路径.函数 ...

  6. Excel拼接字符串

             有时候,需要把一些Excel表格中的内容进行拼接,比如A4行的值是前面三行值的加起来.在Excel中可以使用&来进行这种操作.如果数据非常多,就可以使用这个来进行批量操作.

  7. ibatis常用sql

    (1) 输入参数为单个值 <delete id="com.fashionfree.stat.accesslog.deleteMemberAccessLogsBefore" p ...

  8. scidb

    貌似是给科学家用的数据库,暂不研究

  9. c++ list_iterator demo

    #include <iostream> #include <list> using namespace std; typedef list<int> Integer ...

  10. 【APUE】Chapter14 Advanced I/O

    14.1 Introduction 这一章介绍的内容主要有nonblocking I/O, record locking, I/O multiplexing, asynchronous I/O, th ...