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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29531786/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 15:26:29  来源:igfitidea点击:

Making a request parameter binding case insensitive

javaspringspring-mvc

提问by Renganathan V

I have a requirement where I have to make requestParams to bind properly even if the cases of the param name changes. Note:I am using spring 3.2

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

For eg: http://localhost:8080/sample/home?**userName**=xxx or http://localhost:8080/sample/home?username=xxx or http://localhost:8080/sample/home?usernaMe=xxx should map properly to my @RequestParam value.

例如:http://localhost:8080/sample/home?**userName**=xxx 或http://localhost:8080/sample/home?username=xxx 或 http://localhost:8080/sample/home?usernaMe=xxx 应该正确映射到我的 @RequestParam 值。

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

}

All the three urls should call the above method and bind the user name properly. Please give me suggestions on how to implement this by implementing new argument handler resolver? Overriding spring config classes to implement generically is preferred over changing the logic in the code for all @RequestParam.

三个url都要调用上面的方法,正确绑定用户名。请给我关于如何通过实现新的参数处理程序解析器来实现这一点的建议?覆盖 spring 配置类以通用实现优于更改所有@RequestParam 代码中的逻辑。

回答by M. Deinum

Spring has a LinkedCaseInsensitiveMapWhich you could use to do case insensitive lookups.

Spring 有一个LinkedCaseInsensitiveMap可以用来进行不区分大小写的查找。

An implementation could look like the following.

实现可能如下所示。

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);
        }
    }
}

回答by Paul John

You could write a servlet filter that does this. But it does need some coding work.

您可以编写一个执行此操作的 servlet 过滤器。但它确实需要一些编码工作。

Here is the link to the code - http://www.acooke.org/cute/Forcinglow0.html

这是代码的链接 - http://www.acooke.org/cute/Forcinglow0.html

Something like this - in this servlet filter convert parameters to lower case

像这样 - 在这个 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);
    }
}
}

Here is the xml config - u wuld need

这是 xml 配置 - 你需要

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

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

I did some research and found this Case-insensitive query string request paramters

我做了一些研究,发现这个 不区分大小写的查询字符串请求参数

   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;
    }

回答by Gjera

Solution with implementing custom Filter.

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

Filter:

筛选:

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);
        }

    }

Servlet initializer:

Servlet 初始化程序:

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