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; } }