过滤器Filter

1、要写过滤器类,写注册过滤器的配置类,要重写HttpServletRequestWapper类,因为读取一次入参后,入参流为空

1、过滤器类(实现Filter接口)

package com.liu.web.Filter;

import com.alibaba.dubbo.common.utils.IOUtils;
import com.alibaba.fastjson.JSON;
import com.liu.web.utils.JsonUtils;
import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;


//urlPatterns设置为/*对所有的路径进行拦截
@WebFilter(filterName = "UrlFilter" ,urlPatterns = "/filterTest/*")
public class UrlFilter implements Filter {
    Logger logger = LoggerFactory.getLogger(UrlFilter.class);
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        logger.info("--------初始化过滤器----------");
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        logger.info("------------执行过滤器--------------");
        HttpServletRequest httpServletRequest = (HttpServletRequest)request;
        //getRequestURI:/test/test.jsp
        //getRequestURL:http://localhost:8080/test/test.jsp
        String uri = httpServletRequest.getRequestURI();
        String cotentType = request.getContentType();
        String method = httpServletRequest.getMethod();
        logger.info("------method"+method);
        logger.info("-------contentType"+cotentType);
        // 类型为application/json用流接收参数
        String decReqString ;
        Map<String,String> paramMap = new HashMap();
        if("application/json".equals(cotentType)) {
            InputStreamReader reader = new InputStreamReader(request.getInputStream());
            String reqStr = IOUtils.read(reader);
            logger.info("--------加密的入参信息:" + reqStr);
            //对加密的字符串进行解密
            Map<String, Object> map = (Map) JsonUtils.convertJson2Object(reqStr, Map.class);
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                String key = entry.getKey();
                if ("name".equals(key)) {
                    String value = (String) entry.getValue();
                    String decString = URLDecoder.decode(value, "utf-8");
                    paramMap.put(key, decString);
                }
            }
            decReqString = JSON.toJSONString(paramMap);
            logger.info("------解密后的入参信息:" + decReqString);
        }else {
            //其他请求类型方式获取参数
            Enumeration<?> enumeration = httpServletRequest.getParameterNames();
            if (enumeration.hasMoreElements()) {
                String name = (String) enumeration.nextElement();
                String value = httpServletRequest.getParameter(name);
                String decString = URLDecoder.decode(value, "utf-8");
                paramMap.put(name, decString);
            }
            decReqString = JSON.toJSONString(paramMap);
            logger.info("------解密后的入参信息:" + decReqString);
        }
        if(!uri.contains("success")){
        //可以直接放行调controller
            chain.doFilter(request,response);
            //不包含这个路径,到请求失败的页面,不可以使用重定向          httpServletRequest.getRequestDispatcher("/filterTest/failed").forward(request,response);
            //重定向是两次请求
            // httpServletResponse.sendRedirect(httpServletRequest.getContextPath()+"/filterTest/failed");
            logger.info("------转向的路径:"+httpServletRequest.getContextPath()+"/filterTest/failed");
        }else{
            //直接放行,进入输入的地址Controller
            //xyHttpServletRequestWrapper为重写的类,必须写重写类,否则getInputStream只读取一次,,Controller入参为空
            // decString为解密后的入参字符串
            XyHttpServletRequestWrapper xyHttpServletRequestWrapper2 = new XyHttpServletRequestWrapper(httpServletRequest,decReqString);
            chain.doFilter(xyHttpServletRequestWrapper2,response);
        }
    }

    @Override
    public void destroy() {
        logger.info("--------摧毁过滤器----------");
    }
}

 2、继承HttpServletRequestWrapper,重写getInputStream方法,防止读取一次入参流之后为空

package com.liu.web.Filter;

import org.apache.catalina.servlet4preview.http.HttpServletRequestWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.*;

public class XyHttpServletRequestWrapper extends HttpServletRequestWrapper {

    private static final Logger logger = LoggerFactory.getLogger(XyHttpServletRequestWrapper.class);

    private String responseBody;
    private HttpServletRequest request;

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

    public XyHttpServletRequestWrapper(HttpServletRequest request, String body) {
       super(request);
       this.request=request;
       responseBody=body;
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        return  new ServletInputStream(){
            private ByteArrayInputStream in = new ByteArrayInputStream(responseBody.getBytes(request.getCharacterEncoding()));
            @Override
            public int read()  {
                return in.read();
            }
            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener listener) {

            }
        };
    }

    public String getResponseBody() {
        return responseBody;
    }
}

3、注册过滤器的配置类,可以在此类设置多个过滤器的顺序

package com.liu.web.Filter;

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FilterRegister {
    @Bean
    public FilterRegistrationBean filterRegistrationBean(){
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        //添加自定义的过滤器1
        filterRegistrationBean.setFilter(new UrlFilter());
        设置为/*对所有的路径进行拦截
        filterRegistrationBean.addUrlPatterns("/filterTest/*");
        //多个拦截器时,设置拦截的顺序
        filterRegistrationBean.setOrder(1);
        return filterRegistrationBean;
    }
//    @Bean
//    public FilterRegistrationBean filterRegistrationBean2(){
//        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
//        //添加自定义的过滤器2
//        filterRegistrationBean.setFilter(new UrlFilter());
//        设置为/*对所有的路径进行拦截
//        filterRegistrationBean.addUrlPatterns("/filterTest/*");
//        //多个拦截器时,设置拦截的顺序
//        filterRegistrationBean.setOrder(2);
//        return filterRegistrationBean;
//    }
}

4、测试类

  • 注意:通过过滤器的地址,需要加@RequestBody实体类和@RequestParam来接受入参
  • 如果是加密后的入参,controller接受的还是加密后的入参
package com.liu.web.Filter;

import com.alibaba.dubbo.common.utils.IOUtils;
import com.liu.beans.OutputObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;


@RestController
@RequestMapping("/filterTest")
public class FilterController {
    Logger logger = LoggerFactory.getLogger(FilterController.class);
    //通过过滤器的地址,类型为application/json用@RequestBody实体类获取,其他类型用@RequestParam接收参数
    @RequestMapping("/success")
    public void success(@RequestParam String userNm, @RequestParam MultipartFile file ){
      try{
//          logger.info("------filename="+filename);
          logger.info("------------file length="+ org.apache.commons.io.IOUtils.toString(file.getInputStream()).length());
          HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
          response.setContentType("image/jpeg;");
          OutputStream out = response.getOutputStream();
          out.write(org.apache.commons.io.IOUtils.toByteArray(file.getInputStream()));
          out.flush();
      }catch (Exception e){

      }
        //加密后的参数,通过过滤器后还是加密的
        OutputObject out = new OutputObject();
        logger.info("------------name="+userNm);
        out.setReturnCode("0000");
        out.setReturnMess("操作成功!!!!");
//        return out;
    }
    @RequestMapping("/failed")
    public OutputObject failed(){
        OutputObject out = new OutputObject();
        out.setReturnCode("9999");
        out.setReturnMess("请求失败!!");
        return out;
    }
}
 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值