login.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/loginServlet" method="get">
用户名:<input type="text" name="username"><br>
<input type="submit" value="GET提交">
</form>
<hr/>
<form action="${pageContext.request.contextPath}/loginServlet" method="post">
用户名:<input type="text" name="username"><br>
<input type="submit" value="POST提交">
</form>
</body>
</html>
EncodingFilter.java:
package com.filter.demo;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 编码过滤器:处理全局编码
*/
public class EncodingFilter implements Filter {
// 过滤器业务处理方法
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
// 转换成 http 类型
final HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
// 设置编码(只对 POST 请求有效)
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html, charset=utf-8");
/*
* 出现GET中文乱码,是因为在 request.getParameter 方法内部没有进行提交方式判断并处理。
* String name = request.getParameter("userName");
*
* 解决:对指定接口的某一个方法进行功能扩展,可以使用代理!
* 对 request 对象(目标对象),创建代理对象!
*/
HttpServletRequest proxy = (HttpServletRequest) Proxy.newProxyInstance(
request.getClass().getClassLoader(), // 指定当前使用的累加载器
new Class[]{HttpServletRequest.class}, // 对目标对象实现的接口类型
new InvocationHandler() { // 事件处理器
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// 定义方法返回值
Object returnValue = null;
// 获取方法名
String methodName = method.getName();
// 判断:对 getParameter 方法进行 GET 提交中文处理
if ("getParameter".equals(methodName)) {
// 获取请求数据值【 <input type="text" name="userName">】
String value = request.getParameter(args[0].toString()); // 调用目标对象的方法
// 获取提交方式
String methodSubmit = request.getMethod(); // 直接调用目标对象的方法
// 判断如果是GET提交,需要对数据进行处理 (POST提交已经处理过了)
if ("GET".equals(methodSubmit)) {
if (value != null && !"".equals(value.trim())) {
// 处理GET中文
value = new String(value.getBytes("ISO8859-1"), "UTF-8");
}
}
return value;
} else {
// 执行request对象的其他方法
returnValue = method.invoke(request, args);
}
return returnValue;
}
});
// 放行
filterChain.doFilter(request, response);
}
}
LoginServlet.java:
package com.filter.demo;
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(name = "LoginServlet", value = "/loginServlet")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 获取请求参数,如果没有做编码处理,默认情况下中文会出现乱码
// 避免每个 servlet 都做编码处理,可以在过滤器中 处理全局编码;
String username = request.getParameter("username");
System.out.println("username:" + username);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
}
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- 配置过滤器 -->
<filter>
<filter-name>filter</filter-name>
<filter-class>com.filter.demo.EncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>filter</filter-name>
<url-pattern>/loginServlet</url-pattern>
</filter-mapping>
</web-app>