junit HttpClient 请求端 代码:

package com.taotao.httpclient;

import java.util.ArrayList;
import java.util.List; import org.apache.http.HttpEntity;
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.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;
import org.junit.Test; public class HTTPClientGTest2 { //不带参数的get请求
@Test
public void doGet() throws Exception {
//创建一个可关闭的httpClient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
//创建一个get对象
HttpGet get = new HttpGet("http://localhost:8083/search/doGet/哈哈"); //注意,如果请求这里设置了 Accept header,那么 服务层的Controller 中的Mapping上就可以不用 produces属性,但是如果这样设置,那么Controller方法的返回值只能是String,否则结果无法封装会调用者
get.setHeader(new BasicHeader("Accept", "text/plain;charset=utf-8")); //执行请求
CloseableHttpResponse response = httpClient.execute(get);
//取响应结果
//先获取响应码
int statusCode = response.getStatusLine().getStatusCode();
System.out.println("======响应码:"+statusCode); //200
//获取响应结果对象
HttpEntity entity = response.getEntity();
//将结果对象转换为字符串
String string = EntityUtils.toString(entity,"utf-8");
//结果:=======结果值:username: 张三 password: 123
System.out.println("======结果值:"+string);
//关闭资源
response.close();
httpClient.close();
} //带参数的get请求
@Test
public void doGetWithParam() throws Exception {
//创建一个可关闭的httpClient对象
CloseableHttpClient httpClient = HttpClients.createDefault(); //带参数方法1:直接拼接在请求中 创建get对象
/*HttpGet get = new HttpGet(
"http://localhost:8083/search/doGetWithParam?username=花千骨&password=123");*/ //带参数方法2 用对象的方式添加参数
//先创建一个基本的(不带参数的)uri对象
URIBuilder uriBuilder = new URIBuilder("http://localhost:8083/search/doGetWithParam");
uriBuilder.addParameter("username", "花千骨");
uriBuilder.addParameter("password", "123");
//再创建get对象
HttpGet get = new HttpGet(uriBuilder.build()); //注意,如果请求这里设置了 Accept header,那么 服务层的Controller 中的Mapping上就可以不用 produces属性,但是如果这样设置,那么Controller方法的返回值只能是String,否则结果无法封装会调用者
get.setHeader(new BasicHeader("Accept", "text/plain;charset=utf-8")); //执行请求
CloseableHttpResponse response = httpClient.execute(get);
//取响应结果
//先获取响应码
int statusCode = response.getStatusLine().getStatusCode();
System.out.println("======响应码:"+statusCode);
//获取响应结果对象
HttpEntity entity = response.getEntity();
//将结果对象转换为字符串
String string = EntityUtils.toString(entity,"utf-8");
//======结果值:username: 花千骨 password: 123
System.out.println("======结果值:"+string);
//关闭资源
response.close();
httpClient.close();
} //不带参数的 post 请求
@Test
public void doPost() throws Exception {
CloseableHttpClient httpClient = HttpClients.createDefault();
// HttpPost post = new HttpPost("http://localhost:8082/httpclient/post.html");
// 注意:如果请求的url后缀是 .html则浏览器不能返回正确的json数据,会返回406错误,所以需要修改请求url的后缀为其他
// HttpPost post = new HttpPost("http://localhost:8082/httpclient/post.action");
HttpPost post = new HttpPost("http://localhost:8083/search/doPost/哈哈");
//注意,如果请求这里设置了 Accept header,那么 服务层的Controller 中的Mapping上就可以不用 produces属性
post.setHeader(new BasicHeader("Accept", "text/plain;charset=utf-8")); CloseableHttpResponse response = httpClient.execute(post);
HttpEntity entity = response.getEntity();
String string = EntityUtils.toString(entity, "utf-8");
System.out.println(string);
response.close();
httpClient.close();
} //带参数的post请求
@Test
public void doPostWithParam() throws Exception {
CloseableHttpClient httpClient = HttpClients.createDefault();
//创建一个post对象
HttpPost post = new HttpPost("http://localhost:8083/search/doPostWithParam");
//注意,如果请求这里设置了 Accept header,那么 服务层的Controller 中的Mapping上就可以不用 produces属性,但是如果这样设置,那么Controller方法的返回值只能是String,否则结果无法封装会调用者
post.setHeader(new BasicHeader("Accept", "text/plain;charset=utf-8")); //模拟一个表单
List<NameValuePair> kvList = new ArrayList<NameValuePair>();
kvList.add(new BasicNameValuePair("username", "张三"));
kvList.add(new BasicNameValuePair("password", "123"));
//包装成一个Entity对象(后面加字符集是为了向服务端发送数据时不会乱码)
StringEntity paramEntity = new UrlEncodedFormEntity(kvList,"utf-8");
//设置请求内容
post.setEntity(paramEntity);
//执行post请求
CloseableHttpResponse response = httpClient.execute(post);
HttpEntity rtnEntity = response.getEntity();
String string = EntityUtils.toString(rtnEntity, "utf-8");
System.out.println(string);
response.close();
httpClient.close();
}
}

对应的  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.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; @Controller
public class HttpClientController { //无参数的get请求
/*prodcues的目的是为了返回给调用者时中文不乱码,
* 如果接口调用者请求的 http对象设置了
* httpget.setHeader(new BasicHeader("Accept", "text/plain;charset=utf-8"));
* 那么这里服务端可以不加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;
} //带参数的get请求响应
/**
* 同理,如果 接口调用者中 没有加 setHeader(new BasicHeader("Accept", "text/plain;charset=utf-8")
* 这里必须加上 produces=MediaType.TEXT_PLAIN_VALUE+";charset=utf-8"
*/
@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请求
@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 请求
/**
* 同理,如果 接口调用者中 没有加 setHeader(new BasicHeader("Accept", "text/plain;charset=utf-8")
* 这里必须加上 produces=MediaType.TEXT_PLAIN_VALUE+";charset=utf-8"
*/
//注意:post请求,后台服务接收端不用对参数进行转码
@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;
}
}

注意项总结

1、无论哪种请求//注意,如果请求端设置了 Accept header 例如:
        httpget.setHeader(new BasicHeader("Accept", "text/plain;charset=utf-8"));

那么 服务层的Controller 中的Mapping上就可以不用 produces属性,否则服务端的Controller中比如加入:

  produces=MediaType.TEXT_PLAIN_VALUE+";charset=utf-8"

这样才能保证请求端接收到的结果中的中文编码正确

但是,如果请求端设置了 Accept header ,那么Controller的方法的返回值 只能是 String类型,否则结果无法封装会调用者,

所有强烈建议不要这样做,最好还是在 Controller端返回值为字符串时,设置 produces 属性

2、对于带参数的 get 请求,必须在服务端 Controller 中进行字符串转码 例如:

  username = new String(username.getBytes("iso8859-1"), "utf-8");

否则接收到的参数就是乱码

HttpClient测试类请求端和服务端即可能出现乱码的解决的更多相关文章

  1. 写个OAuth2.0的请求端来测试自己的OAuth2.0服务端(二)

    在上一篇文章中,我们介绍了怎么创建自己的服务器,现在我们开始写个client端,来测试. 我们创建一个MVC项目,叫TestOAuthClient 1. 代码开始 1)第一步,我们创建一个MainCo ...

  2. HTTP服务端JSON服务端

    HTTP服务端JSON服务端 最后更新日期:  2014-5-18 Author: Kagula 阅读前提: CMake工具的基本使用 内容简介: CPPCMS是个开源Web开发框架,通过它可以很容易 ...

  3. 【转】京东金融App端链路服务端全链路压测策略

    京东金融移动端全链路压测历时三个月,测试和服务端同学经过无数日日夜夜,通宵达旦,终于完成了移动端链路的测试任务.整个测试有部分涉及到公司敏感数据,本文只对策略部分进行论述. 1.系统架构与策略 在聊性 ...

  4. 恩布企业IM PC端,服务端公布 1.16 版本号

    恩布企业IM PC端,服务端公布1.16版本号,开源企业IM.免费企业即时通讯软件:主要版本号更新内容: 恩布服务端核心程序,添加进程守护保护机制,确保系统7*24持续稳定服务: 服务端添加内存数据库 ...

  5. HttpURLConnection 发送PUT请求 json请求体 与服务端接收

    发送请求: public void testHttp() { String result = ""; try { URL postURL = new URL("http: ...

  6. socketserver及相关的类 (处理socket服务端)+ event事件的使用

    编写简单的套接字服务器并不难,然而,如果要创建的并非简单服务器,还要求助于服务器模块. 模块SocketServer是标准库提供的服务器框架的基石,这个框架包括好多服务器,他们基本服务器的基础上添加了 ...

  7. SimpleRpc-客户端与服务端工作模型探讨

    前言 本篇文章讲述客户端与服务端的具体设计细节.有细心的小伙伴发现,客户端和服务端的工作方式不一样:服务端是多线程计算模型,利用工作线程完成数据的读取,而客户端是单线程(利用Reactor线程完成数据 ...

  8. jetty 客服端 与服务端

    jetty 服务端,客服端有请求buffter 检查 默认4kb 4096 客服端 HttpClient client=new HttpClient(); client.setRequestBuffe ...

  9. 客服端与服务端APP支付宝支付接口联调的那些坑

    根据支付宝官方提供的文档的建议: TIPS:这一步应在商户服务端完成,商户服务端直接将组装和签名后的请求串orderString传给客户端,客户端直接传给SDK发起请求.文档和Demo是为了示例效果在 ...

随机推荐

  1. ko绑定----记录

    1.绑定变量 globalData = ko.observable({item:{}}); 2.绑定html ko.applyBindings(globalData, document.getElem ...

  2. python字符串编码

    python默认编码 python 2.x默认的字符编码是ASCII,默认的文件编码也是ASCII. python 3.x默认的字符编码是unicode,默认的文件编码是utf-8. 中文乱码问题 无 ...

  3. semcms 网站漏洞挖掘过程与安全修复防范

    emcms是国内第一个开源外贸的网站管理系统,目前大多数的外贸网站都是用的semcms系统,该系统兼容许多浏览器,像IE,google,360极速浏览器都能非常好的兼容,官方semcms有php版本, ...

  4. 幸运三角形 南阳acm491(dfs)

    幸运三角形 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 话说有这么一个图形,只有两种符号组成(‘+’或者‘-’),图形的最上层有n个符号,往下个数依次减一,形成倒 ...

  5. Python tips(

    (此文是在实际工程中遇到的一些小问题,给予解决和整理.解决方法大多来自网上零散的文章.有一个系统化的Python问题解决方案,来自<Python 3 学习笔记>雨痕著,其中对Python的 ...

  6. 【NOIP-2017PJ】图书管理员

    图书管理员 题目描述 图书馆中每本书都有一个图书编码,可以用于快速检索图书,这个图书编码是一个 正整数. 每位借书的读者手中有一个需求码,这个需求码也是一个正整数.如果一本书的图 书编码恰好以读者的需 ...

  7. GET TIME

    基本形式 GET TIME [FIELD tim]. オプション: ... FIELD tim 機能 FIELD オプションを使用しない場合. 日付および時刻のシステム項目 sy-datlo.sy-d ...

  8. java 堆栈内存分析详解

    计算机术语里面堆和栈代表不同的存储结构:stack-栈:heap-堆 所以java虚拟机(JVM)中堆和栈是两种内存 堆.栈对比 对比点 堆 栈 JVM中的功能 内存数据区 内存指令区 动静态 运行时 ...

  9. CSS3实现3d菜单翻转

    transform-style:flat | preserve-3d: 3d透视属性.针对子元素如何在3d空间相对其父元素渲染,这个属性声明在父元素上,并且他的子元素使用了transform才会有效. ...

  10. OpenCV代码提取:transpose函数的实现

    OpenCV中的transpose函数实现图像转置,公式为: 目前fbc_cv库中也实现了transpose函数,支持多通道,uchar和float两种数据类型,经测试,与OpenCV3.1结果完全一 ...