zoukankan      html  css  js  c++  java
  • springboot项目使用拦截器修改/添加前端传输到后台header和cookie参数

      本质上来讲,request请求当中的参数是无法更改的,也不能添加或者删除。
      但在后台程序中,一般对request的参数的操作,都是通过request的getParameter、getParameterNames、getParameterValues等方法执行的;所以我们要是能重写这些方法,就从侧面改变了request的请求参数。恰好,servlet就提供了一个HttpServletRequestWrapper类来供大家去继承(该类是HttpServletRequest的封装类),重写request相关方法。

    这样可以修改比如shiro框架中的JSESSIONID,使单页H5中调用接口时只需要在头部添加在别处登录之后拿到的jsessionid的值,就能保证是登录状态。

    具体服务端实现如下:

    package webapp.conf;
    
    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()]);
                }
            }
        }
    
    }
  • 相关阅读:
    golang框架对比Revel and Beego
    Gin框架系列02:路由与参数
    用cp命令拷贝文件,源目录后带不带斜杠的区别
    Isilon Gen6的换盘步骤
    如何在同一行里执行多个linux命令?
    KB,MB,GB,TB,PB,EB,ZB,YB,BB
    Isilon的WebUI上指定跨时区时间的小问题
    用Powershell强制同步Windows主机与Internet time server的时间
    Remote Desktop突然不能用了 “This could be due to CredSSP encryption oracle remediation”
    打开KVM Console的一些注意事项
  • 原文地址:https://www.cnblogs.com/007sx/p/10175976.html
Copyright © 2011-2022 走看看