Java 使请求参数绑定不区分大小写

Java 使请求参数绑定不区分大小写,java,spring,spring-mvc,Java,Spring,Spring Mvc,我有一个要求,即即使参数名称的情况发生变化,我也必须使requestParams正确绑定。注意:我使用的是spring 3.2 例如:http://localhost:8080/sample/home?**用户名**=xxx或http://localhost:8080/sample/home?用户名=xxx或 http://localhost:8080/sample/home?用户名=xxx应正确映射到我的 @请求参数值 @RequestMapping(value = "home", metho

我有一个要求,即即使参数名称的情况发生变化,我也必须使requestParams正确绑定。注意:我使用的是spring 3.2

例如:
http://localhost:8080/sample/home?*
*用户名**=xxx或
http://localhost:8080/sample/home?
用户名=xxx或
http://localhost:8080/sample/home?
用户名=xxx应正确映射到我的 @请求参数值

@RequestMapping(value = "home", method = RequestMethod.GET)
public goToHome(@RequestParam(value = "userName", required = false) String userName) {

}
所有三个URL都应该调用上述方法并正确绑定用户名。
请给我一些建议,如何通过实现新的参数处理程序解析器来实现这一点?与更改所有@RequestParam的代码中的逻辑相比,最好重写spring配置类以进行一般性实现。

您可以编写一个servlet过滤器来实现这一点。但它确实需要一些编码工作

以下是代码的链接-

类似这样的东西-在这个servlet过滤器中,将参数转换为小写

public final class LowerCaseParametersFilter implements Filter {
 @Override
public void doFilter(final ServletRequest request,
                     final ServletResponse response,
                     final FilterChain chain)
        throws IOException, ServletException {
    if (request instanceof HttpServletRequest) {
        LOG.debug("Wrapping request");
        chain.doFilter(new LowerCaseRequest((HttpServletRequest) request),
                       response);
    } else {
        LOG.warn(format("Not wrapping request: %s", request.getClass()));
        chain.doFilter(request, response);
    }
}
}
这是您需要的xml配置

 <bean id="delegatingFilter"
      class="org.springframework.web.filter.DelegatingFilterProxy"

      p:targetBeanName="lowerParams"/>
 <bean id="lowerParams"   
      class="com.isti.bss.mvc.LowerCaseParametersFilter"/>

我做了一些研究,发现了这个

公共类HttpCustomParamFilter实现过滤器
{
私有静态类HttpServletRequestCustomeWrapper扩展了HttpServletRequestWrapper
{
私有字符串[]参数值;
@凌驾
公共字符串[]getParameterValues(字符串名称)
{
Map localParameterMap=super.getParameterMap();
//处理http请求参数(如开始、计数、查询、排序、筛选等)的大小写不敏感。
if(localParameterMap!=null&&!localParameterMap.isEmpty())
{
parameterValues=新字符串[localParameterMap.size()];
for(字符串键:localParameterMap.keySet())
{
if(名称.相等信号案例(关键))
parameterValues=localParameterMap.get(键);
其他的
parameterValues=null;
}
}
返回参数值;
}
Spring有一个可用于进行不区分大小写的查找的

实现可以如下所示

package biz.deinum.web.filter;

import org.springframework.util.LinkedCaseInsensitiveMap;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Map;

/**
 * Wrapper for an {@link HttpServletRequest} to make the lookup of parameters case insensitive. The functionality
 * is achieved by using the {@link LinkedCaseInsensitiveMap} from Spring.
 * 
 * @author Marten Deinum
 */
public class CaseInsensitiveRequestFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        filterChain.doFilter(new CaseInsensitiveHttpServletRequestWrapper(request), response);
    }

    private static class CaseInsensitiveHttpServletRequestWrapper extends HttpServletRequestWrapper {

        private final LinkedCaseInsensitiveMap<String[]> params = new LinkedCaseInsensitiveMap<>();

        /**
         * Constructs a request object wrapping the given request.
         *
         * @param request
         * @throws IllegalArgumentException if the request is null
         */
        private CaseInsensitiveHttpServletRequestWrapper(HttpServletRequest request) {
            super(request);
            params.putAll(request.getParameterMap());
        }

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

        @Override
        public Map<String, String[]> getParameterMap() {
            return Collections.unmodifiableMap(this.params);
        }

        @Override
        public Enumeration<String> getParameterNames() {
            return Collections.enumeration(this.params.keySet());
        }

        @Override
        public String[] getParameterValues(String name) {
            return (String[])params.get(name);
        }
    }
}
package biz.deinum.web.filter;
导入org.springframework.util.LinkedCaseInsensitiveMap;
导入org.springframework.web.filter.OncePerRequestFilter;
导入javax.servlet.FilterChain;
导入javax.servlet.ServletException;
导入javax.servlet.http.HttpServletRequest;
导入javax.servlet.http.HttpServletRequestWrapper;
导入javax.servlet.http.HttpServletResponse;
导入java.io.IOException;
导入java.util.Collections;
导入java.util.Enumeration;
导入java.util.Map;
/**
*用于{@link HttpServletRequest}的包装器,以使参数的查找不区分大小写
*是通过使用Spring中的{@link LinkedCaseInsensitiveMap}实现的。
* 
*@作者Marten Deinum
*/
公共类CaseInsensitiveRequestFilter扩展了OncePerRequestFilter{
@凌驾
受保护的void doFilterInternal(HttpServletRequest请求、HttpServletResponse响应、FilterChain FilterChain)抛出ServletException、IOException{
filterChain.doFilter(新的不区分大小写的HttpServletRequestWrapper(请求),响应);
}
私有静态类CaseInsensitiveHttpServletRequestWrapper扩展了HttpServletRequestWrapper{
私有最终LinkedCaseInsensitiveMap参数=新LinkedCaseInsensitiveMap();
/**
*构造一个封装给定请求的请求对象。
*
*@param请求
*如果请求为空,@将引发IllegalArgumentException
*/
private CaseInsensitiveHttpServletRequestWrapper(HttpServletRequest请求){
超级(请求);
putAll(request.getParameterMap());
}
@凌驾
公共字符串getParameter(字符串名称){
字符串[]值=getParameterValues(名称);
if(value==null | | values.length==0){
返回null;
}
返回值[0];
}
@凌驾
公共映射getParameterMap(){
返回Collections.unmodifiableMap(this.params);
}
@凌驾
公共枚举getParameterNames(){
返回Collections.enumeration(this.params.keySet());
}
@凌驾
公共字符串[]getParameterValues(字符串名称){
return(String[])params.get(name);
}
}
}

实现自定义过滤器的解决方案

过滤器:

public final class CaseInsensitiveParametersFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) {
    }

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        if (request instanceof HttpServletRequest) {
            chain.doFilter(new CustomHttpServletRequestWrapper((HttpServletRequest) request), response);
        } else {
            chain.doFilter(request, response);
        }

    }

    private static class CustomHttpServletRequestWrapper extends HttpServletRequestWrapper {

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

        public CustomHttpServletRequestWrapper(HttpServletRequest request) {
            super(request);
            Map<String, String[]> originalParams = request.getParameterMap();
            for (Map.Entry<String, String[]> entry : originalParams.entrySet()) {
                lowerCaseParams.put(entry.getKey().toLowerCase(), entry.getValue());
            }
        }

        @Override
        public String getParameter(String name) {
            String[] values = getParameterValues(name);
            if (values != null && values.length > 0) {
                return values[0];
            } else {
                return null;
            }
        }

        @Override
        public Map getParameterMap() {
            return Collections.unmodifiableMap(lowerCaseParams);
        }

        @Override
        public Enumeration getParameterNames() {
            return Collections.enumeration(lowerCaseParams.keySet());
        }

        @Override
        public String[] getParameterValues(String name) {
            return lowerCaseParams.get(name);
        }

    }

为什么?编写此需求的人可能认为它很琐碎,但事实并非如此。然后,所有请求在通过过滤器时都将转换为小写。因此,我必须更改我的控制器@requestParam(value=“username”)。但我需要的是,我希望绑定在不更改控制器逻辑的情况下发生。我需要绑定在任何情况下都会发生请求。仅供参考,requestparam方法参数解析程序中正在发生绑定。我希望自定义此绑定以忽略大小写。您考虑了多少个参数?它只是用户名参数吗?我希望绑定到happen for all controller method ignoring cases。我刚刚发布了一个示例方法。请尝试我发布的解决方案-我认为它可以工作bcos spring调用获取参数名,但需要相当多的重写-还找到了对此的引用-而不是转换为小写-将参数添加到
LinkedCaseInsensitiveMap
w在您的情况下,这将起作用。您需要覆盖所有
getParameter
方法(总共4个)。@M.Deinum此筛选器是否应在某个位置注册?getParameterValues有编译错误。params.get(name)返回对象请检查:@gstackoverflow它是用java8生成的,在这里编译很好,出于某种原因,堆栈溢出代码提交了实例变量定义上的
。@M.Deinum我使用java 8,遇到了此编译错误
public final class CaseInsensitiveParametersFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) {
    }

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        if (request instanceof HttpServletRequest) {
            chain.doFilter(new CustomHttpServletRequestWrapper((HttpServletRequest) request), response);
        } else {
            chain.doFilter(request, response);
        }

    }

    private static class CustomHttpServletRequestWrapper extends HttpServletRequestWrapper {

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

        public CustomHttpServletRequestWrapper(HttpServletRequest request) {
            super(request);
            Map<String, String[]> originalParams = request.getParameterMap();
            for (Map.Entry<String, String[]> entry : originalParams.entrySet()) {
                lowerCaseParams.put(entry.getKey().toLowerCase(), entry.getValue());
            }
        }

        @Override
        public String getParameter(String name) {
            String[] values = getParameterValues(name);
            if (values != null && values.length > 0) {
                return values[0];
            } else {
                return null;
            }
        }

        @Override
        public Map getParameterMap() {
            return Collections.unmodifiableMap(lowerCaseParams);
        }

        @Override
        public Enumeration getParameterNames() {
            return Collections.enumeration(lowerCaseParams.keySet());
        }

        @Override
        public String[] getParameterValues(String name) {
            return lowerCaseParams.get(name);
        }

    }
public class RestServiceInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Filter[] getServletFilters() {
        return new Filter[]{new CaseInsensitiveParametersFilter()};
    }
}