java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Springboot通过filter修改Header的值

Springboot如何通过filter修改Header的值

作者:小石潭记丶

这篇文章主要介绍了Springboot如何通过filter修改Header的值问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

Springboot通过filter修改Header的值

import org.apache.tomcat.util.http.MimeHeaders;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.*;
/**
 * 拦截器配置
 */
@Configuration
public class FilterConfig {
    @Bean
    public FilterRegistrationBean modifyParametersFilter() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new ModifyParametersFilter());
        registration.addUrlPatterns("/*");              // 拦截路径
        registration.setName("modifyParametersFilter"); // 拦截器名称
        registration.setOrder(1);                       // 顺序
        return registration;
    }
    /**
     * 自定义拦截器
     */
    class ModifyParametersFilter extends OncePerRequestFilter {
        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
            // 修改请求头
            Map<String, String> map = new HashMap<>();
            modifyHeaders(map, request);
            // 修改cookie
            ModifyHttpServletRequestWrapper requestWrapper = new ModifyHttpServletRequestWrapper(request);
            String token = request.getHeader("token");
            if (token != null && !"".equals(token)) {
                requestWrapper.putCookie("SHIROSESSIONID", token);
            }
            // finish
            filterChain.doFilter(requestWrapper, response);
        }
    }
    /**
     * 修改请求头信息
     * @param headerses
     * @param request
     */
  private void modifyHeaders(Map<String, String> headerses, HttpServletRequest request {
        if (headerses == null || headerses.isEmpty()) {
            return;
        }
        Class<? extends HttpServletRequest> requestClass = request.getClass();
        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);
            Field headers = o1.getClass().getDeclaredField("headers");
            headers.setAccessible(true);
            MimeHeaders o2 = (MimeHeaders)headers.get(o1);
            for (Map.Entry<String, String> entry : headerses.entrySet()) {
                o2.removeHeader(entry.getKey());
                o2.addValue(entry.getKey()).setString(entry.getValue());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 修改cookie信息
     */
    class ModifyHttpServletRequestWrapper extends HttpServletRequestWrapper {
        private Map<String, String> mapCookies;
        ModifyHttpServletRequestWrapper(HttpServletRequest request) {
            super(request);
            this.mapCookies = new HashMap<>();
        }
        public void putCookie(String name, String value) {
            this.mapCookies.put(name, value);
        }
        public Cookie[] getCookies() {
            HttpServletRequest request = (HttpServletRequest) getRequest();
            Cookie[] cookies = request.getCookies();
            if (mapCookies == null || mapCookies.isEmpty()) {
                return cookies;
            }
            if (cookies == null || cookies.length == 0) {
                List<Cookie> cookieList = new LinkedList<>();
                for (Map.Entry<String, String> entry : mapCookies.entrySet()) {
                    String key = entry.getKey();
                    if (key != null && !"".equals(key)) {
                        cookieList.add(new Cookie(key, entry.getValue()));
                    }
                }
                if (cookieList.isEmpty()) {
                    return cookies;
                }
                return cookieList.toArray(new Cookie[cookieList.size()]);
            } else {
                List<Cookie> cookieList = new ArrayList<>(Arrays.asList(cookies));
                for (Map.Entry<String, String> entry : mapCookies.entrySet()) {
                    String key = entry.getKey();
                    if (key != null && !"".equals(key)) {
                        for (int i = 0; i < cookieList.size(); i++) {
                            if(cookieList.get(i).getName().equals(key)){
                                cookieList.remove(i);
                            }
                        }
                        cookieList.add(new Cookie(key, entry.getValue()));
                    }
                }
                return cookieList.toArray(new Cookie[cookieList.size()]);
            }

Springboot获取请求头header里面的信息

项目中后端服务经常需要前端传的请求头里的信息,给大家分享一下:

1、循环获取

/**
     * 获取判断请求头的参数
     * @return
     */
    public static boolean checkHeaderName(){
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        if(Objects.isNull(ra)){
            log.info("服务里RequestAttributes对象为空");
            return false;
        }
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        HttpServletRequest request = sra.getRequest();
        Enumeration<String> enumeration = request.getHeaderNames();
        while (enumeration.hasMoreElements()) {
            String name = enumeration.nextElement();
            String value = request.getHeader(name);
            if(name.equals("accept-"+HeaderEnum.language.name()) && value.equals(HeaderEnum.language.head())){
                return true;
            }
            /**
             * 或者其他的业务处理
             */
        }
        return false;
    }

2、根据具体的key获取

/**
     *获取 判断请求头的参数
     * @return
     */
    public static boolean checkHeader(){
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        if(Objects.isNull(ra)){
            log.info("服务里RequestAttributes对象为空");
            return false;
        }
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        HttpServletRequest request = sra.getRequest();
        String head = request.getHeader("accept-"+HeaderEnum.language.name());
        if(head.equals(HeaderEnum.language.head())){
            return true;
        }
        /**
         * 或者其他的业务处理
         */
        return false;
    }

3、修改请求头信息

只能依靠反射原原理(HttpServletRequest中定义的对Header的操作全是只读,没有修改)。

假设的场景是,需要对请求Header统一添加一个x-request-id,通过这个ID来从日志中定位每一个请求。

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.UUID;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.RequestFacade;
import org.apache.tomcat.util.http.MimeHeaders;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;
@WebFilter(urlPatterns = "/*")
@Component
@Order(-999)
public class RequestIdGenFilter extends HttpFilter {
    /**
     * 
     */
    private static final long serialVersionUID = 1787347739651657706L;
    @Override
    protected void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
        try {
            // 从 RequestFacade 中获取 org.apache.catalina.connector.Request
            Field connectorField = ReflectionUtils.findField(RequestFacade.class, "request", Request.class);
            connectorField.setAccessible(true);
            Request connectorRequest = (Request) connectorField.get(req);
            // 从 org.apache.catalina.connector.Request 中获取 org.apache.coyote.Request
            Field coyoteField = ReflectionUtils.findField(Request.class, "coyoteRequest", org.apache.coyote.Request.class);
            coyoteField.setAccessible(true);
            org.apache.coyote.Request coyoteRequest = (org.apache.coyote.Request) coyoteField.get(connectorRequest);
            // 从 org.apache.coyote.Request 中获取 MimeHeaders
            Field mimeHeadersField =  ReflectionUtils.findField(org.apache.coyote.Request.class, "headers", MimeHeaders.class);
            mimeHeadersField.setAccessible(true);
            MimeHeaders mimeHeaders =  (MimeHeaders) mimeHeadersField.get(coyoteRequest);
            this.mineHeadersHandle(mimeHeaders);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        super.doFilter(req, res, chain);
    }
    protected void mineHeadersHandle (MimeHeaders mimeHeaders) {
        // 添加一个Header,随机生成请求ID
        mimeHeaders.addValue("x-request-id").setString(UUID.randomUUID().toString());;
        // 移除一个header
        mimeHeaders.removeHeader("User-Agent");
    }
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文