彻底搞定乱码-自定义过滤器(filter)-3

彻底解决get/post中文乱码

1.包装模式过滤器

  • spring boot 中使用@Component 或者@Configuration
package com.dancer4code.actuator.filter;

import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Created with IntelliJ IDEA.
 * User: liangqing.zhao(zlq)
 * Date: 2019/10/4 19:45
 * Description:
 */
//@Component
//@WebFilter
//@Configuration
//@Order(value = 15)
public class MyCharacterEncodingFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest,
                         ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException {
        //System.out.println("----------------MyCharacterEncordingFilter------doFilter-----------------");
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        filterChain.doFilter(new MyRequest(request), response);

    }

    /*
     * 1.写一个类实现与被增强对象相同的接口
     * 2.定义一个变量,记住被增强的对象
     * 3.定义一个构造方法,接受被增强对象
     * 4.覆盖想增强的方法
     * 5.对于不想增强的方法,直接调用被增强对象(目标对象)的方法
     */
    class MyRequest extends HttpServletRequestWrapper {
        private HttpServletRequest request;

        public MyRequest(HttpServletRequest request) {
            super(request);
            this.request = request;
        }

        @Override
        public String getParameter(String name) {
            String value = this.request.getParameter(name);
            if (!request.getMethod().equalsIgnoreCase("get")) {
                return value;
            }
            if (value == null) {
                return null;
            }
            try {
                return new String(value.getBytes("UTF-8"),
                        request.getCharacterEncoding());

            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }


    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //System.out.println("---MyCharacterEncordingFilter-----init-------");
    }

    @Override
    public void destroy() {
        //System.out.println("---MyCharacterEncordingFilter-----destroy-------");
    }
}


  • spring boot中使用@WebFilter+@ServletComponentScan(可自定义过滤路径)

  • spring mvc中使用web.xml中配置(可自定义过滤路径)

<filter>
    <filter-name>MyCharacterEncodingFilter</filter-name>
    <filter-class>com.dancer4code.actuator.filter.MyCharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
     <filter-name>MyCharacterEncodingFilter</filter-name>
     <url-pattern>/*</url-pattern>
</filter-mapping>

  • spring mvc中使用@WebFilter注解

2.动态代理

package com.dancer4code.actuator.filter;

import org.springframework.stereotype.Component;

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;

/**
 * Created with IntelliJ IDEA.
 * User: liangqing.zhao(zlq)
 * Date: 2019/10/5 15:15
 * Description:
 */
@Component
public class MyCharacterEncodingProxyFilter implements Filter {


    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        //System.out.println("----------MyCharacterEncodingProxyFilter---doFilter--------------------");
        final HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        //POST的乱码解决方案
        request.setCharacterEncoding("utf-8");

        //返回数据的乱码解决方案
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");

        //用动态代理拦截,增强getParameter()后,放行
        chain.doFilter((ServletRequest) Proxy.newProxyInstance(MyCharacterEncodingProxyFilter.class.getClassLoader(), request.getClass().getInterfaces(),
                new InvocationHandler() { //直接实现接口
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args)
                            throws Throwable {
                        //如果请求方式是POST,则不用增强,直接调用目标对象的方法
                        if (request.getMethod().equalsIgnoreCase("POST")) {
                            return method.invoke(request, args);
                        }
                        String methodName = method.getName();
                        //如果传递进来的方法不是getParameter(),则不用增强
                        if (!methodName.equals("getParameter")) {
                            return method.invoke(request, args);
                        }
                        //为GET,并且是getParameter(),...
                        String value = (String) method.invoke(request, args);
                        if (value != null) {
                            value = new String(value.getBytes("iso8859-1"), "utf-8");
                        }
                        return value;
                    }
                }), response);
    }

    public void destroy() {
        //System.out.println("----------MyCharacterEncodingProxyFilter---destroy--------------------");
    }

    public void init(FilterConfig fConfig) throws ServletException {
        //System.out.println("----------MyCharacterEncodingProxyFilter---init--------------------");
    }
}

其他配置方式与上面相同

引用自
彻底解决全站乱码
Filter使用全站解决中文乱码问题

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容