前面几篇介绍了如何获取http请求参数,在实际测试的时候发现了一个问题,如果传入的参数为中文的时候,接收没什么问题;但是返回有中文的时候,会出现乱码;接下来我们看一下这个问题如何解决
I. 基本环境 首先得搭建一个web应用才有可能继续后续的测试,借助SpringBoot搭建一个web应用属于比较简单的活;
创建一个maven项目,pom文件如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 <parent > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-parent</artifactId > <version > 2.1.7</version > <relativePath /> </parent > <properties > <project.build.sourceEncoding > UTF-8</project.build.sourceEncoding > <project.reporting.outputEncoding > UTF-8</project.reporting.outputEncoding > <spring-cloud.version > Finchley.RELEASE</spring-cloud.version > <java.version > 1.8</java.version > </properties > <dependencies > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-web</artifactId > </dependency > </dependencies > <build > <pluginManagement > <plugins > <plugin > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-maven-plugin</artifactId > </plugin > </plugins > </pluginManagement > </build > <repositories > <repository > <id > spring-milestones</id > <name > Spring Milestones</name > <url > https://repo.spring.io/milestone</url > <snapshots > <enabled > false</enabled > </snapshots > </repository > </repositories >
II. 中文乱码 1. 问题复现 一个简单的rest接口
1 2 3 4 5 6 7 8 9 10 @RestController @RequestMapping (path = "get" )public class ParamGetRest { @GetMapping (path = "arg" ) public String argParam (String name, Integer age) { String ans = "name: " + name + " age: " + age; System.out.println(ans); return ans; } }
我们实际测试一下,发现接收的name参数里的中文可以正常显示,输出控制台也没有问题;但是返回的正文却出现了乱码
2. 乱码问题修复 为什么返回的中文会出现乱码呢?要确定这个问题有必要先了解一下返回数据的处理逻辑,前面介绍了几篇web结合页面渲染引擎(thymeleaf, freemaker,beetl)的博文,里面返回的是视图,在参数解析篇里面,返回的是数据;那么web返回又有哪些不同的操作姿势呢,本篇将集中在解决返回中文乱码的问题上,至于上面提出的问题,则将作为后续的研究目标
a. HttpMessageConverter 对于返回数据的处理,有一个非常重要的类就是HttpMessageConverter,从命名上也可以看出,他的主要做那个用就是实现http信息的转换
至于导致我们出现中文乱码的,主要是StringHttpMessageConverter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class StringHttpMessageConverter extends AbstractHttpMessageConverter <String > { public static final Charset DEFAULT_CHARSET = StandardCharsets.ISO_8859_1; public StringHttpMessageConverter () { this (DEFAULT_CHARSET); } public StringHttpMessageConverter (Charset defaultCharset) { super (defaultCharset, MediaType.TEXT_PLAIN, MediaType.ALL); } }
上面是字符串转换类的默认构造方式,指定的字符集为"ISO-8859-1",而这个字符集是没法处理中文的,所以为了处理中文,我们希望指定编码为UTF-8
b. 注册HttpMessageConverter 所以为了解决中文乱码的问题,我们的一个思路就是通过new StringHttpMessageConverter(Charset.forName("UTF-8"));创建一个支持utf8编码的字符串转换类,然后将它注册给Spring容器,具体的操作借助配置类WebMvcConfigurationSupport
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @SpringBootApplication public class Application extends WebMvcConfigurationSupport { @Bean public HttpMessageConverter<String> responseBodyConverter () { StringHttpMessageConverter converter = new StringHttpMessageConverter(Charset.forName("UTF-8" )); return converter; } @Override public void configureMessageConverters (List<HttpMessageConverter<?>> converters) { super .configureMessageConverters(converters); converters.add(responseBodyConverter()); } public static void main (String[] args) { SpringApplication.run(Application.class); } }
c. 测试验证 然后再次测试验证下我们的处理是否生效
II. 其他 0. 项目&博文
1. 一灰灰Blog 尽信书则不如,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激
下面一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛
打赏
如果觉得我的文章对您有帮助,请随意打赏。
微信打赏
支付宝打赏