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

Posted

技术标签:

【中文标题】不区分大小写的查询字符串请求参数【英文标题】:Case-insensitive query string request parameters 【发布时间】:2013-06-03 12:14:49 【问题描述】:

我的目标是所有低于 URI 的都应该工作

https://rest/xyz?排序=名称

https://rest/xyz?排序=名称

https://rest/xyz?过滤器=name=value

https://rest/xyz?过滤器=name=value

为了实现这一点,我创建了覆盖传递给 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】:

首先,让我说我的平安:我不认为修改 HttpServletRequestWrapper 是要走的路。我什至不确定您将如何使用它,因为我的理解是它是特定于 App Server 的。附带说明一下,this article 详细说明了如何使用 HttpServletRequest 来获取不区分大小写的查询参数,而无需自己动手。

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

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

【讨论】:

嘿 CodeChimp,谢谢。这是您在文章中建议的方法之一,我正在编写自己的自定义过滤器并将http请求传递给spring。在通过 spring 代码时,我发现只有 getParaNames 被调用,因此覆盖它正在解决我的目的。但是 getParamter() 可能会在其他一些框架中使用,我不知道,所以不知道它是否必须被覆盖。我按照您的建议在应用服务器代码中看到了这些方法的实现,在我的例子中是码头。

以上是关于不区分大小写的查询字符串请求参数的主要内容,如果未能解决你的问题,请参考以下文章

Oracle 如可控制查询不区分大小写?

字符串属性的 gql 查询中不区分大小写的 where 子句

Laravel 7 / SQL不区分大小写的where子句

mysql 字段值不区分大小写

使用 Amazon Dynamodb 进行不区分大小写的查询

NHibernate、SQLite 和 Cyrillic 字符:区分大小写和回退查询