zoukankan      html  css  js  c++  java
  • java 修改HttpServletRequest的参数或请求头

    场景:过滤器中获取参数Token并添加到请求头(用户认证兼容老系统)
    请求头和请求参数是不能直接修改,也没有提供修改的方法,但是可以在过滤器和拦截器中使用HttpServletRequestWrapper包装类达到修改的目的。

    一、实现HttpServletRequestWrapper接口,下面直接使用匿名类
    package com.xxxx.web.filter;
    
    import org.apache.commons.lang3.StringUtils;
    import javax.servlet.*;
    import javax.servlet.annotation.WebFilter;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletRequestWrapper;
    import java.io.IOException;
    import java.util.Enumeration;
    
    @WebFilter
    public class AuthHeaderSettingFilter implements Filter{
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            HttpServletRequestWrapper requestWrapper = new HttpServletRequestWrapper((HttpServletRequest) request) {
                /**
                 * 当调用request.getHeader("token")时,则获取请求参数中token值并当做Header的值返回
                 * @param name
                 * @return
                 */
                @Override
                public String getHeader(String name) {
                    // 先从原本的Request中获取头,如果为空且名字为token,则从参数中查找并返回
                    String superHeader = super.getHeader(name);
                    if("token".equals(name) && StringUtils.isEmpty(superHeader)){
                        String token = request.getParameter("token");
                        if (StringUtils.isNotEmpty(token)) {
                            return token ;
                        }
                    }
                    return superHeader;
                }
            };
            chain.doFilter(requestWrapper,response);
        }
    
        @Override
        public void destroy() {
        }
    }
    
    二、HttpServletRequestWrapperServletRequestWrapperHttpServletRequest接口中的很多方法都可以重写
    1. 要想增加一个请求参数可以在HttpServletRequestWrapper中重写getParameter(String name)
        @Override
        public String getParameter(String name) {
            if("newParam".equals(name)){
                return "这是我新增加的参数";
            }
            return super.getParameter(name);
        }
        @Override
        public Map<String, String[]> getParameterMap() {
            HashMap<String, String[]> newMap = new HashMap<>();
            newMap.putAll(super.getParameterMap());
            newMap.put("newParam",new String[]{"这是我新增加的参数"}) ;
            return Collections.unmodifiableMap(newMap);
        }
        @Override
        public String[] getParameterValues(String name) {
            if("newParam".equals(name)){
                return new String[]{"这是我新增加的参数"};
            }
            return super.getParameterValues(name);
        }
    

    注意: getParameterMap()返回的时一个不可修改的map ,不能直接向里面put值, 所以在重写这个方法时要自己new 一个HashMap ,然后在新建的map中放值,最后返回时必须调用Collections.unmodifiableMap(Map<? extends K, ? extends V> m) 把map改成不可变的

    1. 结构


       
      image.png
     
    image.png
    参考:


    作者:else05
    链接:https://www.jianshu.com/p/a8c9d45775ea
    来源:简书
    简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

    背景

    由于环境升级,需要重新设置header中的 一个值,暂设定为 org . http 请求时加入在header中加入org,但在filter中,会通过验证,生成新的org,需要覆盖原来header中的org.

    修改 filter 。代码是在网上找的一部分,根据自己的需要进行调整了。

    @Component
    @Slf4j
    @WebFilter(urlPatterns = { "/" }, filterName = "authorFilter")
    public class DemoFilter implements Filter {
        @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
                                       FilterChain filterChain) throws IOException, ServletException {
            HttpServletRequest req = (HttpServletRequest) servletRequest;
            req.setAttribute("hdd","tttt");
            HeaderMapRequestWrapper requestWrapper = new HeaderMapRequestWrapper(req);
            requestWrapper.addHeader("realm","test");
            log.info("header-->{}",getHeadKeyAndValue(req));
            filterChain.doFilter(requestWrapper, servletResponse);
    
        }
    
        private Map<String, String> getHeadKeyAndValue(HttpServletRequest httpRequest) {
            Map<String, String> header = new HashMap<>();
            Enumeration<String> headerNames = httpRequest.getHeaderNames();
            while (headerNames.hasMoreElements()) {
                String nextElement = headerNames.nextElement();
                header.put(nextElement, httpRequest.getHeader(nextElement));
            }
            return header;
        }
    }
    
    @Slf4j
    public class HeaderMapRequestWrapper extends HttpServletRequestWrapper {
        /**
         * construct a wrapper for this request
         *
         * @param request
         */
        public HeaderMapRequestWrapper(HttpServletRequest request) {
            super(request);
        }
    
        private Map<String, String> headerMap = new HashMap<>();
    
        /**
         * add a header with given name and value
         *
         * @param name
         * @param value
         */
        public void addHeader(String name, String value) {
            headerMap.put(name, value);
        }
    
        @Override
        public String getHeader(String name) {
            log.info("getHeader --->{}",name);
            String headerValue = super.getHeader(name);
            if (headerMap.containsKey(name)) {
                headerValue = headerMap.get(name);
            }
            return headerValue;
        }
    
        /**
         * get the Header names
         */
        @Override
        public Enumeration<String> getHeaderNames() {
            List<String> names = Collections.list(super.getHeaderNames());
            for (String name : headerMap.keySet()) {
                names.add(name);
            }
            return Collections.enumeration(names);
        }
    
        @Override
        public Enumeration<String> getHeaders(String name) {
            log.info("getHeaders --->>>>>>{}",name);
            List<String> values = Collections.list(super.getHeaders(name));
            log.info("getHeaders --->>>>>>{}",values);
            if (headerMap.containsKey(name)) {
                log.info("getHeaders --->{}",headerMap.get(name));
                values = Arrays.asList(headerMap.get(name));
            }
            return Collections.enumeration(values);
        }
    }
    
    

    经过测试,在header解析时,是通过getHeaders方法,这个地方原来的时候是通过,values直接添加新的header,组成了一个 header的数组,而不是覆盖。

    https://www.liangzl.com/get-article-detail-35965.html

    HttpServletRequest修改/添加header和cookie参数

    实现功能:

    所有接口经过过滤器,获取每个接口的自定义头部(token)

    判断如果是app访问,则给头部设置cookie,值为自定义token的值。

    即:使用过滤器实现修改请求头headers

    实现步骤:

    1.自定义过滤器 ModifyParametersFilter.java 并继承 OncePerRequestFilter

    复制代码
    package com.mobile.web.common;
    
    import org.springframework.web.filter.OncePerRequestFilter;
    
    import javax.servlet.FilterChain;
    import javax.servlet.ServletException;
    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.util.*;
    
    /**
     * 自定义的过滤器,
     * Created by Administrator on 2017/6/19 0019.
     */
    public class ModifyParametersFilter extends OncePerRequestFilter {
        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
                throws ServletException, IOException {
            // 修改cookie
            ModifyHttpServletRequestWrapper mParametersWrapper = new ModifyHttpServletRequestWrapper(request);
            String token = request.getHeader("token");
            if (token != null && !"".equals(token)) {
                mParametersWrapper.putCookie("JSESSIONID", token);
            }
            // finish
            filterChain.doFilter(mParametersWrapper, response);
        }
    
        /**
         * 修改cookie信息
         */
        private class ModifyHttpServletRequestWrapper extends HttpServletRequestWrapper {
            private Map<String, String> mapCookies;
            ModifyHttpServletRequestWrapper(HttpServletRequest request) {
                super(request);
                this.mapCookies = new HashMap<>();
            }
            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()]);
                }
            }
        }
    }
    复制代码

    2.在web.xml中注册该过滤器:

    复制代码
        <filter>
            <filter-name>ModifyParametersFilter</filter-name>
            <filter-class>com.xiyinli.web.common.ModifyParametersFilter</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>ModifyParametersFilter</filter-name>
            <url-pattern>/*</url-pattern>
            <!-- 直接从客户端过来的请求以及通过forward过来的请求都要经过该过滤器 -->
            <dispatcher>REQUEST</dispatcher>
            <dispatcher>FORWARD</dispatcher>
        </filter-mapping>
    复制代码

    如:

    参考文章:

    继承HttpServletRequestWrapper以实现在Filter中修改HttpServletRequest的参数

    https://www.cnblogs.com/007sx/p/7049514.html

  • 相关阅读:
    为什么测试人员需要了解代码逻辑、表结构
    http报文常见的请求头、响应头
    测试人如何做出一份好简历
    如何制定测试计划
    写SQL的套路
    我是如何理解对公信贷业务
    db2----实操篇
    Oracle----高级操作
    常见web中间件漏洞(二)Apache漏洞
    常见web中间件漏洞(一)IIS漏洞
  • 原文地址:https://www.cnblogs.com/softidea/p/10838237.html
Copyright © 2011-2022 走看看