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.BasicNameValuePair;
import org.apache.http.util.EntityUtils; public class HttpClientUtil { 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); // 执行请求
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;
} public static String doGet(String url) {
return doGet(url, null);
} 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);
// 创建参数列表
if (param != null) {
List<NameValuePair> paramList = new ArrayList<>();
for (String key : param.keySet()) {
paramList.add(new BasicNameValuePair(key, param.get(key)));
}
// 模拟表单
// UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);
// 模拟表单(后面是转码,发送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;
} public static String doPost(String url) {
return doPost(url, null);
} 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;
import com.taotao.httpclient.HttpClientUtil; 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 doGet2(){ String url = "http://localhost:8083/search/doGet2/哈哈";
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)
* 返回值为String类型,requestMapping上必须加produces解决中文乱码
*/
@RequestMapping(value="/doGet/{pid}",
produces=MediaType.TEXT_PLAIN_VALUE+";charset=utf-8")
@ResponseBody
public String doGet(@PathVariable String pid){
System.out.println("============== "+pid); //这里不会乱码 哈哈
String username = "张三";
String password = "123";
String result = "username: "+username+"\tpassword: "+password; return result;
} /**
* 请求方法为:HttpClientUtil.doGet(url)
* 返回值为 对象类型,不会乱码,而且一定不能加produces属性,否则结果封装不到调用者
*/
@RequestMapping(value="/doGet2/{pid}")
@ResponseBody
public User doGet2(@PathVariable String pid){
System.out.println("============== "+pid); //这里不会乱码 哈哈
String username = "张三";
String password = "123"; User user = new User();
user.setUsername(username);
user.setPassword(password);
return user;
} //带参数的get请求响应
/**
* 请求方法为:HttpClientUtil.doGet(url,paramMap)
*/
@RequestMapping(value="/doGetWithParam",
produces=MediaType.TEXT_PLAIN_VALUE+";charset=utf-8")
@ResponseBody
public String doGetWithParam(String username,String password) throws Exception{
//====== username: 花千骨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}",
produces=MediaType.TEXT_PLAIN_VALUE+";charset=utf-8")
@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",
produces=MediaType.TEXT_PLAIN_VALUE+";charset=utf-8")
@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)方法,
* 同get请求一样,返回值为 对象类型,不会乱码,而且一定不能加produces属性,否则结果封装不到调用者
*/
@RequestMapping(value="/doPostWithParamReturnUser")
@ResponseBody
public User doPostReturnUser(User user){
System.out.println("===u=== "+user);
return user;
} //带参数的 post请求,用对象接收
/**
* 请求方法为:HttpClientUtil.doPost(url,paramMap))
* 返回值用的String,所以要加 produces 解决中文乱码
*/
@RequestMapping(value="/doPostWithParamReturnUser2",
produces=MediaType.TEXT_PLAIN_VALUE+";charset=utf-8")
@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"
*/
@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、带参数的get请求,在Controller层中必须对接收到的参数进行转码

//为了避免乱码我们需要转码(带参数的 get 请求,必须在这里转码)
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 对象即可:

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 工具类】)的更多相关文章

  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. Hadoop(10)-HDFS的DataNode详解

    1.DataNode工作机制 1)一个数据块在DataNode上以文件形式存储在磁盘上,包括两个文件,一个是数据本身,一个是元数据包括数据块的长度,块数据的校验和,以及时间戳. 2)DataNode启 ...

  2. kafka单机部署文档

    单机Kafka部署文档 最简单的使用方式,单机,使用自带的zookeeper 1.解压 下载地址:http://pan.baidu.com/s/1i4K2pXr tar –zxvf kafka_2.1 ...

  3. python基础集结号

    Python 号称是最接近人工智能的语言,因为它的动态便捷性和灵活的三方扩展,成就了它在人工智能领域的丰碑 走进Python,靠近人工智能 一.编程语言Python的基础 之 "浅入浅出&q ...

  4. Android之线程安全的单例模式,Adapter注意事项之引用传值

    线程安全的单例模式单位模式一般写法如下: public static FestivalLab mInstance; private FestivalLab() { } public static Fe ...

  5. css的水平居中和垂直居中总结

    Html代码: <div class="md-warp"> <div class="md-main">块级元素</div> ...

  6. mcrouter facebook 开源的企业级memcached代理

    原文地址:https://code.facebook.com/posts/296442737213493/introducing-mcrouter-a-memcached-protocol-route ...

  7. join ,left join ,right join有什么区别

    join等价于inner join内连接,是返回两个表中都有的符合条件的行. left join左连接,是返回左表中所有的行及右表中符合条件的行.(左表为主表) right join右连接,是返回右表 ...

  8. URAL 1736 Chinese Hockey(网络最大流)

    Description Sergey and Denis closely followed the Chinese Football Championship, which has just come ...

  9. 用Navicat建表的字段编码问题

    最近在做Amazon的订单导入的时候,一直报字符编码的错误. java.sql.SQLException: Incorrect stringvalue: '\xB7\xAD\xA0...' for c ...

  10. PM所该学习的

     最近第二阶段实在大家都是大一大二,面临的考试很多也很难,很多时候就开始松懈了下来.可是做事情就是需要效率和时间,慢慢地,也开始懈怠了下来. 作为pm,首先自己必须比组员先了解云笔记的各种进程,做好沟 ...