1. 程式人生 > >HttpClientUntils工具類的使用及註意事項(包括我改進的工具類和Controller端的註意事項【附 Json 工具類】)

HttpClientUntils工具類的使用及註意事項(包括我改進的工具類和Controller端的註意事項【附 Json 工具類】)

string類 匹配 frame json .net hash 中文 .data 請求方法

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.BasicHeader; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; public class HttpClientUtil { //帶參數的get請求 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); //註意,如果請求這裏設置了 Accept 的 header,那麽 服務層的 Controller 中的Mapping上就可以不用 produces屬性 httpGet.setHeader(new BasicHeader("Accept", "text/plain;charset=utf-8")); // 執行請求 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; } //無參數的get請求 public static String doGet(String url) { return doGet(url, null); } //帶參數的post請求 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); //註意,如果請求這裏設置了 Accept 的 header,那麽 服務層的 Controller 中的Mapping上就可以不用 produces屬性 httpPost.setHeader(new BasicHeader("Accept", "text/plain;charset=utf-8")); // 創建參數列表 if (param != null) { List<NameValuePair> paramList = new ArrayList<>(); for (String key : param.keySet()) { paramList.add(new BasicNameValuePair(key, param.get(key))); } // 模擬表單(後面是轉碼,發送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; } //不帶參數的post請求 public static String doPost(String url) { return doPost(url, null); } //帶參數的post請求,參數是 json串 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;

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 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)
     */
    @RequestMapping(value="/doGet/{pid}")
    @ResponseBody
    public String doGet(@PathVariable String pid){
        System.out.println("============== "+pid); //這裏不會亂碼 哈哈
        String username = "張三";
        String password = "123";
        String result = "username: "+username+"\tpassword: "+password;
        return result;
    }
    
    //帶參數的get請求響應
    /**
     * 請求方法為:HttpClientUtil.doGet(url,paramMap)
     */
    @RequestMapping(value="/doGetWithParam")
    @ResponseBody
    public String doGetWithParam(String username,String password) throws Exception{
        //====== username: è?±???éa¨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}")
    @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")
    @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)方法,
     * 則下面這種寫法是會報錯的
     */
    @RequestMapping(value="/doPostWithParamReturnUser")
    @ResponseBody
    public User doPostReturnUser(User user){
        System.out.println("===u=== "+user);
        return user; //錯錯錯錯錯
    }
    
    //帶參數的 post請求,用對象接收
    /**
     * 請求方法為:HttpClientUtil.doPost(url,paramMap))
     * 註意:用上面的方法發來的請求,在Controller這裏只能返回String類型,
     * 如果返回 User對象(即:doPostReturnUser的寫法)是會報錯的
     */
    @RequestMapping(value="/doPostWithParamReturnUser2")
    @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"
     * 否則調用者返回值中的中文會亂碼
     * 而且,這種情況下,在請求方的HttpClientUtil.doPostJson方法中是不能設置 Accept的Header的
     * 否則 用同樣的方法調用上面的 doPostWithJsonParam 時就會報錯,找不到匹配的返回值類型
     */
    @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、//帶參數的 post請求,用對象接收
/**
* 請求方法為:HttpClientUtil.doPost(url,paramMap))
* 註意:用上面的方法發來的請求,在Controller這裏只能返回String類型,
* 如果返回 User對象(即:doPostReturnUser的寫法)是會報錯的
*/

2、 //帶參數的post請求,參數是個json對象
/**
* 註意:請求此方法的httpClient調用的是如下方法
* HttpClientUtil.doPostJson(url,objectToJson)
* 這時,如果在Controller這裏方法的返回值不是User對象而是String類型
* 那麽必須在RequestMapping上加上
* produces=MediaType.TEXT_PLAIN_VALUE+";charset=utf-8"
* 否則調用者返回值中的中文會亂碼
* 而且,這種情況下,在請求方的HttpClientUtil.doPostJson方法中是不能設置 Accept的Header的
* 否則 用同樣的方法調用上面的 doPostWithJsonParam 時就會報錯,找不到匹配的返回值類型
*/

其他附件代碼:

只要保證 發送端 和 服務端 有同樣的 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 工具類】)