spring boot + thymeleaf 无法正确编码 POST 中的 UTF-8 字符
Posted
技术标签:
【中文标题】spring boot + thymeleaf 无法正确编码 POST 中的 UTF-8 字符【英文标题】:spring boot + thymeleaf cannot correctly encode UTF-8 characters form POST 【发布时间】:2016-01-11 13:50:57 【问题描述】:我正在使用 thymeleaf 模板引擎评估 spring boot。我正面临UTF8字符形式发布问题。
对于最简单的form.html
帖子示例:
<head>
<title>test</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
<form th:action="@/test/doPost" method="post">
<input type="text" name="name" />
<button type="submit">submit</button>
</form>
在控制器中:
@Controller
@RequestMapping("/test")
public class TestController
private Logger logger = LoggerFactory.getLogger(getClass());
@RequestMapping(value = "/form", method = RequestMethod.GET)
public String showForm()
return "test/form";
@RequestMapping(value = "/doPost", method = RequestMethod.POST)
public String doPost(@RequestBody String body,
@RequestParam(value = "name", required = true) String name)
logger.info("body = ", body);
logger.info("name = ", name);
return "redirect:/test/form";
在此示例中,Spring MVC(或 thymeleaf)无法正确编码带有 UTF-8 字符的表单。
如果我输入 ä
,我会看到这个日志:
TestController - body = name=%C3%83%C2%A4
TestController - name = ä
ä
应编码为 %C3%A4
。正文应该是 name=%C3%A4
,但我不知道为什么它变成 %C3%83%C2%A4
并解码为错误的字符。
我google了一下,找到了一些解决方案,比如添加一个编码过滤器:
@Bean
public Filter characterEncodingFilter()
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceEncoding(true);
return characterEncodingFilter;
但不工作。
另一种解决方案是通过这种方式thymeleafViewResolver.setCharacterEncoding("UTF-8");
:
@Bean
public SpringResourceTemplateResolver templateResolver()
final SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setCacheable(false);
templateResolver.setPrefix("classpath:/templates/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("HTML5");
return templateResolver;
@Bean
public SpringTemplateEngine springTemplateEngine()
SpringTemplateEngine springTemplateEngine = new SpringTemplateEngine();
springTemplateEngine.setTemplateResolver(templateResolver());
return springTemplateEngine;
@Bean
public ThymeleafViewResolver viewResolver()
ThymeleafViewResolver thymeleafViewResolver = new ThymeleafViewResolver();
thymeleafViewResolver.setTemplateEngine(springTemplateEngine());
thymeleafViewResolver.setCharacterEncoding("UTF-8");
return thymeleafViewResolver;
但它也不起作用。
此外,ThymeleafViewResolver
的字符编码已经设置在 ThymeleafAutoConfiguration source code 中。这里似乎不需要重新定义UTF-8
。
似乎我对这个问题也有类似的情况:UTF-8 encoding with form post and Spring Controller。接受的解决方案是
将 CharacterEncodingFilter 移到顶部并强制编码 设置为 UTF-8 解决了这个问题。
我试过这个:
@Bean
public FilterRegistrationBean filterRegistrationBean()
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceEncoding(true);
registrationBean.setFilter(characterEncodingFilter);
registrationBean.setOrder(0);
return registrationBean;
但还是不行。
我认为 UTF-8 表单发布是非常基本的,但为什么它不能在这里工作。我错过了什么吗?
环境:
<springboot.version>1.3.0.M5</springboot.version>
<spring.version>4.2.1.RELEASE</spring.version>
非常感谢。
有点跑题了:我用过很多其他框架,比如 JSP/wicket/grails/play1/play2,没有一个有这么烦人的 UTF-8 情况。
【问题讨论】:
【参考方案1】:This is a known issue, already fixed - 该修复程序将随 Spring Boot 1.3.0.RC1 一起提供。
与此同时,您可以通过手动声明编码过滤器来解决此问题:
@Autowired
private HttpEncodingProperties httpEncodingProperties;
@Bean
public OrderedCharacterEncodingFilter characterEncodingFilter()
OrderedCharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
filter.setEncoding(this.httpEncodingProperties.getCharset().name());
filter.setForceEncoding(this.httpEncodingProperties.isForce());
filter.setOrder(Ordered.HIGHEST_PRECEDENCE);
return filter;
【讨论】:
谢谢。有用。希望 1.3.0.RC1 尽快发布。以上是关于spring boot + thymeleaf 无法正确编码 POST 中的 UTF-8 字符的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot2:使用Spring Boot结合Thymeleaf模板引擎使用总结