我有一个 Spring MVC Web 应用程序并使用 JSP 来创建我的网页。 问题是,当我直接提交表单时,编码是“application/x-www-form-urlencoded”。当我通过 AJAX 请求从同一表单提交相同数据时,编码为“application/x-www-form-urlencoded; charset=UTF-8”。
我需要在我的 Controller 中作为用户输入 utf8 编码的字符。例如:用户输入“äöüß”,我的 Controller 得到“äöüß”。当我通过 AJAX 请求发送数据时,我得到正确的“äöüß”。
我做错了什么?这是一个通过 http-post 提交的简单表单。 utf8 编码不可能是不可能的。
我的应用程序在带有 Spring 5.0.1 的 tomcat 8.5.11 上运行。网页都是 HTML5 的,我在 servlet 3.1 环境中使用 JSTL 1.2.5。 JSON映射和序列化由fasterxml 2.9.2完成
配置完全基于Java。
我的 WebAppInitializer(又名 web.xml)
...
@Override
protected Filter[] getServletFilters() {
return new Filter[] { new HiddenHttpMethodFilter(),
new CharacterEncodingFilter("UTF-8", true, true) };
}
在我的 servlet 配置中,我显式地为 StringHttpMessageConverter 设置了一个字符集。
...
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new StringHttpMessageConverter(Charset.forName("UTF-8")));
converters.add(new ResourceHttpMessageConverter());
converters.add(new MappingJackson2HttpMessageConverter());
}
网页看起来像
<%@page contentType="text/html;charset=UTF-8"%>
<%@page pageEncoding="UTF-8"%>
<%@page session="true" %>
<%@page trimDirectiveWhitespaces="true" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<!DOCTYPE html>
<html lang="de">
...
<meta charset="UTF-8"/>
...
<form id="createArticleForm" action="<c:url value='/article/save' />" method="post">
<input type="hidden" name="utf8" value="✓" />
...
<input type="text" name="name" required="required" />
...
</form>
正如你所看到的,我还尝试了带有隐藏字段的 utf8 hacks。但没有任何作用。即使我设置表单属性accept-charset =“UTF-8”和/或encoding =“application/x-www-form-urlencoded; charset = UTF-8”也没有任何变化。
编辑1 我检查了从浏览器发送到服务器的 HTTP 请求 header 。我发现所有参数都是正确的。所以我假设 Spring 配置问题。
最佳答案
我自己找到了解决方案。问题出在characterEncodingFilter的初始化上。
在 web.xml 中,您执行以下操作:
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
由于 Spring 5 基于 Java 的注释配置受到青睐,根据文档,您可以在 WebApplicationInitializer 中执行以下操作,这比上面的代码简单得多:
@Override
protected Filter[] getServletFilters() {
return new Filter[] { new HiddenHttpMethodFilter(),
new CharacterEncodingFilter("UTF-8", true, true) };
}
但是这对于每个传入的 HttpRequest 都不能正常工作!!!
解决方案是不使用提供的便捷方法自动将过滤器映射到servlet。
相反,您必须:
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
FilterRegistration.Dynamic filterRegistration = servletContext.addFilter("characterEncodingFilter", new CharacterEncodingFilter("UTF-8", true, true));
filterRegistration.addMappingForUrlPatterns(null, false, "/*");
filterRegistration = servletContext.addFilter("hiddenHttpMethodFilter", new HiddenHttpMethodFilter() );
filterRegistration.addMappingForUrlPatterns(null, false, "/*");
super.onStartup(servletContext);
}
在这里,您可以重新看到过滤器映射,这非常完美!
关于java - 使用 Spring MVC Web 应用程序强制以 html 形式进行 UTF8 编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50987844/