JavaWeb 乱码问题终极解决方案!

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
云数据库 RDS MySQL Serverless,价值2615元额度,1个月
简介: JavaWeb 乱码问题终极解决方案!经常有读者在公众号上问 JavaWeb 乱码的问题,昨天又有一个小伙伴问及此事,其实这个问题很简单,但是想要说清楚却并不容易,因为每个人乱码的原因都不一样,给每位小伙伴都把乱码的原因讲一遍也挺费时间的,因此,松哥今天决定写一篇文章,和大伙好好捋捋 JavaWeb 中的乱码问题。

JavaWeb 乱码问题终极解决方案!

经常有读者在公众号上问 JavaWeb 乱码的问题,昨天又有一个小伙伴问及此事,其实这个问题很简单,但是想要说清楚却并不容易,因为每个人乱码的原因都不一样,给每位小伙伴都把乱码的原因讲一遍也挺费时间的,因此,松哥今天决定写一篇文章,和大伙好好捋捋 JavaWeb 中的乱码问题。

对于一些老司机而言,其实并不太容易遇到乱码问题,但是对于一些新手来说,乱码几乎是家常便饭,而且每当乱码时,网上搜了一大堆解决方案,发现自己的问题还是没能解决,其实这就是平时研究代码不求甚解导致的,乱码问题,也要去分析,然后才能对症下药,才能药到病除。

整体思路
首先出现乱码之后,要先去确认乱码的地方,当一个网页上出现乱码,有可能是浏览器显示问题,也有可能是 Java 编码问题,也有可能数据库中的数据本身就是乱码的,所以我们要做的第一件事就是确认乱码发生的位置,缩小 bug 范围,通过打印日志或者 debug 首先去确认乱码发生的位置,然后再去进一步解决,一般来说,乱码的原因大致上可以分为两类:

请求乱码
响应乱码
请求乱码,可能是因为参数放在 URL 地址中乱码,也有可能是参数放在请求体中乱码,不同传参方案也对应了不同的乱码解决方案。如果是响应乱码,那么原因就会比较多了,一般来说,有如下几种可能的原因:

数据库本身乱码
数据在 Java 代码中乱码
数据在浏览器显示的时候乱码
数据在从 Java 应用传到数据库的过程中乱码
对于不同的乱码原因,会有不同的解决方案,对症下药,才能药到病除,所以当出现乱码时,大家要做的第一件事就是分析乱码发生的原因,找到原因了,才能找到解决方案。

基本原则
发生乱码是因为各自编码不同导致的,所以,大家首先要有一个良好的开发习惯,项目编码,文件编码都要统一起来,松哥有个同事就因为 Freemarker 乱码,找了半天没找到原因,后来在松哥建议下修改了项目编码,乱码问题才解决了,一般来说,公司制度稍微成熟一些,都会对项目编码,文件编码有硬性规定的。在Eclipse 中,设置项目编码方式如下(工程的编码要提前设置,如果项目已经开发一半再去设置,已有的中文就会乱码):

Window->Preferences->General

然后对于 JSP 文件也需要提前设置好编码方式,如下:

这是在 Eclipse 中设置文件编码,如果是在 IntelliJ IDEA中,则不需要设置JSP文件编码,因为默认就是 UTF-8,只需要提前设置下工程编码即可:

除了开发工具的编码,数据库的编码也要统一,一般来说,主要是设置一下数据库的编码和数据表的编码,如下:

设置数据库编码:

CREATE DATABASE vhr DEFAULT CHARACTER SET utf8;
设置数据表编码:

DROP TABLE IF EXISTS adjustsalary;
CREATE TABLE adjustsalary (
id int(11) NOT NULL AUTO_INCREMENT,
eid int(11) DEFAULT NULL,
PRIMARY KEY (id),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
这些是准备工作,这些工作做好了,还是有可能会遇到乱码问题,接下来我们就具体问题具体分析。

请求乱码
请求乱码,就是说数据在浏览器中显示是正常的,但是传到 Java 后端之后,就乱码了,这种乱码一般来说,分为两种:

参数放在 URL 地址中导致的乱码
参数放在请求体中导致的乱码
两种乱码原因,对应了两种不同的解决方案。分别来看。

URL 地址中的参数乱码
这种乱码主要发生在 GET 请求中,因为在 GET 请求中我们一般通过 URL 来传递参数,这个问题可以在代码中解决,但是太过于麻烦,因此一般我们直接在Tomcat配置中解决,修改 Tomcat的conf/server.xml 文件,修改 URL 编码格式,如下:

这样就可以搞定 URL 地址中的参数乱码。

请求体中的参数乱码
请求体中的参数乱码,我们可以在解析参数之前通过设置 HttpServletRequest 的编码来解决,如下:

request.setCharacterEncoding("UTF-8");
但是一样也太过于麻烦,所以如果是普通的 Servlet/JSP 项目,我们就可以直接定义一个过滤器来处理,如下:

public class EncodingFilter implements Filter {

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    request.setCharacterEncoding("UTF-8");
    chain.doFilter(request, response);
}

}
过滤器配置:

<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.sang.filter.EncodingFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

在工程编码和JSP/HTML编码都没问题的情况下,请求乱码基本上就是这两种情况。

响应乱码
如果在浏览器上加载页面看到了乱码,大家首先要确认在从服务端往浏览器写数据的前一刻,这个数据还没有乱码(即数据库中查询出来的数据是OK的,没有发生乱码的问题),那么对于这种乱码,我们只需要设置响应数据的 ContentType 就可以了,如下:

response.setContentType("text/html;charset=UTF-8");
如果从数据库中查询出来的数据就是乱码的,那么就需要去确认数据库中的编码是否 OK 。

框架处理
前面提到的方案,都是在 Servlet/JSP 项目中我们可以采用的方案,在 SSM 框架中当然也可以使用,但是,SpringMVC 框架本身也提供了一个过滤器,我们可以借用这个过滤器更加高效的解决响应乱码问题,如下:

<filter-name>encoding</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>forceRequestEncoding</param-name>
    <param-value>true</param-value>
</init-param>
<init-param>
    <param-name>forceResponseEncoding</param-name>
    <param-value>true</param-value>
</init-param>


<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>


当然,上面这段配置并不能代替 Tomcat 中 conf/server.xml 中的编码配置,如果是在 Spring Boot 中,配置可以更加简单,只需要在 application.properties 中添加如下配置即可:

server.tomcat.uri-encoding=UTF-8
spring.http.encoding.force-request=true
spring.http.encoding.force-response=true
其他乱码
其他乱码主要是指使用一些第三方框架导致的乱码,例如使用 Alibaba 的 fastjson,开发者就需要在配置 HttpMessageConverter 时指定编码格式,否则就有可能出现乱码,这种第三方框架的乱码松哥没法穷举,大伙在使用时需要注意看官方文档,fastjson 的 HttpMessageConverter 配置如下:

@Bean
FastJsonHttpMessageConverter fastJsonHttpMessageConverter() {

FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
FastJsonConfig config = new FastJsonConfig();
config.setCharset(Charset.forName("UTF-8"));
converter.setFastJsonConfig(config);
converter.setDefaultCharset(Charset.forName("UTF-8"));
return converter;

}
一个隐蔽的乱码
除了前面介绍的这几种乱码之外,还有一个比较隐蔽的乱码,容易被很多初学者忽略的地方,就是数据在从 Java 应用传递到 MySQL 的过程中,发生了乱码,这种问题一般在 Windows 上不易发生,如果数据库装在 Linux 上,则这个问题就很容易发生,数据在代码中命名没有乱码,存到 MySQL 上就乱码了,但是如果直接使用 Navicat 等工具往 MySQL 上存储数据,又不会乱码,或者 MySQL 中数据没有乱码,但是用 Java 查询出来就乱码了,这种都是数据在 应用 和 数据库 之间传递时发生了乱码,解决方式很简单,在数据库连接地址上指定编码即可,如下:

db.url=jdbc:mysql:///yuetong?useUnicode=true&characterEncoding=UTF-8
大致就这些,还有一些非常偶尔的情况可能会用到 @RequestMapping 注解中的 produces 属性,在这里指定数据类型即可。

原文地址https://www.cnblogs.com/lenve/p/10675044.html

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
10天前
|
Java UED
Java Web 中forward 和 redirect 的区别
在Java Web开发中,页面跳转是构建用户界面和实现业务逻辑的重要组成部分。Forward(转发)和Redirect(重定向)是两种常见的跳转方式,它们分别具有不同的特点和适用场景。正确地选择和使用这两种跳转方式,有助于提高Web应用的性能、用户体验和代码可维护性。
19 4
|
22天前
|
Java
Java 字符串分割split空字符串丢失解决方案
Java 字符串分割split空字符串丢失解决方案
|
27天前
|
监控 JavaScript 前端开发
《理解 WebSocket:Java Web 开发的实时通信技术》
【4月更文挑战第4天】WebSocket是Java Web实时通信的关键技术,提供双向持久连接,实现低延迟、高效率的实时交互。适用于聊天应用、在线游戏、数据监控和即时通知。开发涉及服务器端实现、客户端连接及数据协议定义,注意安全、错误处理、性能和兼容性。随着实时应用需求增加,WebSocket在Java Web开发中的地位将更加重要。
|
28天前
|
前端开发 JavaScript Java
使用Ajax进行异步交互:提升Java Web应用的用户体验
【4月更文挑战第3天】Ajax技术在Web开发中提升UX,通过与服务器异步交互实现页面局部更新,无需完整刷新。核心组件包括XMLHttpRequest、JavaScript、HTML/CSS及服务器端脚本。在Java Web应用中,可使用原生JavaScript或框架如jQuery、AngularJS实现Ajax请求。Ajax减少页面刷新,实现实时数据更新,即时表单验证和动态UI,显著改善用户体验,是现代Web开发不可或缺的一部分。
|
28天前
|
JSON Java 应用服务中间件
JavaWeb项目之乱码问题及如何解决
JavaWeb项目之乱码问题及如何解决
|
6天前
|
存储 消息中间件 Java
Java多线程实战-异步操作日志记录解决方案(AOP+注解+多线程)
Java多线程实战-异步操作日志记录解决方案(AOP+注解+多线程)
|
7天前
|
设计模式 存储 前端开发
Java从入门到精通:2.2.1学习Java Web开发,了解Servlet和JSP技术,掌握MVC设计模式
Java从入门到精通:2.2.1学习Java Web开发,了解Servlet和JSP技术,掌握MVC设计模式
|
12天前
|
缓存 负载均衡 前端开发
构建高性能 Java Web 应用程序
【4月更文挑战第19天】构建高性能 Java Web 应用涉及数据库优化(合理设计、查询优化、性能调优)、缓存策略(服务器端缓存、HTTP 缓存)、代码优化(避免冗余查询、减少对象创建、有效使用线程)、异步处理(增强并发能力)、负载均衡(分发请求、提升可靠性)、性能测试与监控(发现瓶颈、实时问题)、前端优化(减少加载时间、优化资源)、服务器配置(硬件资源、系统优化)以及代码压缩和资源合并。综合运用这些技术,能显著提升应用性能和用户体验。
|
16天前
|
Web App开发 Java 应用服务中间件
【Java Web】在 IDEA 中部署 Tomcat
【Java Web】在 IDEA 中部署 Tomcat
|
16天前
|
JavaScript Java 测试技术
基于Java的web新闻流媒体平台的设计与实现(源码+lw+部署文档+讲解等)
基于Java的web新闻流媒体平台的设计与实现(源码+lw+部署文档+讲解等)
21 0