servlet过滤器中的静态资源版本控制(添加一个额外的GET参数)

Static resources versioning in servlet filter (adding an extra GET parameter)

本文关键字:一个 参数 GET 添加 过滤器 静态 资源 servlet 版本控制      更新时间:2023-09-26

im正在尝试实现filter,它将以某种方式将JS url从/script/script1.js修改为/scripts/script1.js?version=1.3.2

我试过:

  1. 使用response.sendRedirect("/scripts/script1.js?version=1.3.2"),我得到浏览器控制台日志中的ERR_TOO_MANY_REDIRECTS

  2. 使用了RequestWrapper,其中我在parameterMap中添加了值为"1.3.2"的参数"version",但它需要以某种方式添加到queryParameters映射中是否可以在过滤器中添加queryParameters

或者有什么解决方案可以在javafilter中进行版本控制?

PS:是的,我知道这不是最好的解决方案,我不会使用URLrewriteFilter

是的,我会想到过滤器:

1.实现一个过滤器,将原始请求封装到一个请求包装器中,该包装器将新参数添加到现有参数中:

@WebFilter("/scripts/*")
public class MyFilter implements Filter
{
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException,
        ServletException
    {
        String version=request.getParameter("version");
        if (version == null)
        {
            Map<String, String[]> myParameters=new HashMap<>(request.getParameterMap());
            request=new MyHttpServletRequest((HttpServletRequest)request, myParameters);
        }
        chain.doFilter(request, response);
    }
    // ... rest of Filter boilerplate...
}

2.请求包装器:

public class MyHttpServletRequest extends HttpServletRequestWrapper
{
    private final Map<String, String[]> parameters;
    public MyHttpServletRequest(HttpServletRequest request, Map<String, String[]> parameters)
    {
        super(request);
        this.parameters=parameters;
    }
    @Override
    public String getParameter(String name)
    {
        String[] values=parameters.get(name);
        return values!=null && values.length > 0
            ? values[0]
            : null;
    }
    @Override
    public Map<String, String[]> getParameterMap()
    {
        return parameters;
    }
}

更新

如果需要重写getQueryString方法,可以这样做:

    @Override
    public String getQueryString()
    {
        String s;
        try
        {
            s=super.getQueryString();
            if (s == null)
            {
                s="?";
            }
            for (Map.Entry<String, String[]> param : getParameterMap().entrySet())
            {
                s+="&";
                for (String value : param.getValue())
                {
                    s+=URLEncoder.encode(param.getKey(), "UTF-8") + "=" + URLEncoder.encode(value, "UTF-8");
                }
            }
        }
        catch (UnsupportedEncodingException e)
        {
            throw new java.lang.RuntimeException("Exception without treatment", e);
        }
        return s;
    }
}

另一个选项是转发来自过滤器的请求:

RequestDisptacher disp = request.getRequestDisptacher("/scripts/script1.js?version=1.3.2");
disp.forward(request,response);

如果你这样做,你就不会调用filter.doChain(请求,响应).

对于转发的请求,"版本"将作为查询参数提供。

您可以在调用该文件的JSP文件中执行此筛选。

<c:choose>
    <c:when test="${filter.value eq 'xxx'}">
      ... import js here
    </c:when>
    <c:otherwise>
    .... other script
    </c:otherwise>
</c:choose>