JSP/Servlet中文乱码处理总结

下面的任何一条缺一不可,注意,我之所以全部都用的XXX,意思就是这几个最好全部都一致!

1、HTML中要用meta content="text/html; charset=XXX"来指出HTML页面的编码为XXX,XXX必须和HTML文件本身的编码一致!

2、JSP页面中必须要出现pageEncoding="XXX"用来指出JSP文件本身的编码,这样JSP文件在编译为java文件的时候才不会有乱码(并且JSP文件对应的java文件是UTF-8的编码),然后JSP文件对应的java文件被编译为class文件,仍然是UTF-8编码,最后class文件被web-container(例如tomcat)执行,得到的结果tomcat会给返回到客户端浏览器上,这时就需要contentType="...; charset=XXX"来指定编码;如果是contentType="text/html",也可以用meta来指定charset=XXX,

3、JSP和Servlet中,必须确保在用request取出参数之前调用request.setCharacterEncoding("XXX"),这个如果不希望重复写这个代码,就采取在filter中写上这个代码

4、response.setCharacterEncoding和response.setContentType()暂时不明真相

比如下面有个测试的典型,input.html, input.jsp,这些页面的pageEncoding,charset都事先写在代码里了,一个不缺,并且文件本身的编码与之一致,然后你可以看看打开、关闭filter的效果有什么不同

文件结构如下

/WebContent/WEB-INF/web.xml

/WebContent/9.10.3/input.html

/WebContent/9.10.3/input.jsp

web.xml

<!-- FooServlet2 -->
    <servlet>
        <servlet-name>foo-servlet2</servlet-name>
        <servlet-class>
            org.lxh.servletdemo.FooServlet2
        </servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>foo-servlet2</servlet-name>
        <url-pattern>/FooServlet2</url-pattern>
    </servlet-mapping>
    
    <!-- encoding filter -->
    
    <filter> 
        <filter-name>charset-encoding</filter-name> 
        <filter-class>org.lxh.filterdemo.CharacterEncodingFilter</filter-class> 
        <init-param> 
            <param-name>encoding</param-name> 
            <param-value>UTF-8</param-value> 
        </init-param> 
        <init-param> 
            <param-name>enable</param-name> 
            <param-value>true</param-value> 
        </init-param> 
    </filter>
    <filter-mapping>
        <filter-name>charset-encoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

input.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <form action="../FooServlet2" method="post">
        <!-- 输入中文来测试 -->
        请输入要显示的内容:<input type="text" name="info">
        <input type="submit" value="显示">
    </form>
</body>
</html>

input.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <!--
        注意这里并没有调用request.setCharacterEncoding(),
        你把CharacterEncodingFilter关闭了试试,看看结果有什么
        不一样
    -->
    <%
        String str = (String) request.getAttribute("info") ;
        out.println("<h1>"+str+"</h1>") ;
    %>
</body>
</html>

FooServlet2.java

package org.lxh.servletdemo;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.*;

public class FooServlet2 extends HttpServlet {
    @Override
    public void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        // 在这里也没有调用request.setCharacterEncoding(),
        // 你把CharacterEncodingFilter关闭了试试,看看结果有什么
        // 不一样
        String info = req.getParameter("info");
        if (info != null) {
            info = info + "--- 这是一条小尾巴";
            System.out.println(this + ", " + info);
            req.setAttribute("info", info);
            req.getRequestDispatcher("/9.10.3/input.jsp").forward(req, resp);
        }
    }
    @Override
    public void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        this.doGet(req, resp);
    }
}

CharacterEncodingFilter.java

package org.lxh.filterdemo;

import java.io.IOException;
import java.nio.charset.Charset;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CharacterEncodingFilter implements Filter {
    protected String encoding = null; 
    protected FilterConfig filterConfig = null; 
    protected boolean enable = false; 
    public void destroy() { 
        this.encoding = null; 
        this.filterConfig = null; 
    } 
    public void doFilter(ServletRequest request, ServletResponse response, 
                           FilterChain chain) throws IOException, ServletException { 
        if (this.enable) {
            String encoding = this.selectEncoding(request); 
            if (encoding != null && !encoding.equals("")) { 
                System.out.println(this + ": " + encoding);
                request.setCharacterEncoding(encoding); //Overrides the name of the character encoding used in the body of this request. This method must be called prior to reading request parameters or reading input using getReader().
                // response.setCharacterEncoding(encoding); // 暂时不太清楚
            }
        }
        // Pass control on to the next filter 
        chain.doFilter(request, response); 
     } 
     public void init(FilterConfig filterConfig) throws ServletException { 
         this.filterConfig = filterConfig; 
         this.encoding = filterConfig.getInitParameter("encoding");
         if (!Charset.isSupported(encoding)) {
            encoding = null;
         }
         String enableString = filterConfig.getInitParameter("enable");
         if (enableString.equalsIgnoreCase("true")) {
            this.enable = true;
         } else {
            this.enable = false;
         }
      } 
      protected String selectEncoding(ServletRequest request) { 
          return (this.encoding); 
      } 
}
原文地址:https://www.cnblogs.com/qrlozte/p/3178761.html