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

以下为比较常见的编码设置

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

(1)请求乱码

  请求乱码,可能是因为参数放在 URL 地址中乱码,也有可能是参数放在请求体中乱码,不同传参方案也对应了不同的乱码解决方案。

(2)响应乱码

  如果是响应乱码,那么原因就会比较多了,一般来说,有如下几种可能的原因:
    (1)数据库本身乱码;
    (2)数据在 Java 代码中乱码;
    (3)数据在浏览器显示的时候乱码;
    (4)数据在从 Java 应用传到数据库的过程中乱码;
当出现乱码时,大家要做的第一件事就是分析乱码发生的原因,找到原因了,才能找到解决方案。

基本原则

  发生乱码是因为各自编码不同导致的,所以,大家首先要有一个良好的开发习惯,项目编码,文件编码都要统一起来。在MyEclipse 中,设置项目编码方式如下(工程的编码要提前设置,如果项目已经开发一半再去设置,已有的中文就会乱码):

设置步骤:Window–>Preferences–>General–>Workspace

乱码检测java java出现乱码的原因_数据库

  然后对于 JSP 文件也需要提前设置好编码方式(这一步一般都是默认设置了UTF-8,不需要我们手动再去设置了),如下:

乱码检测java java出现乱码的原因_数据库_02


  这是在 MyEclipse 中设置文件编码,如果是在 IntelliJ IDEA中,也不需要设置JSP文件编码,因为默认就是 UTF-8,只需要提前设置下工程编码即可:(编辑器右下角)

乱码检测java java出现乱码的原因_数据库_03

idea常见的乱码设置:参考以下设置:

第一种:

乱码检测java java出现乱码的原因_数据_04


第二种:

  如果还不行,再去设置idea server编码。在菜单栏找到”Run->Edit Configration” 找到”server”选项卡 设置 vm option为 -Dfile.encoding=utf-8,如图:

乱码检测java java出现乱码的原因_数据库_05


第三种:

  若乱码问题依然存在,请尝试继续按以下步骤解决:

1.打开IntelliJ IDEA本地安装目录中bin文件夹下的idea.exe.vmoptions和idea64.exe.vmoptions这两个文件。

分别在这两个文件内容的末尾添加-Dfile.encoding=UTF-8,如图:

乱码检测java java出现乱码的原因_ide_06


乱码检测java java出现乱码的原因_数据库_07

以下为比较少见的编码设置

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

设置数据库编码:

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 后端之后,就乱码了,这种乱码一般来说,分为两种:
    (1)参数放在 URL 地址中导致的乱码;
    (2)参数放在请求体中导致的乱码。
  两种乱码原因,对应了两种不同的解决方案。分别来看。

URL 地址中的参数乱码

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

乱码检测java java出现乱码的原因_乱码检测java_08


这样就可以搞定 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>
    <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>
<filter-mapping>
    <filter-name>encoding</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

  当然,上面这段配置并不能代替 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