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;
    }

    }


     

    小蚊子大人
  • 相关阅读:
    使用 ASP.NET Core MVC 创建 Web API(五)
    使用 ASP.NET Core MVC 创建 Web API(四)
    使用 ASP.NET Core MVC 创建 Web API(三)
    使用 ASP.NET Core MVC 创建 Web API(二)
    使用 ASP.NET Core MVC 创建 Web API(一)
    学习ASP.NET Core Razor 编程系列十九——分页
    学习ASP.NET Core Razor 编程系列十八——并发解决方案
    一个屌丝程序猿的人生(九十八)
    一个屌丝程序猿的人生(九十七)
    一个屌丝程序猿的人生(九十五)
  • 原文地址:https://www.cnblogs.com/ywsheng/p/14980268.html
Copyright © 2011-2022 走看看