一、概述

客户端与服务器端在交互过程中,需要将字符以某种编码方式转化为字节流进行传输,因此涉及字符的编码和解码。某一方以编码方案A编码,另一方须以同样的编码方案解码,否则会出现乱码。

客户端与服务器端的交互可分为三种:

  • 服务端向客户端传递数据
  • 客户端向服务端传递数据(POST)
  • 客户端向服务端传递数据(GET)

服务端在不指定编码方式时,默认使用 ISO-8859-1 解码

客户端在使用 encodeURIComponent() 方法时,使用 UTF-8 编码

二、服务端向客户端传递数据

服务端向客户端传递数据依赖HttpServletResponse类提供的方法,需要两步:

1、以某种编码写数据

response.getOutputStream().write("异常处理hello".getBytes("UTF-8"));

或者

response.setCharacterEncoding("UTF-8");
response.getWriter().write("异常处理hello");

2、添加响应头,告知客户端解码方式

response.addHeader("content-type", "text/html;charset=UTF-8");

三、客户端向服务端传递数据(POST)

客户端向服务端传递数据依赖HttpServletRequest类提供的方法,需要两步:

1、设置解码方式

request.setCharacterEncoding("UTF-8");

2、读取参数

String name = request.getParameter("name");
Integer age = Integer.valueOf(request.getParameter("age"));

测试请求包(使用Fiddler发起)

POST http://localhost:8080/java-web-test/encoding/1 HTTP/1.1
Content-Type: application/x-www-form-urlencoded name=%E9%80%89%E6%8B%A9%E5%A4%A7%E4%BA%8E%E5%8A%AA%E5%8A%9B&age=859

四、客户端向服务端传递数据(GET)

客户端通过GET方式(即通过url)传递参数,须以如下方式解析:

String name = new String(request.getParameter("name").getBytes("ISO-8859-1"), "UTF-8");

测试:http://localhost:8080/java-web-test/encoding/1?name=%E9%80%89%E6%8B%A9&age=52

即服务端默认以 ISO-8859-1 编码方式解析,解析时须以 ISO-8859-1 编码方式还原为字节码,再在以 UTF-8 编码方式解码

补充:

浏览器的encodeURIComponent()编码方式是将特定字符以 UTF-8 方式编码为二进制,再以%为分隔、以十六进制方式展示,如:

encodeURIComponent('选择'); // 输出:%E9%80%89%E6%8B%A9

java等价代码:

String str = URLEncoder.encode("选择", "UTF-8");

同样,decodeURIComponent() 解码方式是将以%为分隔的十六进制字符转换为二进制,再以 UTF-8 方式解码

decodeURIComponent("%E9%80%89%E6%8B%A9") // 输出:选择

java等价代码:

String str = URLDecoder.decode("%E9%80%89%E6%8B%A9", "UTF-8");

五、web.xml中设置编码方式

web.xml中,编码方式的设置可通过添加过滤器实现:

 <filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

过滤器的部分源码如下:

    @Override
protected void doFilterInternal(
HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException { if (this.encoding != null && (this.forceEncoding || request.getCharacterEncoding() == null)) {
request.setCharacterEncoding(this.encoding);
if (this.forceEncoding) {
response.setCharacterEncoding(this.encoding);
}
}
filterChain.doFilter(request, response);
}

即设置了请求与响应内容区的编码方式,但对GET请求无处理,因此仍然需要另外处理,如下:

@RestController
public class TestController { @RequestMapping(value = "/hello")
public Map<String, Object> helloWorld(@RequestParam("name") String name) throws UnsupportedEncodingException { Map<String, Object> map = new HashMap<String, Object>();
map.put("name", new String(name.getBytes("ISO-8859-1"), "UTF-8"));
return map;
}
}

测试:http://localhost:8080/myweb/hello?name=%E7%A8%8B%E5%90%9B&age=29

例外一种解决方法为添加过滤器,详细可参考javaweb学习总结(四十三)——Filter高级开发

参考:

javaweb学习总结(七)——HttpServletResponse对象(一)

javaweb学习总结(十)——HttpServletRequest对象(一)

javaweb学习总结(四十三)——Filter高级开发

Spring MVC 使用介绍(十)—— 编码的更多相关文章

  1. Spring MVC 使用介绍(十五)数据验证 (二)依赖注入与方法级别验证

    一.概述 JSR-349 (Bean Validation 1.1)对数据验证进一步进行的规范,主要内容如下: 1.依赖注入验证 2.方法级别验证 二.依赖注入验证 spring提供BeanValid ...

  2. Spring MVC 使用介绍(十四)文件上传下载

    一.概述 文件上传时,http请求头Content-Type须为multipart/form-data,有两种实现方式: 1.基于FormData对象,该方式简单灵活 2.基于<form> ...

  3. Spring MVC 使用介绍(十三)数据验证 (一)基本介绍

    一.消息处理功能 Spring提供MessageSource接口用于提供消息处理功能: public interface MessageSource { String getMessage(Strin ...

  4. Spring MVC 使用介绍(十二)控制器返回结果统一处理

    一.概述 在为前端提供http接口时,通常返回的数据需要统一的json格式,如包含错误码和错误信息等字段. 该功能的实现有四种可能的方式: AOP 利用环绕通知,对包含@RequestMapping注 ...

  5. Spring MVC 使用介绍(五)—— 注解式控制器(一):基本介绍

    一.hello world 相对于基于Controller接口的方式,基于注解方式的配置步骤如下: HandlerMapping 与HandlerAdapter 分别配置为RequestMapping ...

  6. Spring MVC 使用介绍(八)—— 类型转换

    一.概述 spring类型转换有两种方式: PropertyEditor:可实现String<--->Object 之间相互转换 Converter:可实现任意类型的相互转换 类型转换的过 ...

  7. spring mvc简单介绍xml版

    spring mvc介绍:其实spring mvc就是基于servlet实现的,只不过他讲请求处理的流程分配的更细致而已. spring mvc核心理念的4个组件: 1.DispatcherServl ...

  8. Spring MVC 数据验证——validate编码方式

    1.导入jar包 validation-api-1.0.0.GA.jar这是比較关键的一个jar包,主要用于解析注解@Valid. hibernate-validator-4.3.2.Final.ja ...

  9. Spring MVC 原理介绍(执行流程)

    Spring MVC工作流程图   图一   图二    Spring工作流程描述       1. 用户向服务器发送请求,请求被Spring 前端控制Servelt DispatcherServle ...

  10. Spring MVC 简单介绍

    Spring MVC 是典型的mvc架构,适合web开发. controler 输入输出的控制器,也是对外view提供数据的接口,调用service层. model 数据,由bean组成(相应表),关 ...

随机推荐

  1. 解决Centos7 yum 出现could not retrieve mirrorlist 错误

    刚通过VMware12安装了centos7.x后,使用ip addr查看centos局域网的ip发现没有,使用yum安装一些工具包时也出现报错: Loaded plugins: fastestmirr ...

  2. CentOS 7安装指南

    CentOS 7安装指南(U盘版) 一.准备阶段 1.下载CentOS7镜像文件(ISO文件)到自己电脑,官网下载路径: http://isoredirect.centos.org/centos/7/ ...

  3. 腾讯云centos7远程连接配置

    1.申请腾讯云 注册腾讯云账号,申请一个centos7的服务器,1G内存,1核处理器,1M网速. 对于这种入门级配置,建议还是别用windows server了,不然不装任何东西,光运行系统就需要60 ...

  4. Android为TV端助力 ViewTreeObserver(转载)

    Android ViewTreeObserver简介   一.结构 public final class ViewTreeObserver extends Object java.lang.Objec ...

  5. 关于如何使用xposed来hook某支付软件

    由于近期有业务上的需要,所以特地花时间去研究了一下如何使用hook技术.但是当我把xposed环境和程序编写完成时,突然发现手机上的某个支付软件无法使用了.这个时候我意识到,应该是该软件的安全机制在起 ...

  6. win10的react native 开发环境搭建,使用Android模拟器

    1.打开cmd的管理员模式,win+X,选择命令提示符(管理员)即可,运行如下命令: @"%SystemRoot%\System32\WindowsPowerShell\v1.0\power ...

  7. 测者的测试技术手册:自动化单元工具EvoSuie的代码覆盖报告

    EvoSuite是由Sheffield等大学联合开发的一种开源工具,用于自动生成测试用例集,生成的测试用例均符合Junit的标准,可直接在Junit中运行.得到了Google和Yourkit的支持. ...

  8. Spark资源调度和任务调度

    一.资源调度&任务调度 1.启动集群后,Worker节点会周期性的[心跳]向Master节点汇报资源情况,Master掌握集群资源情况. 2.当Spark提交一个Application后,根据 ...

  9. [转]QQ空间、新浪微博、腾讯微博等一键分享API链接代码

    转自------ 1.新浪微博:http://service.weibo.com/share/share.php?url= count=表示是否显示当前页面被分享数量(1显示)(可选,允许为空)&am ...

  10. kmalloc分配物理内存与高端内存映射--Linux内存管理(十八)

    1 前景回顾 1.1 内核映射区 尽管vmalloc函数族可用于从高端内存域向内核映射页帧(这些在内核空间中通常是无法直接看到的), 但这并不是这些函数的实际用途. 重要的是强调以下事实 : 内核提供 ...