当前位置: 首页 > 知识库问答 >
问题:

spring boot thymeleaf无法从POST正确编码UTF-8字符

熊博远
2023-03-14

我正在评估与thymeleaf模板引擎的Spring启动。我正面临UTF8字符表单张贴问题。

对于最简单的表单。htmlpost示例:

<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 = ä

ä应编码为ä。正文应该是name=ä,但我不知道为什么它会变成Ã,并被解码成错误的字符。

我在谷歌上搜索并找到了一些解决方案,比如添加一个编码过滤器:

  @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

似乎我在这个问题上也有类似的情况:使用form post和Spring控制器进行UTF-8编码。公认的解决方案是

将特征编码过滤器移动到顶部并强制将编码设置为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个答案

尹俊雅
2023-03-14

这是一个已知的问题,已经修复-该修复程序将随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;
}
 类似资料:
  • 问题内容: 我正在尝试使用DOMDocument解析一些HTML,但是当我这样做时,我突然失去了编码(至少这对我来说是这样)。 这段代码的结果是我得到了一堆不是日语的字符。但是,如果我这样做: 正确显示。我尝试过saveHTML和saveXML,但都无法正确显示。我正在使用PHP 5.3。 我所看到的: 应该显示什么: 编辑:我已经将代码简化为五行,因此您可以自己对其进行测试。 这是返回的html

  • 我正在处理一个位置数据集,其中一些位置名称使用本地字符。大多数字符都被正确地看到,但我对一些罗马尼亚字符有意见,比如“ș”。 我尝试改变我的Windows 10 64位系统区域设置使用UTF-8编码,但这并没有解决问题。 可以在此处找到用于测试的示例文件:https://drive.google.com/file/d/1T7QQQ7G_dA_rXD9Ewf51uuQ6CUkscjP_/view?u

  • 我真的被Eclipselink MOXy 2.5.1卡住了,没有给我提供正确编码的亚洲字符(或其他字符,例如:德语umLautsäöü)。 我的代码: 测试类如下所示: 属性"key"仅为测试目的初始化一个字符串,我从一个UTF-8编码的文件中读取,该文件没有包含BOM 当我通过客户端调用这两种资源时: 我得到以下结果: 奇怪的是,当我在/test2中编组测试对象的toString()方法时,它将

  • 我正在尝试提交一个包含UTF-8字符的表单。 问题是,在查询日志中,日语字符是乱码的,从响应来看,它们似乎是双重编码的(UTF-8)。 如果我使用GET而不是POST,一切都会正常。谁能帮帮我吗?这在哪里得到双重编码?我该怎么修?

  • 问题内容: 我遇到了这行遗留代码,我试图找出这些遗留代码: 据我了解,它是使用相同的charSet进行编码和解码。 这与以下内容有何不同? 在任何情况下,两条生产线的输出将不同? ps:只是要澄清一下,是的,我知道Joel Spolsky撰写的关于编码 的出色文章! 问题答案: 这可能是很复杂的方式 这缩短了String,而所使用的基础char []则更长。 但是,更具体地说,将检查每个字符是否都

  • 问题内容: 我在AngularJS上建立的SPA中有一个文本输入框,供用户向打印输出中添加标题。输入框的声明如下: 文本框中填充了服务器提供的默认标题。用户可以将标题更改为适合他们的名称。更改标题后,服务器将更新并在响应的标题中发送回新标题,然后替换框中的标题。这非常适合标准ASCII类型的字符。 但是,对于unicode字符(例如àßéçøö),它不起作用。文本已正确发送,在服务器上正确更新并正