首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Tomcat服务器中运行的Java应用程序中不工作的UTF-8

在Tomcat服务器中运行的Java应用程序中不工作的UTF-8
EN

Stack Overflow用户
提问于 2021-12-27 07:28:30
回答 3查看 1.9K关注 0票数 6

我正在开发一个Java应用程序。我需要在我的Java中获得UTF-8编码,以支持孟加拉语(বাংলা)文本。我做了以下工作:

Tomcat's server.xml

代码语言:javascript
复制
<Connector port="8080"
    protocol="HTTP/1.1"
    connectionTimeout="20000"
    redirectPort="8443"
    URIEncoding="UTF-8" />

<Connector executor="tomcatThreadPool"
    port="8080"
    protocol="HTTP/1.1"
    connectionTimeout="20000"
    redirectPort="8443"
    URIEncoding="UTF-8" />

<Connector protocol="AJP/1.3"
    address="::1"
    port="8009"
    redirectPort="8443"
    URIEncoding="UTF-8" />

JVM defaultCharset中的catalina.bat文件

代码语言:javascript
复制
set JAVA_OPTS=%JAVA_OPTS% -Dfile.encoding=UTF-8

在application.properties中的性质

代码语言:javascript
复制
spring.datasource.url=jdbc:mysql://localhost:3306/database_name?useUnicode=true\&characterEncoding=UTF-8
spring.datasource.tomcat.connection-properties=useUnicode=true;characterEncoding=UTF-8

spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true

server.tomcat.uri-encoding=UTF-8
spring.webflux.multipart.headers-charset=UTF-8
spring.thymeleaf.encoding=UTF-8

html文件中的元标记

代码语言:javascript
复制
<!doctype html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
    <head>
        <meta charset="utf-8">
    </head>

    <body>
    </body>
</html>

utf-8对表单标记的支持

代码语言:javascript
复制
<form enctype="multipart/form-data" accept-charset="UTF-8" action="#" th:action="@{/create}" th:object="${object}" th:method="POST">
    <div class="form-group">
        <label for="name" class="col-form-label">Name</label>
        <input type="text" class="form-control" id="name" name="name" th:field="*{name}" placeholder="Enter Name">
    </div>
<div class="form-group">
    <label for="photo">Photo</label>
    <input type="file" class="form-control-file" id="photo" name="photo"/>
</div>
    <div>
        <button class="btn" type="submit">Submit</button>
    </div>
</form>

MySQL configuration (my.ini)

代码语言:javascript
复制
[client]
default-character-set = utf8mb4

[mysql]
default-character-set = utf8mb4

MySQL属性:

代码语言:javascript
复制
Database:
Default collation: utf8mb4_0900_ai_ci
Default charactterset: utf8mb4

Table:
Table collation: utf8mb4_0900_ai_ci

Column:
Type: varchar(255)
Character Set: utf8mb4
Collation: utf8mb4_0900_ai_ci

Configuration:

  • Java 11.0.2
  • Tomcat 8.5
  • MySQL 8.0.16
  • 弹簧启动2.2.4
  • Maven 3.8.1
  • Windows 2019标准(生产)+ Windows 10家庭(开发)

当我提交一个值为আনোয়ার的表单时,它将保存为আনোয়ার

我该如何解决这个问题?

当我从eclipse运行应用程序时,它工作得很好。但是,当war文件部署在Tomcat服务器上时,它无法工作。

我尝试了下面的代码。它在tomcat8-stdout文件中打印আনোয়ার。因此,我认为在从浏览器到服务器,从服务器到数据库传输数据时会出现问题。

代码语言:javascript
复制
@PostMapping("/create")
public String create(@ModelAttribute("object") Object object, @RequestParam("photo") MultipartFile photo) throws IOException {
    System.out.println(object.getName());
    return "redirect:/index";
}
EN

回答 3

Stack Overflow用户

发布于 2022-01-08 11:50:04

在使用Spring时,可以尝试使用CharacterEncondingFilter来强制执行UTF-8编码。

您可以找到关于如何做到这一点的多个示例。例如,考虑另一个

基本上,您需要在Java配置中的某个位置注册过滤器。举其中一个例子:

代码语言:javascript
复制
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public FilterRegistrationBean<CharacterEncodingFilter> characterEncodingFilterRegistration() {
  CharacterEncodingFilter filter = new CharacterEncodingFilter();
  filter.setEncoding("UTF-8"); // use your preferred encoding
  filter.setForceEncoding(true); // force the encoding

  FilterRegistrationBean<CharacterEncodingFilter> registrationBean =
    new FilterRegistrationBean<>(filter); // register the filter
  registrationBean.addUrlPatterns("/*"); // set preferred url
  return registrationBean;
}

实际上,这个注册过程应该由Spring HttpEncodingAutoConfiguration自动执行。请注意以下要求:

代码语言:javascript
复制
@Configuration(proxyBeanMethods=false)
@EnableConfigurationProperties(value=ServerProperties.class)
@ConditionalOnWebApplication(type=SERVLET)
@ConditionalOnClass(value=org.springframework.web.filter.CharacterEncodingFilter.class)
@ConditionalOnProperty(prefix="server.servlet.encoding",
                       value="enabled",
                       matchIfMissing=true)

如您所见,过滤器的注册与带有server.servlet.encoding前缀的属性相关。

因此,作为另一种选择,要正确配置字符集筛选器,可以尝试的另一种方法是使用与server.servlet.encoding.*相关的属性配置应用程序:

代码语言:javascript
复制
server.servlet.encoding.charset=UTF-8
server.servlet.encoding.force=true

您现在使用的不是前缀,而是application.properties配置。

这个问题可能与多部分请求的处理有关。尽管使用Spring和底层容器公开的默认机制是可取的,但您可以尝试使用commons-multipart处理文件上载,并配置库以将标头和表单字段作为UTF-8处理。这一过程可以实现如下。

首先,如果使用Maven,则将commons-fileupload依赖项包含在pom.xml中,如果使用Gradle,则包含相应的依赖项:

代码语言:javascript
复制
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.4</version>
</dependency>

然后,在Java配置的任何地方,包括以下bean:

代码语言:javascript
复制
@Bean(name = "multipartResolver")
public CommonsMultipartResolver multipartResolver() {
    CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
    // Note how we set the encoding
    multipartResolver.setDefaultEncoding("UTF-8");
    return multipartResolver;
}

如您所见,我们正在将默认编码属性配置为适当的值:

将默认字符编码设置为用于解析请求、应用于各个部件的标头和形成字段。根据Servlet规范,缺省值是ISO-8859-1

CommonsMultipartResolver提供了可以根据需要自定义上载行为的不同方法。

除了这些技巧,还有@Olivier在他的回答中的建议,乍一看,您似乎正确地配置了所有内容。在任何情况下,请考虑阅读,例如这是个相关的问题,虽然对于PHP,它可以提供有价值的信息。

至于您的评论,您的信息似乎是正确地传输到您的服务器和数据库之间,尝试调试您的HTML页面和服务器之间的通信。

这方面的一个宝贵工具可能是“浏览器检查器网络”选项卡:查看从页面提交到服务器的内容,几乎可以肯定的是,任何浏览器都会在发送它的实际编码中提供“原样”的实际信息。

实现同样目的的另一个有价值的工具可能是网络流量分析器,如Wireshark或Fiddler。

除非您有能力远程调试代码并查看变量值,否则请不要依赖于System.out提供的输出:当您在文件中查看时,存在大量的因素,几乎肯定会给出错误的信息。

为了寻找有关这个问题的信息,我偶然发现了这个优秀文章。特别是,它提供了一个分析组成String的不同代码点的示例:这种分析可以提供有价值的信息,而不是直接将信息输出到System.out

票数 6
EN

Stack Overflow用户

发布于 2022-01-08 09:20:53

POST参数的编码不是在Connector级别设置,而是在ServletRequest对象上设置。

Tomcat提供了一个过滤器来设置它,正如文档中所解释的那样。

将其添加到web.xml文件中:

代码语言:javascript
复制
<filter>
  <filter-name>setCharacterEncodingFilter</filter-name>
  <filter-class>org.apache.catalina.filters.SetCharacterEncodingFilter</filter-class>
  <init-param>
    <param-name>encoding</param-name>
    <param-value>UTF-8</param-value>
  </init-param>
</filter>

<filter-mapping>
  <filter-name>setCharacterEncodingFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
票数 3
EN

Stack Overflow用户

发布于 2022-01-10 16:34:01

您是否尝试将下面的server.xml设置为tomcat,以便允许URL中的转义字符

代码语言:javascript
复制
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000" relaxedPathChars="[]|" relaxedQueryChars="&#x5B;&#x5D;&#x7C;&#x7B;&#x7D;&#x5E;&#x5C;&#x60;&#x22;&#x3C;&#x3E;" redirectPort="8443" />
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70492711

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档