2

我在我的项目中使用 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对请求正文进行编码。一旦正文包含中文字符集,我得到的参数是错误的,不是人类可读的,类似于“结果������Ʒ”。

因为客户端使用GBK编码发送请求体,但是spring boot使用UTF-8解码请求体,这是spring boot的默认字符集编码。

该项目有不同的第三方可用,其中大多数都使用 UTF-8,所以我无法通过配置 yml 文件将项目编码更改为 GBK:

spring:
  http:
    encoding:
      charset: GBK
        enabled: true

所以我的第一个想法是扭转我得到的错误字符串。但是我在下面的测试中失败了。

String para = "p=result中文的&amp;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 编码请求。

4

2 回答 2

3

添加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;
}
于 2016-10-09T16:14:55.413 回答
0

我遇到了类似的问题,发现 Spring Boot 默认启用了“forceEncoding”。这会导致请求字符集被覆盖并在其过滤器中每次设置为 UTF-8 。

请参阅附录 A。常见应用程序属性

关键部分是:

未指定“强制”时默认为 true。

所以设置要么

spring.http.encoding.force=false

或者

spring.http.encoding.force-request=false

只要请求具有正确的标头,应该可以解决您的问题。

于 2018-11-09T05:49:16.497 回答