spring boot + thymeleaf无法正确编码POST

时间:2015-10-13 17:30:39

标签: spring spring-mvc encoding spring-boot thymeleaf

我正在用百里叶模板引擎评估弹簧靴。我正面临着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(或百里香)无法正确编码具有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的{​​{1}}已经设置了UTF-8的characterEncoding。似乎没有必要在这里重新定义 @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; }

我似乎对这个问题有类似的情况:ThymeleafAutoConfiguration source code。接受的解决方案是

  

将CharacterEncodingFilter移动到顶部并强制进行编码   设置为UTF-8解决了问题。

我试过了:

<springboot.version>1.3.0.M5</springboot.version>
<spring.version>4.2.1.RELEASE</spring.version>

但仍然没有工作。

我认为UTF-8表单发布非常基础,但为什么它不能在这里工作。我错过了什么吗?

环境:

 <td>Master Event:</td>
 <td>
    <input type = "checkbox" id = "cb_e" name = "datesumm" value = "" >
    <label for = "cb_e">&nbsp; </label>
 </td>

非常感谢。

有点偏离主题:我使用过很多其他框架,例如JSP / wicket / grails / play1 / play2,其中没有这些烦人的UTF-8情况。

1 个答案:

答案 0 :(得分:3)

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;
}