一、概述

客户端与服务器端在交互过程中,需要将字符以某种编码方式转化为字节流进行传输,因此涉及字符的编码和解码。某一方以编码方案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. Scrapped or attached views may not be recycled

    在使用recycleView的时候出现了错误Scrapped or attached views may not be recycled 原因: view没有被recycled,recyclerVie ...

  2. Android 通过反射获取DatePicker 中的控件,并改变其颜色

    到最后也只是成功改变了中间部分的颜色. private void setDatePickerDividerColor(DatePicker datePicker) { // Divider chang ...

  3. android中的websocket 应用

    websocket 在实际的应用中不仅仅能做聊天应用,还可以利用websocket长连接保持数据的实时更新以及信息的推送. websocket 的实现的关键点 第一个:首先需要引入 java-webs ...

  4. matlab练习程序(渲染三原色)

    这里我用的空间是x向右为正,y向下为正,z向屏幕里面为正.相当于标准右手系绕x轴旋转了180度. 将三个点光源放在 r = [0.3,0,0.5];g = [0.3,-0.5*cos(pi/6),-0 ...

  5. 010 Editor v8.0.1(32 - bit) 算法逆向分析、注册机编写

    010 Editor 的逆向分析整体算下来还是比较简单的,将程序拖入OD,通过字符串搜索定位到核心代码,经过分析,主要是如下图所示的两个关键函数,返回正确的值,才算是注册成功. 00409C9B 这个 ...

  6. c#操作SQL Server入门总结

    我是一名c#新手.本文只是我是常学习的随笔. 一.下载SQL server软件 听说下载开发板是最好的(开发板如果只是用来学习.研究不算是侵权).在安装的时候,我也遇到了很多问题,在公司的电脑安装第一 ...

  7. 爬虫系列---selenium详解

    一 安装 pip install Selenium 二 安装驱动 chrome驱动文件:点击下载chromedriver (yueyu下载) 三 配置chromedrive的路径(仅添加环境变量即可) ...

  8. 使用idea搭建Scala 项目

    主要内容 Intellij IDEA开发环境简介 Intellij IDEA Scala开发环境搭建 Intellij IDEA常见问题及解决方案 Intellij IDEA常用快捷键 1. Inte ...

  9. JavaScript-创建日志调试对象(面向对象实例)

    参考自http://www.2cto.com/kf/201312/261990.html IC.js文件 自己封装的js类库 /** * * @authors Your Name (you@examp ...

  10. Spring service本类中方法调用另一个方法事务不生效问题(转载)

    前些日子一朋友在需要在目标对象中进行自我调用,且需要实施相应的事务定义,且网上的一种通过BeanPostProcessor的解决方案是存在问题的.因此专门写此篇帖子分析why. 1.预备知识 aop概 ...