我在项目中使用Spring Boot,但遇到了一些编码问题。
在项目中,有一个控制器(下面),该控制器接受带有内容类型标头“ application / x-www-form-urlencoded; charset = GBK”的请求。
@RequestMapping(value = "/notify",headers ={"Content-Type=application/x-www-form-urlencoded;charset=GBK"} , method = RequestMethod.POST, produces = "application/x-www-form-urlencoded; charset=GBK") public ResponseEntity<String> notify(@RequestParam(name = "p") String plain, @RequestParam("s") String signature), HttpServletRequest request){}
当第三方调用此api时,它们将通过GBK编码请求主体。一旦主体包含中文字符集,我得到的参数是错误的,这是人类无法读取的,类似于“result Ʒ”之类的东西。
因为客户端使用GBK编码发送请求主体,但是Spring Boot使用UTF-8解码请求主体,这是Spring Boot的默认字符集编码。
该项目有不同的第三方,其中大多数使用的是UTF-8,因此我无法通过使用以下命令配置yml文件来将项目编码更改为GBK:
spring: http: encoding: charset: GBK enabled: true
所以我的第一个想法是反转我得到的错误字符串,但是我在以下测试中失败了。
String para = "p=result中文的&s=ad98adj"; byte[] bytes = para.getBytes("GBK"); ByteChunk byteChunk = new ByteChunk(); byteChunk.setBytes(bytes , 0 , bytes.length); byteChunk.setCharset(Charset.forName("utf-8")); String receive = byteChunk.toString();//this is the wrong string //reverse byteChunk.reset(); bytes = receive.getBytes("GBK"); byteChunk.setBytes(bytes , 0 ,bytes.length); byteChunk.setCharset(Charset.forName("GBK")); receive = byteChunk.toString(); //still the wrong string
因此,如何使用单个spring boot应用程序来支持GBK和UTF-8编码请求。
添加CharacterEncodingFilter bean可以解决此问题,请参见表格https://github.com/spring- projects/spring-boot/issues/1182
@Bean CharacterEncodingFilter characterEncodingFilter() { CharacterEncodingFilter filter = new CharacterEncodingFilter(); filter.setEncoding("UTF-8"); filter.setForceEncoding(true); return filter; }