过滤器+动态代理过滤请求数据

过滤器

用来过滤请求数据和响应数据的技术

创建方式

首先实现Filter接口:

@WebFilter("/*")
public class EncodingFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        //设置字符编码格式,设置过滤请求数据和响应数据的字符编码集
        servletRequest.setCharacterEncoding("UTF8");
        servletResponse.setContentType("text/html;charset=UTF-8");
        servletResponse.setCharacterEncoding("UTF-8");
        //过滤完成,放行
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {

    }
}

注册方式(即项目如何使用)

选择其中一种即可,执行顺序是:
1、先执行配置方式在执行注解的方式
2、配置方式里面,按照在web.xml里面的顺序执行
3、注解方式里面按照类名的字母顺序执行a>b>…>z

配置文件的方式(web.xml)

注意:必须在servlet之前

<!--  注册过滤器-->
  <filter>
    <filter-name>filter1</filter-name>
    <filter-class>com.cqust.filter.EncodingFilter</filter-class>
  </filter>
<!--  给过滤器添加映射-->
  <filter-mapping>
    <filter-name>filter1</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
<!--  注册servlet-->
  <servlet>
    <servlet-name>userServlet</servlet-name>
    <servlet-class>com.cqust.controller.LoginServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>userServlet</servlet-name>
    <url-pattern>/login</url-pattern>
  </servlet-mapping>

注解的方式

在需要的类上添加
@webServlet("/*")//注解方式配置servlet
@webFilter("/*")//注解方式配置过滤器
*:表示匹配任意个任意字符,只能在最前或者最后
如:/*:匹配任意url
/*.do:匹配所有的xxx.do

代理模式

代理模式就是,通过第三方的类代理目标类,就是在执行目标类的方法之前或者之后执行我们需要添加的方法
注意:代理类和目标需要实现同一个接口类

静态代理

由程序员自己写一个代理类对目标类进行扩展
首先需要定义一个接口和目标类:

/**
* 接口类
*/
public interface Car {
    /**
     * 卖某种车辆
     * @param carName 车辆名称
     */
     void  saleCar(String carName);
}
/**
* 目标类,汽车制造厂
 * @author wwq
 * @date 2021/5/11-15:44
 */
public class CarFactory implements Car {
    @Override
    public void saleCar(String carName) {
        System.out.println("创造汽车:"+carName);
    }
}

程序员自己编写代理类

/**
* 代理类 在执行买车服务之前、之后添加了一下方法
 * @author wwq
 * @date 2021/5/11-15:46
 */
public class Car4s implements Car {
    private Car proxyimp;

    public Car4s(Car carFactory) {
        this.proxyimp = carFactory;
    }
    @Override
    public void saleCar(String carName) {
        System.out.println("预约客户");
        proxyimp.saleCar(carName);
        System.out.println("车类进行保养");
    }
}

调用代理的对象实现测试:

//静态代理
        Car carFactory = new CarFactory();
        Car carS = new Car4s(carFactory);
        carS.saleCar("劳斯莱斯·幻影");

动态代理

首先接口类和目标类都是上面的方法

/*
参数1:目标类的加载器,推测用来加载该类
参数2,目标类的实现的接口数组,推测用来实现父接口
参数3,执行处理,需要程序员实现InvocationHandler,实现方法invoke
*/
Car o = (Car) Proxy.newProxyInstance(CarFactory.class.getClassLoader(), CarFactory.class.getInterfaces(), new MyInvokHandler(CarFactory.class));

自定义执行处理器,添加扩展方法

/**
 * 自定义执行处理器
 * @author wwq
 * @date 2021/5/11-16:41
 */
public class MyInvokHandler implements InvocationHandler {
    private Class aClass;

    public MyInvokHandler(Class aClass) {
        this.aClass = aClass;
    }

    /**
     *
     * @param proxy 代理对象(程序自动创建的)
     * @param method 需要执行的每一个方法
     * @param args 参数
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("方法前的扩展");
        //目标对象
        Object o = aClass.newInstance();
        method.invoke(o,args);
        System.out.println("方法后的扩展");
        return null;
    }
}

过滤器+动态代理

自定义过滤器,过滤所有请求

/**
 * 过滤器,过滤请求数据中含有sb的参数,将其替换成***
 * @author wwq
 * @date 2021/5/11-17:48
 */
@WebFilter("/*")
public class ProxyRegister implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //动态代理处理注册的用户名,过滤掉sb
        ServletRequest req = (ServletRequest) Proxy.newProxyInstance(servletRequest.getClass().getClassLoader(), servletRequest.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //执行方法的名称
                String name = method.getName();
                if ("getParameterMap".equals(name)){
                    //获取所有的参数
                    Map<String,String[]> map = (Map) method.invoke(servletRequest, args);
                    //原生的map无法进行修改,需要复制一个新map
                    HashMap<String,String[]> new_map = new HashMap<>(map);
                    //获取所有参数的Key,通过key修改对应的value,如果直接values 无法修改map里面的值
                    Set<String> key = new_map.keySet();
                    for (String k : key) {
                        //获取参数对应的值,(如:checkbox对应多个值)
                        String[] values = new_map.get(k);
                        //遍历每一个值进行判断是否包含sb,有就进行替换
                        for (int i = 0; i < values.length; i++) {
                            if (values[i].contains("sb")){
                                values[i] = values[i].replace("sb","***");
                            }
                        }
                    }
                    return new_map;
                }
                return method.invoke(servletRequest,args);
            }
        });
        System.out.println("register");
        filterChain.doFilter(req,servletResponse);
    }

    @Override
    public void destroy() {

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值