如何在Spring Boot中设置UTF-8字符编码?

20

我在项目中使用spring-boot,并将由spring-boot构建的JAR文件作为服务在Centos上运行。当我运行此服务时:

service myApp start

我总是会收到以下错误消息:

2016-08-26 09:11:02.002 ERROR 31900 --- [           main] o.s.b.c.FileEncodingApplicationListener  : System property 'file.encoding' is currently 'ANSI_X3.4-1968'. It should be 'UTF-8' (as defined in 'spring.mandatoryFileEncoding').
2016-08-26 09:11:02.018 ERROR 31900 --- [           main] o.s.b.c.FileEncodingApplicationListener  : Environment variable LANG is 'null'. You could use a locale setting that matches encoding='UTF-8'.
2016-08-26 09:11:02.018 ERROR 31900 --- [           main] o.s.b.c.FileEncodingApplicationListener  : Environment variable LC_ALL is 'null'. You could use a locale setting that matches encoding='UTF-8'.
2016-08-26 09:11:02.031 ERROR 31900 --- [           main] o.s.boot.SpringApplication               : Application startup failed
java.lang.IllegalStateException: The Java Virtual Machine has not been configured to use the desired default character encoding (UTF-8).
    at org.springframework.boot.context.FileEncodingApplicationListener.onApplicationEvent(FileEncodingApplicationListener.java:74) ~[spring-boot-1.3.7.RELEASE.jar!/:1.3.7.RELEASE]
如果我直接运行这个JAR文件,那么这个应用程序将正常运行。

java -jar target/myApp-1.0.jar

 .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.3.7.RELEASE)

......

2016-08-26 09:54:34.954 DEBUG 32035 --- [           main] o.s.w.s.resource.ResourceUrlProvider     : Found resource handler mapping: URL pattern="/**", locations=[ServletContext resource [/], class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver@1817d444]
2016-08-26 09:54:35.051  INFO 32035 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8000 (http)
2016-08-26 09:54:35.053 DEBUG 32035 --- [           main] o.s.w.c.s.StandardServletEnvironment     : Adding [server.ports] PropertySource with highest search precedence
2016-08-26 09:54:35.061  INFO 32035 --- [           main] co.nz.myApplication           : Started myApplication in 12.339 seconds (JVM running for 13.183)

这是pom.xml文件:

<project>
....

 <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.3.7.RELEASE</version>
    <relativePath/>
 </parent>

 <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <java.version>1.8</java.version>
 </properties>
 ....

 <build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <executable>true</executable>
                <jvmArguments>-Dfile.encoding=UTF8 -Dspring.profiles.active="production"</jvmArguments>
            </configuration>
            <dependencies>
                <dependency>
                    <groupId>org.springframework</groupId>
                    <artifactId>springloaded</artifactId>
                    <version>1.2.5.RELEASE</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
 </build>
</project>

应用程序配置文件:

....
spring.mandatory-file-encoding=UTF-8
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
....

CentOS的本地化设置:

$ locale

LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=en_US.UTF-8

我尽可能地检查了所有文件设置,但仍然不知道如何解决这个问题。如果您能给我任何建议,我将不胜感激。


创建一个FilterRegistrationBean 请参见:字符编码过滤器 - Kuldeep Singh
4个回答

17

解决方案

在配置文件中添加以下行(对于应用程序/var/app/app.jar,配置文件为/var/app/app.conf):

export LANG='en_US.UTF-8'

原因

问题出在Linux的systemdservice)中。我使用脚本/etc/init.d/test进行了测试:

#/bin/bash
locale

命令 $ /etc/init.d/test 的结果:

LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

以及命令$ service test的结果:

LANG=
LC_CTYPE="POSIX"
LC_NUMERIC="POSIX"
LC_TIME="POSIX"
LC_COLLATE="POSIX"
LC_MONETARY="POSIX"
LC_MESSAGES="POSIX"
LC_PAPER="POSIX"
LC_NAME="POSIX"
LC_ADDRESS="POSIX"
LC_TELEPHONE="POSIX"
LC_MEASUREMENT="POSIX"
LC_IDENTIFICATION="POSIX"
LC_ALL=

在Spring Boot的JAR文件中,内置了systemd脚本,在运行Spring Boot之前会执行其他操作:

# Source any config file
configfile="$(basename "${jarfile%.*}.conf")"

# Initialize CONF_FOLDER location defaulting to jarfolder
[[ -z "$CONF_FOLDER" ]] && CONF_FOLDER="${jarfolder}"

# shellcheck source=/dev/null
[[ -r "${CONF_FOLDER}/${configfile}" ]] && source "${CONF_FOLDER}/${configfile}"

谢谢,这为我节省了很多时间,非常有帮助。 - Gaurav Rawat

5

2
我尝试了你的命令,但是不起作用。这个命令应该是 java -Dfile.encoding=UTF-8 -jar khar.jar - M. Rostami
这是用于JAR应用程序而非Spring Boot的 - 我的项目中没有JAR文件。 - Michail Michailidis
向下投票,因为运行此Maven命令仅适用于您的本地环境。 对于这个答案在操作员端工作,他们需要在服务器内安装Maven,您不应该这样做,因为Maven是开发人员的构建工具,而不是操作工具。 在服务器环境中,无论是直接还是间接运行(通过服务启动命令或类似方式),都应该使用java -jar命令。 - Jukka Hämäläinen
不要在服务器上运行此Maven命令,因为它仅适用于本地环境。要使此答案适用于操作员,他们需要在服务器上安装Maven,但你不应该这样做,因为Maven是开发人员的构建工具,而不是运维工具。在服务器环境中,所有操作都应该使用java -jar命令运行,无论是直接运行还是间接运行(通过服务启动命令等)。 - undefined

2

最终我找到了一个方法,使我能够正确地启动Spring-boot项目。

解决方案是使用sudo /etc/init.d/myApp start而不是service myApp start


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接