中文乱码就是值在请求信息或者响应信息中包含的中文字符不能正常显示。产生原因无非就是客户端与服务器采用的编码方式不同导致的。
- request乱码:在发送请求时,浏览器默认将参数按照
utf-8
进行编码。而服务器的解码默认是ISO-8859-1
。在tomcat8之和,对于get方法中请求参数的中文问题已经解决 ,但是post方法的请求参数中文乱码问题却依旧存在。 - response乱码:服务器向浏览器发送的数据默认是采用
ISO-8859-1
编码,浏览器按照默认的字符集进行解码,只要浏览器默认的字符集不是ISO-8859-1
,就会产生乱码。
解放方法也很简单,只要把接收和发送数据采用的字符集设置成utf-8
即可。
下面记录一下模拟登录界面中文乱码的解决方案。
1. 创建一个J2E项目
LoginServlet.java
package com.jxj4869;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
System.out.println(username);
response.getWriter().println("欢迎登录:"+username);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
index.jsp
<%--
Created by IntelliJ IDEA.
User: jiangxiaoju
Date: 2020/2/24
Time: 10:25
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<form method="post" action="${pageContext.request.contextPath}/loginServlet">
<label>username:</label>
<input type="text" name="username">
<br/>
<label>password:</label>
<input type="text" name="password">
<br/>
<button type="submit">确定</button>
</form>
</body>
</html>
起初没有设置编码的时候,输出都是乱码的状态
2.解决request中文乱码
将服务器的解码方式设置为utf-8
。下面这段代码记得要在获取参数前加入才有用
request.setCharacterEncoding("utf-8");
3.解决response中文乱码
解决response中文乱码有两种方法。
设置服务器编码为uft-8
,并告知浏览器服务端发送的数据格式text/html
。下面这段代码要在获取输出流之前添加。
response.setCharacterEncoding("utf-8”);
response.setHeader("contentType", "text/html; charset=utf-8”);
上面的代码也可以简写成。这个方法可以让浏览器按照utf-8
进行解码。服务器按照utf-8
进行编码
response.setContentType("text/html;charset=utf-8”);
修改完的代码如下
LoginServlet.java
package com.jxj4869;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
String username = request.getParameter("username");
System.out.println(username);
response.setContentType("text/html;charset=utf-8");
response.getWriter().println("欢迎登录:"+username);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
这样乱码问题就都解决了。
4.使用过滤器将解决方法封装
如果有很多servlet的话,每次获取数据或者发送数据前都要进行编码的设置,那么就会造成大量重复性的代码。所以我们可以用过滤器预先处理一下编码问题,在发送到servlet中。
CharsetFilter.java
package com.jxj4869;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
// "/*" 是为了无论发送任何请求,都先进行编码处理。
@WebFilter("/*")
public class CharsetFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
chain.doFilter(req, resp);
}
}
完整代码在Github:Github链接 欢迎start