不区分大小写的查询字符串请求参数

时间:2013-06-07 08:46:03

标签: java spring rest spring-mvc spring-webflow

我的目标是以下所有URI都可以正常工作

的https://其余/ XYZ的排序 =名称

的https://其余/ XYZ的排序 =名称

的https://其余/ XYZ 过滤 =名=值

的https://其余/ XYZ 过滤 =名=值

为了实现这一点,我创建了自定义过滤器来覆盖传递给FilterChain的HttpServletRequest。以下是此方法的链接:

http://forum.springsource.org/archive/index.php/t-87433.html

我的代码:

import java.io.IOException;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper; 

public class HttpCustomParamFilter implements Filter
{
    private static class HttpServletRequestCustomeWrapper extends HttpServletRequestWrapper
    {
        private String[] parameterValues;

        @Override
        public String[] getParameterValues(String name)
        {
            Map<String, String[]> localParameterMap = super.getParameterMap();

            // Handle case insensitivity of http request paramters like start, count, query, sort, filter etc.
            if (localParameterMap != null && !localParameterMap.isEmpty())
            {
                parameterValues = new String[localParameterMap.size()];
                for (String key : localParameterMap.keySet())
                {
                    if (name.equalsIgnoreCase(key))
                        parameterValues = localParameterMap.get(key);
                    else
                        parameterValues = null;
                }
            }
            return parameterValues;
        }

        public HttpServletRequestCustomWrapper(final ServletRequest request)
        {
            super((HttpServletRequest) request);
        }


    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
        FilterChain chain) throws IOException, ServletException {
        // override the request passed to the FilterChain
        chain.doFilter(new HttpServletRequestCustomWrapper(request), response);
        }

    @Override
    public void init(FilterConfig filterConfig)
            throws ServletException
    {
        // TODO Auto-generated method stub

    }

    @Override
    public void destroy()
    {
        // TODO Auto-generated method stub

    }

}

在这段代码中,我重写了getParameterValues(String name)方法并实现了请求参数的大小写不敏感,但不确定我是否需要覆盖任何其他方法。

我的怀疑:

  • 我是否需要覆盖其他方法,例如getParameter()和getParameterNames()?

  • 内部实施会受到什么影响?

  • 哪个类可以看到getParameter(),getParameterNames()和getParameterValues()的代码实现?

1 个答案:

答案 0 :(得分:2)

首先,让我说出我的平安:我不认为修改HttpServletRequestWrapper是可行的方法。我甚至不确定你将如何使用它,因为我的理解是它是特定于App Server的。作为旁注,this article具体说明了如何使用HttpServletRequest来获取不区分大小写的查询参数而不需要自己编译。

但是,本着回答你的问题的精神:

  1. 您需要覆盖getParameter()和getParameterNames()吗?你可以,因为它会让你有能力操纵案件。事实上,我认为使查询参数不区分大小写的最安全的方法是仅覆盖那些方法。使getParameter()调用对字符串名称执行不区分大小写的等号。不确定你会用getParameterNames()做什么,也许会返回所有可能的情况,但这似乎是多余的。
  2. 这会影响哪些内部实施?我不确定。 HttpServletRequest几乎是所有内容的核心,如果您的代码不是100%可靠,那么无法告诉您可以引入什么。例如,Spring有一个SecurityContextHolderAwareRequestWrapper,这是否意味着你刚刚打破了Spring Security?没有经过大量的测试就没问题。
  3. 哪个类可以看到getParameter(),getParameterNames()和getParameterValues()的代码实现?根据JavaDocs,HttpServletRequestWrapper是HttpServletRequest接口的唯一实现。此类的实际实现取决于您的应用程序容器。例如,在我的应用程序中它的weblogic.servlet.internal.ServletRequestImpl,因为我使用Web Logic。希望您使用的是具有现成代码的开源应用服务器。我发现这个的方法是在我的一个Controller处理程序方法中放置一个中断HttpServletRequest并在调试器中查看它的getClass()响应。