spring boot + thymeleaf не може да кодира правилно UTF-8 символи от POST

Оценявам пролетно зареждане с машина за шаблони 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 (или 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 . Изглежда няма нужда да се предефинира UTF-8 тук.

Изглежда, че имам подобна ситуация с този въпрос: UTF-8 кодиране с формуляр post и 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.


person smallufo    schedule 13.10.2015    source източник


Отговори (1)


Това е известен проблем, вече е коригиран - корекцията ще бъде изпратена с 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;
}
person Brian Clozel    schedule 13.10.2015
comment
Благодаря. работи. Надяваме се, че 1.3.0.RC1 ще бъде пуснат скоро. - person smallufo; 14.10.2015