Java+Jetty欧洲字符编码异常问题求助
解决Jetty部署Spring REST服务时欧洲字符乱码问题
针对你遇到的ø显示为ø、接收端显示�的乱码问题,这是UTF-8编码被错误用ISO-8859-1解码的典型表现,结合本地正常、服务器异常的场景,按以下步骤排查修复:
1. 强制Jetty全局编码配置
1.1 添加编码过滤器
在项目的web.xml中添加CharacterEncodingFilter,确保请求/响应都强制使用UTF-8:
<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>
1.2 设置Jetty启动JVM参数
修改Jetty启动脚本(如start.ini或启动shell脚本),添加JVM编码参数,覆盖服务器系统默认编码:
-Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8
2. 修正SQL Server JDBC连接编码
即使数据库保存正常,也要确保JDBC连接时强制使用Unicode编码,在连接URL中添加:
jdbc:sqlserver://xxx:1433;databaseName=xxx;sendStringParametersAsUnicode=true;characterEncoding=UTF-8
sendStringParametersAsUnicode=true是SQL Server JDBC驱动的关键参数,确保字符串读写时用UTF-8编码。
3. 配置Spring MVC消息转换器
显式指定Spring的消息转换器编码,避免默认编码覆盖:
@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { // 处理字符串类型响应 StringHttpMessageConverter stringConverter = new StringHttpMessageConverter(StandardCharsets.UTF_8); stringConverter.setWriteAcceptCharset(false); // 禁止客户端指定编码覆盖 converters.add(stringConverter); // 处理JSON类型响应 MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter(); jsonConverter.setDefaultCharset(StandardCharsets.UTF_8); converters.add(jsonConverter); } }
4. 检查服务器系统默认编码
登录服务器执行以下命令,确认系统locale是否为UTF-8:
locale echo $LANG
如果输出不是en_US.UTF-8或类似UTF-8编码,可在Jetty启动脚本开头添加:
export LANG=en_US.UTF-8 export LC_ALL=en_US.UTF-8
5. 验证Jetty Servlet编码设置
如果通过代码配置Jetty Servlet,需显式设置编码参数:
ServletHolder springServletHolder = new ServletHolder(new DispatcherServlet(context)); springServletHolder.setInitParameter("encoding", "UTF-8"); springServletHolder.setInitParameter("forceEncoding", "true");
快速验证方法
在服务器端日志中打印字符的字节数组,确认编码转换逻辑:
String problematicStr = "ø"; // 打印原始字节(UTF-8下ø的字节是[-61, -98]) System.out.println(Arrays.toString(problematicStr.getBytes(StandardCharsets.UTF_8))); // 模拟错误解码(ISO-8859-1解码UTF-8字节会得到ø) System.out.println(new String(problematicStr.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
如果输出匹配你的异常场景,说明确实是某个环节将UTF-8字节用ISO-8859-1解码了,重点检查上述编码配置是否生效。
内容的提问来源于stack exchange,提问作者Nand
相关产品推荐
相关产品推荐

