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. AIM Tech Round 5C. Rectangles 思维

    C. Rectangles time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...

  2. java8lambda表达式初识

    一.函数式接口 只有一个 抽象方法 的 接口 叫函数式接口 /** * @auther hhh * @date 2018/12/24 22:20 * @description 函数式接口:只有 一个 ...

  3. Python自动化运维——文件与目录差异对比

    Infi-chu: http://www.cnblogs.com/Infi-chu/ 模块:filecmp 安装:Python版本大于等于2.3默认自带 功能:实现文件.目录.遍历子目录的差异 常用方 ...

  4. STL 一些常用的STL函数(持续更新

    先说一下  一边要用到算法的东西一般要加#include<algorithm>头文件 一.栈和队列 1 栈 :一种线性表 特点  后进先出 头文件  #include<stack&g ...

  5. python--基本类型之列表

    Lest(列表): 定义和创建列表: 列表:是python以及其他语言中最常用的数据结构之一.python用 [] 来解析列表列表是可变的.--可以改变列表的内容可以用切片 a=['张三','李四', ...

  6. redhat6.4 安装Oracle11gR2 遇到的问题

    http://blog.sina.com.cn/s/blog_53a5865c0102e2u6.html   1.使用的时候出现一个错误: /lib/ld-linux.so.2: bad ELF in ...

  7. RAID(冗余硬盘阵列)

    一. RAID定义 RAID( Redundant Array of Independent Disk 独立冗余磁盘阵列 )技术是加州大学伯克利分校1987年提出,最初是为了组合小的廉价磁盘来代替大的 ...

  8. Java工程师笔试题整理[校招篇]

    Java工程师笔试题整理[校招篇]     隔着两个月即将开始校招了.你是不是也想借着这个机会崭露头角,拿到某些大厂的offer,赢取白富美.走上人生巅峰?当然如果你还没能打下Java基础,一定要先打 ...

  9. EFT4 生成实体类

    创建T4模本拷贝以下代码 <#@ template language="C#" debug="false" hostspecific="true ...

  10. KVM web管理工具——WebVirtMgr(一)

    WebVirtMgr 介绍     WebVirtMgr采用几乎纯Python开发,其前端是基于Python的Django,后端是基于Libvirt的Python接口,将日常kvm的管理操作变的更加的 ...