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. Python特别low的一个文字游戏

    闲来无事 ,调侃舍友的游戏 import os class Role(): def __init__(self,name,sex,fighting): self.name=name self.sex= ...

  2. python学习之面向对象程序设计的一些思考

    将属于一类的对象放在一起: 如果一个函数操纵一个全局变量,那么两者最好都在类内作为特性和方法实现. 不要让对象过于亲密: 方法应该只关心自己实例的特性,让其他实例管理自己的状态. 简单就好: 让方法小 ...

  3. SPFA算法(2) POJ 1511 Invitation Cards

    原题: Invitation Cards Time Limit: 8000MS   Memory Limit: 262144K Total Submissions: 31230   Accepted: ...

  4. SELECT(データ取得)

    WHERE 句は.満たすべき条件を指定することにより選択される行数を制限します. WHERE 句は.SELECT 命令と同様に OPEN CURSOR.UPDATE.および DELETE 命令でも使用 ...

  5. onenet基础通信套件返回+CIS ERROR: 50的问题解决

    1. 场景分析,主要问题就是有些操作返回+CIS ERROR: 50 2. 看了一下在AT+MIPLOBSERVERSP这个指令里面是没有返回+CIS ERROR: 50的错误类型的,所以应该是在解析 ...

  6. thrift服务端到客户端开发简单示例

    (1)首先我们在服务器端写个helloworld.thrift文件,如下所示: service HelloWorld{ string ping(1: string name), string getp ...

  7. 『Golang』MongoDB在Golang中的使用(mgo包)

    有关在Golang中使用mho进行MongoDB操作的最简单的例子.

  8. Tuxedo 通讯方式解析

    本节根据tuxedo自带samples的例子,让其运行起来.并通过这个例子,深入的理解tuxedo的通讯方式. 进入tuxedo的安装目录,samples目录下自带了一些例子 [root@localh ...

  9. 树莓派搭建 Hexo 博客(二)

    Hexo 一个开源的博客框架,本文记录了一下在树莓派上搭建 Hexo 博客的过程. 上一篇介绍了 Hexo 的配置,现在网站已经能在本地访问了,也能通过 hexo generate 命令生成静态界面 ...

  10. POJ 2162 Document Indexing(模拟)

    Description Andy is fond of old computers. He loves everything about them and he uses emulators of o ...