Filter向Request添加参数

Filter向Request中添加参数

1. 情景

系统基于SSM+SpringBoot+JWT。

Token中通常会带有用户的信息,需要在后端解析出来作为Controller层的参数,这时就要通过Filter来处理HttpServletRequest了。因为HttpServletRequest是不可改变的,所以要通过HttpServletRequestWrapper 进行包装。采用到了设计模式中的装饰者模式。

2. 代码


import com.dubbo.config.ParameterRequestWrapper;
import com.dubbo.tools.TokenUtils;
import com.dubbo.wrap.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

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

/**
 * @author gyh
 * @csdn https://blog.csdn.net/qq_40788718
 * @date 2020/4/30 21:39
 */

@WebFilter
@Order(1)
@Component
public class
RequestParameterFilter implements Filter {

    @Autowired
    @Qualifier(value = "pathSet")
    private Set<String> pathSet ;

    @Override
    public void init(FilterConfig filterConfig) {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest ;
        HttpServletResponse response = (HttpServletResponse) servletResponse ;
        //跨域
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
        ParameterRequestWrapper wrapper = new ParameterRequestWrapper(request) ;
        //加入IP参数
        wrapper.addParameter("loginIP" , request.getRemoteAddr());
        //System.out.println(request.getRemoteAddr());
        //包含URL,验证token,成功则加入userId,失败则重定向到登录页
        if (pathSet.contains(request.getServletPath())){
            String token = request.getParameter("token") ;
            User user = null ;
            if (token == null || token == "" ||
                    (user =TokenUtils.isToken(token , request.getRemoteAddr())) == null){
                //System.out.println(JacksonUtils.bean2Json(user));
                //重定向到登录页
//                response.sendRedirect() ;
            }else{
                //加入UserId参数
                wrapper.addParameter("userId" , user.getUserId());
            }
        }
        filterChain.doFilter(wrapper , servletResponse);
    }

    @Override
    public void destroy() {

    }
}

需要从token里面获取用户的Id,并且插入到request的参数集合里。


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;

/**
 * @author gyh
 * @csdn https://blog.csdn.net/qq_40788718
 * @date 2020/4/30 18:40
 */

public class ParameterRequestWrapper extends HttpServletRequestWrapper {

    private Map<String , String[]> params = new HashMap<>() ;


    public ParameterRequestWrapper(HttpServletRequest request) {
        super(request);
        //将参数表,赋予给当前Map以便于持有request中的参数
        this.params.putAll(request.getParameterMap());
    }

    public ParameterRequestWrapper(HttpServletRequest request , Map<String , Object> extendParams){
        this(request);
        addAllParameters(extendParams) ;
    }

    /**
     * 重写getParameter方法
     * @param name 参数名
     * @return 参数数值
     */
    @Override
    public String getParameter(String name) {
        String[] values = params.get(name) ;
        if (values == null){
            return null ;
        }
        return values[0] ;
    }

    @Override
    public String[] getParameterValues(String name){
        String[] values = params.get(name) ;
        if (values == null || values.length == 0){
            return null ;
        }
        return values ;
    }

    /**
     * 在获取所有的参数名,必须重写此方法,
     * 否则对象中参数值映射不上
     * @return
     */
    @Override
    public Enumeration<String> getParameterNames(){
        return new Vector(params.keySet()).elements() ;
    }

    public void addAllParameters(Map<String, Object> extendParams) {
        for (Map.Entry<String , Object> entry : extendParams.entrySet())
            addParameter(entry.getKey() , entry.getValue()) ;
    }

    public void addParameter(String key, Object value) {
        if (value != null){
            if (value instanceof String[])
                params.put(key , (String[])value) ;
            else if (value instanceof String)
                params.put(key , new String[]{(String) value}) ;
            else
                params.put(key , new String[]{String.valueOf(value)}) ;
        }
    }

}

3. HttpServletRequestWrapper

通过类名就可以知道此类是HttpServletRequest 的包装类,通过 this.params.putAll(request.getParameterMap()); 将原request中的参数数据转移到当前request(因为我们只添加参数)。

HttpServletRequestWrapperHttpServletResponseWrapper 的作用:

强化和修改requestresponse

4.参考:

https://blog.csdn.net/tyyytcj/article/details/78528499

https://www.cnblogs.com/xuhewei/p/11474389.html

https://www.cnblogs.com/afangfang/p/12812276.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在 Spring Cloud Gateway 中添加 RequestBody 参数,你需要使用 Spring Cloud Gateway 的自定义过滤器来处理请求和响应。下面是一个简单的示例: ```java @Component public class RequestBodyFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { ServerHttpRequest request = exchange.getRequest(); MediaType contentType = request.getHeaders().getContentType(); if (contentType != null && contentType.equals(MediaType.APPLICATION_JSON)) { return DataBufferUtils.join(exchange.getRequest().getBody()) .flatMap(dataBuffer -> { byte[] bytes = new byte[dataBuffer.readableByteCount()]; dataBuffer.read(bytes); DataBufferUtils.release(dataBuffer); String bodyString = new String(bytes, Charset.forName("UTF-8")); if (StringUtils.isNotBlank(bodyString)) { exchange.getAttributes().put("cachedRequestBodyObject", bodyString); } return chain.filter(exchange); }); } else { return chain.filter(exchange); } } @Override public int getOrder() { return -1; } } ``` 此过滤器将检查请求的内容类型是否为 JSON,并将请求体转换为字符串形式,然后将其存储在 Exchange 属性中,以便在后续处理中使用。 你可以在 RouteLocator 中添加此过滤器: ```java @Bean public RouteLocator customRouteLocator(RouteLocatorBuilder builder) { return builder.routes() .route("test", r -> r.path("/test") .filters(f -> f.filter(new RequestBodyFilter())) .uri("http://localhost:8080")) .build(); } ``` 以上代码将在访问 /test 路径时,应用 RequestBodyFilter 过滤器。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值