zoukankan      html  css  js  c++  java
  • @ServletComponentScan

     //启动类加上@ServletComponentScan注解

     filter

    package com.box.marketing.service.filter;

    import com.box.common.core.constant.RequestConstant;
    import com.box.common.core.exception.ServiceException;
    import com.box.common.core.utils.GatewayUtils;
    import com.box.marketing.service.wrapper.MultiReadHttpServletRequestWrapper;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.lang.StringUtils;
    import org.springframework.core.annotation.Order;
    import org.springframework.http.HttpMethod;
    import org.springframework.http.MediaType;

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

    /**
    * 初始化MultiReadHttpServletRequestWrapper类,必须在过滤中初始化,不能拦截器修改值无效
    *
    * @author yuan.dingwang
    * @date 2021年03月03日 11:19
    */
    @Slf4j
    @Order(0)
    @WebFilter(urlPatterns = "/*", filterName = "reqWrapperFilter") //启动类加上@ServletComponentScan注解
    public class RequestWrapperFilter 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;
    String safetyVal = request.getHeader(RequestConstant.HEADER_SAFETY_LABEL_NAME);
    if (!StringUtils.equals(RequestConstant.HEADER_SAFETY_LABEL_VAL, safetyVal)) {
    throw new ServiceException(HttpServletResponse.SC_FORBIDDEN, "请通过网关访问资源");
    }

    String contentType = servletRequest.getContentType();
    if (request.getMethod().toUpperCase().equals(HttpMethod.POST.toString()) && (MediaType.APPLICATION_JSON_VALUE.equals(contentType)) ||
    (MediaType.APPLICATION_JSON_UTF8_VALUE.equals(contentType))) {
    MultiReadHttpServletRequestWrapper requestWrapper = new MultiReadHttpServletRequestWrapper((HttpServletRequest) servletRequest);
    filterChain.doFilter(requestWrapper, servletResponse);
    }else{
    filterChain.doFilter(servletRequest, servletResponse);
    }

    //
    }

    @Override
    public void destroy() {

    }

    }

    interceptor

    我们可以知道 Filter 依赖于 Servlet,它主要是针对 URL 地址做一个编码的事情、过滤掉没用的参数、简单的安全校验(比如登录不登录之类),而 Interceptor 依赖于 SpringMVC 框架,它是在 service 或者一个方法调用前,调用一个方法,或者在方法调用后,调用一个方法。下面来具体介绍 Interceptor 的用法和使用场景。

    package com.box.marketing.service.interceptor;

    import com.alibaba.fastjson.JSONObject;
    import com.box.common.core.constant.RequestConstant;
    import com.box.common.core.utils.StringUtils;
    import com.box.marketing.service.wrapper.MultiReadHttpServletRequestWrapper;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.tomcat.util.http.MimeHeaders;
    import org.springframework.http.HttpHeaders;
    import org.springframework.http.HttpMethod;
    import org.springframework.http.MediaType;
    import org.springframework.stereotype.Component;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.method.HandlerMethod;
    import org.springframework.web.multipart.MultipartHttpServletRequest;
    import org.springframework.web.multipart.MultipartResolver;
    import org.springframework.web.multipart.commons.CommonsMultipartResolver;
    import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Objects;

    /**
    * 文件描述
    *
    * @author yuan.dingwang
    * @date 2021年03月02日 18:00
    */
    @Slf4j
    @Component
    public class ContentTypeInterceptor extends HandlerInterceptorAdapter {


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

    String httpMethod = request.getMethod();
    String contentType = request.getHeader(HttpHeaders.CONTENT_TYPE);
    if (httpMethod.equals(HttpMethod.POST.toString()) && MediaType.APPLICATION_JSON_VALUE.equals(contentType)) {
    MultiReadHttpServletRequestWrapper requestWrapper = (MultiReadHttpServletRequestWrapper) request;
    String body = requestWrapper.getBody();

    HandlerMethod handlerMethod = (HandlerMethod) handler;
    Method method = handlerMethod.getMethod();
    RequestBody requestBody = method.getAnnotation(RequestBody.class);

    if (Objects.isNull(requestBody) && StringUtils.isNotBlank(body)) {
    JSONObject obj = JSONObject.parseObject(body);
    Map<String, String[]> param = new HashMap<>(16);
    for (String key : obj.keySet()) {
    String[] put = new String[1];
    put[0] = obj.getString(key);
    param.put(key, put);
    }
    requestWrapper.setParameterMap(param);
    //reflectSetparam(request, "content-type", MediaType.APPLICATION_FORM_URLENCODED_VALUE);
    }
    return super.preHandle(requestWrapper, response, handler);
    }

    return super.preHandle(request, response, handler);
    }


    /**
    * 修改header信息,key-value键值对儿加入到header中
    *
    * @param request
    * @param key
    * @param value
    */
    private void reflectSetparam(HttpServletRequest request, String key, String value) {
    Class<? extends HttpServletRequest> requestClass = request.getClass();
    log.info("request实现类=" + requestClass.getName());
    try {
    Field request1 = requestClass.getDeclaredField("request");
    request1.setAccessible(true);
    Object o = request1.get(request);
    Field coyoteRequest = o.getClass().getDeclaredField("coyoteRequest");
    coyoteRequest.setAccessible(true);
    Object o1 = coyoteRequest.get(o);
    log.info("coyoteRequest实现类=" + o1.getClass().getName());
    Field headers = o1.getClass().getDeclaredField("headers");
    headers.setAccessible(true);
    MimeHeaders o2 = (MimeHeaders) headers.get(o1);
    //o2.removeHeader("content-type");
    o2.addValue(key).setString(value);
    System.out.println(request.getHeader(HttpHeaders.CONTENT_TYPE));
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }

    wrapper 包装类

    package com.box.marketing.service.wrapper;

    import javax.servlet.ReadListener;
    import javax.servlet.ServletInputStream;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletRequestWrapper;
    import java.io.*;
    import java.nio.charset.Charset;
    import java.util.Enumeration;
    import java.util.Map;
    import java.util.Vector;
    /**
    * 重新写请求
    *
    * @author yuan.dingwang
    * @date 2021年03月02日 19:54
    */
    public class MultiReadHttpServletRequestWrapper extends HttpServletRequestWrapper {

    private String tempBody;

    private Map<String, String[]> params; //定义参数集合

    public MultiReadHttpServletRequestWrapper(HttpServletRequest request) {
    super(request);
    tempBody = getBodyString(request);
    params = request.getParameterMap();
    }

    @Override
    public ServletInputStream getInputStream() {
    final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(tempBody.getBytes());
    return new ServletInputStream() {
    @Override
    public boolean isReady() {
    return false;
    }

    @Override
    public int readLine(byte[] b, int off, int len) throws IOException {
    return super.readLine(b, off, len);
    }

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

    @Override
    public void setReadListener(ReadListener readListener) {

    }

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

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

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

    public void setBody(String body) {

    this.tempBody = body;
    }


    private static String getBodyString(HttpServletRequest request) {
    StringBuilder sb = new StringBuilder();
    InputStream inputStream = null;
    BufferedReader reader = null;
    try {
    inputStream = request.getInputStream();
    reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
    String line = "";
    while ((line = reader.readLine()) != null) {
    sb.append(line);
    }
    } catch (IOException e) {
    e.printStackTrace();
    } finally {
    if (inputStream != null) {
    try {
    inputStream.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    if (reader != null) {
    try {
    reader.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
    return sb.toString();
    }


    @Override
    public Enumeration<String> getParameterNames() {
    Vector<String> vector = new Vector<String>(params.keySet());
    return vector.elements();
    }

    /**
    * 获取指定参数名的值,如果有重复的参数名,则返回第一个的值 接收一般变量 ,如text类型
    *
    * @param name 指定参数名
    * @return 指定参数名的值
    */
    @Override
    public String getParameter(String name) {
    String[] results = params.get(name);
    return results[0];
    }


    /**
    * 36 * 获取指定参数名的所有值的数组,如:checkbox的所有数据
    * 37 * 接收数组变量 ,如checkobx类型
    * 38
    */
    @Override
    public String[] getParameterValues(String name) {
    return params.get(name);
    }

    @Override
    public Map<String, String[]> getParameterMap() {
    return params;
    }

    public void setParameterMap(Map<String, String[]> parameterMap) {
    this.params = parameterMap;
    }

    }


     

    小蚊子大人
  • 相关阅读:
    pikachu-xss(1)
    eNSP上配置RIPv2的认证
    eNSP模拟器OSPF单区域配置
    OSPF与ACL综合实验
    利用单臂路由实现vlan间路由
    理解Hybrid接口的应用
    eNSP下配置Trunk接口实现跨交换机传递数据
    eNSP上VLAN的基础的配置及access接口
    eNSP下利用三层交换机实现VLAN间路由
    NFS网络文件系统
  • 原文地址:https://www.cnblogs.com/ywsheng/p/14980268.html
Copyright © 2011-2022 走看看