java Interceptor中 request.getparamter获取不到数据问题

实际业务中需要在request header中获取数据。
然而header可以拿到数据,request.getParameterMap 却变成空的了,导致流程走不下去。
百度查了一下
通过request.getInputStream() 本以为这样问题就解决了,然而并没有紧接着就抛出了 Stream closed
查了一下问题是request.getInputStream() 只可以读一次。
解决方案如下:

首先封装一下HttpServletRequestWrapper

public class ParameterRequestWrapper extends HttpServletRequestWrapper {

    private final String body;

    public ParameterRequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader bufferedReader = null;
        try {
            InputStream inputStream = request.getInputStream();
            if (inputStream != null) {
                bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                char[] charBuffer = new char[128];
                int bytesRead = -1;
                while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
                    stringBuilder.append(charBuffer, 0, bytesRead);
                }
            } else {
                stringBuilder.append("");
            }
        } catch (IOException ex) {
            throw ex;
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException ex) {
                    throw ex;
                }
            }
        }
        body = stringBuilder.toString();
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
        ServletInputStream servletInputStream = new ServletInputStream() {
            @Override
            public boolean isFinished() {
                return false;
            }

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

            @Override
            public void setReadListener(ReadListener readListener) {
            }

            @Override
            public int read() throws IOException {
                return byteArrayInputStream.read();
            }
        };
        return servletInputStream;

    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(this.getInputStream()));
    }

    public String getBody() {
        return this.body;
    }

下面是Interceptor的代码

public class CommonInterceptor implements HandlerInterceptor {


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object obj) throws IOException {
        if (obj instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) obj;
            Method method = handlerMethod.getMethod();
            MacValidate annotation = method.getAnnotation(MacValidate.class);
            if (annotation != null) {
                MacUtil.validateMac(request,annotation.data());
            }
        }
         return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object obj, ModelAndView modelAndView) {
        log.info("view:{},url:{}", modelAndView, request.getRequestURL());
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
        log.info("afterCompletion");
    }
}

工具类 MacUtil

public class MacUtil {

    public static void validateMac(HttpServletRequest request, String[] data) throws ParameterException, IOException {
        // 获取token
        String v = request.getHeader("token");
        log.info(v);
        if (StringUtils.isEmpty(v)) {
             // 抛出异常
        }
        if (!StringUtils.isEmpty(v)) {
            if (!checkData(v, request, data)) {
                // 抛出异常
            }
        }
    }

    private static boolean checkData(String mac, HttpServletRequest request, String[] data) throws IOException {
        String value = getValue(request, data);
        log.info(value);
        // do  Something 
    }

    private static String getValue(HttpServletRequest request, String[] data) throws IOException {
      // 通过封装方法 获取到数据
      // form data 方式
        ParameterRequestWrapper myRequestWrapper = new ParameterRequestWrapper((HttpServletRequest) request);
        String body = myRequestWrapper.getBody();
        Map map = null;
        if (StringUtils.isNotBlank(body)) {
            map = (Map) JSON.parse(body);
        } else {
        //  json
            map = new HashMap();
            Enumeration enu = request.getParameterNames();
           // do Something
    }
}

还有filter

@Slf4j
public class MacFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        ServletRequest requestWrapper = null;
        if (request instanceof HttpServletRequest) {
            requestWrapper = new ParameterRequestWrapper((HttpServletRequest) request);
        }
        // 将request 传递下去
        if (requestWrapper == null) {
            chain.doFilter(request, response);
        } else {
            chain.doFilter(requestWrapper, response);
        }
    }

    @Override
    public void destroy() {

    }
}

最后一步

@Configuration
public class FilterRegister {

    @Bean
    public FilterRegistrationBean macFilter() {
        FilterRegistrationBean macFilter = new FilterRegistrationBean();
        macFilter.setOrder(0);
        macFilter.setFilter(new MacFilter());
        xssFilter().addUrlPatterns("/*");
        xssFilter().setEnabled(true);
        return macFilter;
    }
}

代码贴完了,大体逻辑就是这样的。
还有一种思路就是 通过 request.getInputStream() 获取到的数据再次给"setParameter"回去,有想法的朋友可以尝试一下。

有问题可以留言讨论。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值