【问题标题】:Modify ServletRequest using Filter in a Spring boot application在 Spring Boot 应用程序中使用 Filter 修改 ServletRequest
【发布时间】:2019-12-04 19:37:05
【问题描述】:

这方面有一些文章,但他们的解决方案并没有解决我的问题。 我有一个看起来像这样的 GET 请求: localhost:8080/rest/users/search?name=john&age=20&count=20

我的要求是每当请求包含“count”查询参数时,我要检查该值是否不超过10。如果超过10,则将查询参数替换为“count=10”

为了解决这个问题,我尝试使用 javax.servlet.Filterjavax.servlet.http.HttpServletRequestWrapper 但我无法替换请求中的原始值。

这就是我的 WebFilter 的样子:

@Component
public class WebFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) {
        logger.debug("Initiating WebFilter >> ");
    }

    @Override
    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
            throws IOException, ServletException {

            final HttpServletRequestWrapper requestWrapper = new HttpServletRequestWrapper((HttpServletRequest) request);
            if (requestWrapper.getParameterValues("count") != null) {
                String[] count = requestWrapper.getParameterValues("price");

                for (int i = 0; i < count.length; i++) {
                    if (Integer.parseInt(count[i]) > 10) {
                        count[i] = "10";
                    }
                }
                requestWrapper.setAttribute("count", count);
            }

            System.out.println("count: " + requestWrapper.getParameter("count"));

            // Goes to default servlet
            chain.doFilter(requestWrapper, response);
    }

    @Override
    public void destroy() {
        logger.debug("Destroying WebFilter >> ");
    }
}

我在其他帖子中看到,只需执行requestWrapper.setAttribute("count", count); 即可将新值添加到 responseWrapper。但我总是得到原始值。

【问题讨论】:

  • 1) 你不需要包装器,因为你没有扩展它——因此它毫无意义。 2)链中的不同过滤器可能正在修改它 3)您的过滤器可能在链中的错误位置(与 2 相关)
  • 4) 设置属性不会修改查询参数——它只是将给定属性添加到一个映射中,其他组件可以从同一个请求对象中读取——它是一种数据交换映射。跨度>

标签: java spring-boot servlet-filters


【解决方案1】:

您无法设置查询参数 - 从 API 的角度来看,它是不可变的。您需要做的是扩展请求包装器并覆盖 getParameter() 方法以返回您希望在提供给定查询名称时返回的值。所以像这样(记事本中的膝盖编程)

class YourWrapper{
  ...ctors etc
   @Override
   public String[] getParamter(String name){
         if(name.equals("count"){
             String[] original super.getParameter(name); // get original values, process it and 
             return ...// either original val or String.valueOf(10);
          }
         return super.getParameter(name);
    }

}

比你包装你的请求并沿着过滤器链传递

chain.doFilter(new YourWrapper(request),response);

所以一切都是为了拦截。

【讨论】:

    猜你喜欢
    • 2019-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-30
    • 2020-01-19
    • 2023-03-16
    • 2020-08-30
    • 2021-10-24
    相关资源
    最近更新 更多