问题
我有一个使用ApacheCXF(JAX-RS(和Spring的遗留应用程序,它接受请求体中内容类型为application/json; charset=Windows-1252
的请求。现在,我正在将这个应用程序迁移到Spring Boot 2,我遇到了这个问题:
我的Spring Boot应用程序无法正确处理此请求:
{
"text": "Apenas um teste técnico çâãéüûà"
}
它处理为:
{
"text": "Apenas um teste técnico çâãéüûà "
}
如果客户端使用内容类型application/json; charset=UTF-8
,一切都可以,但我无法控制我的客户端,所以我无法确保它。
我用一些server.servlet.encoding
配置、CharacterEncodingFilter
配置和RequestBodyAdvice
做了很多测试,但到目前为止还没有成功。
下面您可以看到为Spring类启用了跟踪的测试:
使用字符集UTF-8的POST-OK
2022-11-01 21:02:20.695 TRACE 12932 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : POST "/string-encoding/v1/my-string", parameters={}, headers={masked} in DispatcherServlet 'dispatcherServlet'
2022-11-01 21:02:20.695 TRACE 12932 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'stringTestController'
2022-11-01 21:02:20.695 TRACE 12932 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.sap.string.encoding.controller.StringTestController#postString(HttpServletRequest, MyString)
2022-11-01 21:02:39.166 TRACE 12932 --- [nio-8080-exec-1] m.m.a.RequestResponseBodyMethodProcessor : Read "application/json;charset=UTF-8" to [MyString{text='Apenas um teste técnico çâãéüûà'}]
2022-11-01 21:02:39.166 TRACE 12932 --- [nio-8080-exec-1] o.s.web.method.HandlerMethod : Arguments: [org.apache.catalina.connector.RequestFacade@48c529f2, MyString{text='Apenas um teste técnico çâãéüûà'}]
Encoding: UTF-8, Text: Apenas um teste técnico çâãéüûà
2022-11-01 21:02:39.166 DEBUG 12932 --- [nio-8080-exec-1] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Using 'application/json', given [*/*] and supported [application/json, application/*+json, application/json, application/*+json]
2022-11-01 21:02:39.166 TRACE 12932 --- [nio-8080-exec-1] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Writing [MyString{text='Apenas um teste técnico çâãéüûà'}]
2022-11-01 21:02:39.716 TRACE 12932 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerAdapter : Applying default cacheSeconds=-1
2022-11-01 21:02:39.716 TRACE 12932 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : No view rendering, null ModelAndView returned.
2022-11-01 21:02:39.716 DEBUG 12932 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed 200 OK, headers={masked}
2022-11-01 21:02:39.716 TRACE 12932 --- [nio-8080-exec-1] o.s.b.w.s.f.OrderedRequestContextFilter : Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@48c529f2
cURL UTF-8
curl --request POST
--url http://localhost:8080/string-encoding/v1/my-string
--header 'Content-Type: application/json; charset=UTF-8'
--data '{
"text": "Apenas um teste técnico çâãéüûà"
}'
使用字符集Windows-1252的POST-错误
2022-11-01 21:01:26.759 TRACE 12932 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : POST "/string-encoding/v1/my-string", parameters={}, headers={masked} in DispatcherServlet 'dispatcherServlet'
2022-11-01 21:01:26.767 TRACE 12932 --- [nio-8080-exec-2] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'stringTestController'
2022-11-01 21:01:26.767 TRACE 12932 --- [nio-8080-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.sap.string.encoding.controller.StringTestController#postString(HttpServletRequest, MyString)
2022-11-01 21:01:42.091 TRACE 12932 --- [nio-8080-exec-2] m.m.a.RequestResponseBodyMethodProcessor : Read "application/json;charset=Windows-1252" to [MyString{text='Apenas um teste técnico çâãéüûà '}]
2022-11-01 21:01:42.107 TRACE 12932 --- [nio-8080-exec-2] o.s.web.method.HandlerMethod : Arguments: [org.apache.catalina.connector.RequestFacade@48c529f2, MyString{text='Apenas um teste técnico çâãéüûà '}]
Encoding: UTF-8, Text: Apenas um teste técnico çâãéüûÃ
2022-11-01 21:01:42.137 DEBUG 12932 --- [nio-8080-exec-2] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Using 'application/json', given [*/*] and supported [application/json, application/*+json, application/json, application/*+json]
2022-11-01 21:01:42.137 TRACE 12932 --- [nio-8080-exec-2] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Writing [MyString{text='Apenas um teste técnico çâãéüûà '}]
2022-11-01 21:01:43.526 TRACE 12932 --- [nio-8080-exec-2] s.w.s.m.m.a.RequestMappingHandlerAdapter : Applying default cacheSeconds=-1
2022-11-01 21:01:43.526 TRACE 12932 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : No view rendering, null ModelAndView returned.
2022-11-01 21:01:43.526 DEBUG 12932 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Completed 200 OK, headers={masked}
2022-11-01 21:01:43.526 TRACE 12932 --- [nio-8080-exec-2] o.s.b.w.s.f.OrderedRequestContextFilter : Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@48c529f2
cURL Windows-1252
curl --request POST
--url http://localhost:8080/string-encoding/v1/my-string
--header 'Content-Type: application/json; charset=Windows-1252'
--data '{
"text": "Apenas um teste técnico çâãéüûà"
}'
问题
我的Spring引导应用程序可以完美地使用UTF-8运行,并且可以正确地处理这些情况下的请求。我只需要确保向后兼容性,因为它在遗留应用程序中工作。
我需要一些自定义的过滤器来从Windows-1252
转换为UTF-8
吗?或者在MappingJackson2HttpMessageConverter
中进行一些配置?
此日志行:
Apenas um teste técnico çâãéüûÃ
清楚地表明UTF-8字符串被解释为windows-1252(而不是相反(。
原因是:你的卷曲测试是错误的。您正在发送一个UTF-8字符串,但声称它在windows-1252中。
为了正确地进行测试,您应该使用JSON内容创建一个文件,确保它在windows-1252中编码,并使用如下命令:
curl -d @test-1252.json -H "Content-Type: application/json; charset=windows-1252" http://localhost:8080/string-encoding/v1/my-string