• 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+"	password: "+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+"	password: "+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+"	password: "+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+"	password: "+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;
        }
        
    }
  • 相关阅读:
    Python学习————作业
    Python学习————前端
    Python学习————前端(JS)
    Python————前端
    Python学习————作业(简单页面设计)
    Python学习————前端(注册)
    Python学习————表格与表单
    Python学习————作业(前端)
    Python学习————前端
    51Nod1307 绳子与重物
  • 原文地址:https://www.cnblogs.com/libin6505/p/9817925.html
Copyright © 2020-2023  润新知