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.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 工具类】)的更多相关文章
- Spring统一返回Json工具类,带分页信息
前言: 项目做前后端分离时,我们会经常提供Json数据给前端,如果有一个统一的Json格式返回工具类,那么将大大提高开发效率和减低沟通成本. 此Json响应工具类,支持带分页信息,支持泛型,支持Htt ...
- Spring实现类私有方法测试通用方案
现实的业务场景中,可能需要对Spring的实现类的私有方法进行测试. 场景描述: 比如XXXService里有 两个函数a.函数b. 而实现类XXXServiceImpl中实现了函数a.函数b,还包含 ...
- 22.编写一个类A,该类创建的对象可以调用方法showA输出小写的英文字母表。然后再编写一个A类的子类B,子类B创建的对象不仅可以调用方法showA输出小写的英文字母表,而且可以调用子类新增的方法showB输出大写的英文字母表。最后编写主类C,在主类的main方法 中测试类A与类B。
22.编写一个类A,该类创建的对象可以调用方法showA输出小写的英文字母表.然后再编写一个A类的子类B,子类B创建的对象不仅可以调用方法showA输出小写的英文字母表,而且可以调用子类新增的方法sh ...
- 用jackson封装的JSON工具类
package hjp.smart4j.framework.util; import com.fasterxml.jackson.databind.ObjectMapper; import org.s ...
- Code片段 : .properties属性文件操作工具类 & JSON工具类
摘要: 原创出处:www.bysocket.com 泥瓦匠BYSocket 希望转载,保留摘要,谢谢! “贵专” — 泥瓦匠 一.java.util.Properties API & 案例 j ...
- Json工具类,实现了反射将整个Object转换为Json对象的功能,支持Hibernate的延迟加
package com.aherp.framework.util; import java.lang.reflect.Array;import java.lang.reflect.Method;imp ...
- Json工具类 - JsonUtils.java
Json工具类,提供Json与对象之间的转换. 源码如下:(点击下载 - JsonUtils.java . gson-2.2.4.jar ) import java.lang.reflect.Type ...
- Java json工具类,jackson工具类,ObjectMapper工具类
Java json工具类,jackson工具类,ObjectMapper工具类 >>>>>>>>>>>>>>> ...
- 小程序入口构造工具&二维码测试工具
小程序入口构造工具&二维码测试工具 本文将介绍我们小程序中隐藏的两个工具页面.原理虽不复杂,收益却实实在在,或许也能给诸君带来启发. 入口构造工具 痛点 PM&运营 投放链接 PM&a ...
随机推荐
- Python学习:1.快速搭建python环境
一.安装python 现在python有两个比较大的版本一个是python3.x一个是python2.x,python3.x相当于与python2.x是一个比较大的升级,但是python3.x没有向下 ...
- dfs Gym - 100989L
AbdelKader enjoys math. He feels very frustrated whenever he sees an incorrect equation and so he tr ...
- c/c++指针传参
首先要理解参数传递,参数传递分值传递,指针传递,引用传递.(就我自己理解,就是把实参对形参进行赋值) 值传递: 形参是实参的拷贝,改变形参的值并不会影响外部实参的值.从被调用函数的角度来说,值传递是单 ...
- T分布、卡方分布、F分布
请参考: https://www.cnblogs.com/think-and-do/p/6509239.html
- PHP通过copy()函数来复制一个文件
PHP通过copy()函数来复制一个文件.用法如下: bool copy(string $source, string $dest) 其中$source是源文件的路径,$dest是目的文件的路径.函数 ...
- Excel拼接字符串
有时候,需要把一些Excel表格中的内容进行拼接,比如A4行的值是前面三行值的加起来.在Excel中可以使用&来进行这种操作.如果数据非常多,就可以使用这个来进行批量操作.
- ibatis常用sql
(1) 输入参数为单个值 <delete id="com.fashionfree.stat.accesslog.deleteMemberAccessLogsBefore" p ...
- scidb
貌似是给科学家用的数据库,暂不研究
- c++ list_iterator demo
#include <iostream> #include <list> using namespace std; typedef list<int> Integer ...
- 【APUE】Chapter14 Advanced I/O
14.1 Introduction 这一章介绍的内容主要有nonblocking I/O, record locking, I/O multiplexing, asynchronous I/O, th ...