繁体   English   中英

Spring MVC。 不区分大小写获取参数映射

[英]Spring mvc. case insensitive get parameters mapping

根据这个答案,我尝试编写我的代码:

波乔:

class MyBean{

    public String getValueName() {
        return valueName;
    }

    public void setValueName(String valueName) {
        this.valueName = valueName;
    }

    String valueName;
}

内部 controller:

    @ModelAttribute
    public MyBean createMyBean() {
        return new MyBean();
    }
    @RequestMapping(value = "/getMyBean", method = RequestMethod.GET)
    public String getMyBean(@ModelAttribute MyBean myBean) {
        System.out.println(myBean.getValueName());
        return "pathToJsp";
    }

web.xml配置:

<filter>
    <filter-name>caseInsensitiveFilter</filter-name>
    <filter-class>com.terminal.interceptor.CaseInsensitiveRequestFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>caseInsensitiveFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

筛选:

@Component
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 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 getParameterMap() {
            return Collections.unmodifiableMap(this.params);
        }

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

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

在调试中,我看到过滤器方法调用但我无法实现不区分大小写的获取参数映射。

例如localhost:8081/getMyBean?valueName=trololo有效但localhost:8081/getMyBean?valuename=trololo - 不

我相信您的问题是@ModelAttribute 您要让Spring将参数映射到MyBean对象,并且该对象内的属性是valueName

为了使Spring将参数反映到对象,它必须处于正确的情况下。

您有2个选择:

  • 将MyBean对象中的属性名称更改为valuename ,并将所有属性名称更改为小写,它应该在您的解决方案的帮助下起作用。
  • 删除@ModelAttribute并为每个属性添加@RequestParam 如果您有很多道具,这可能会很痛苦。

这是您可以做的...

使用所有小写变量创建域(POJO)

public class MyBean{
    private String valuename;

    public String getValuename() {
        return valuename;
    }

    public void setValuename(String valuename) {
        this.valuename = valuename;
    }
}

然后创建一个将扩展HttpServletRequestWrapper的类

public class CustomWrappedRequest extends HttpServletRequestWrapper
{
    private final Map<String, String[]> modifiableParameters;
    private Map<String, String[]> allParameters = null;

    public CustomWrappedRequest(final HttpServletRequest request, 
                                                    final Map<String, String[]> additionalParams)
    {
        super(request);
        modifiableParameters = new TreeMap<String, String[]>();
        modifiableParameters.putAll(additionalParams);
    }

    @Override
    public String getParameter(final String name)
    {
        String[] strings = getParameterMap().get(name);
        if (strings != null)
        {
            return strings[0];
        }
        return super.getParameter(name);
    }

    @Override
    public Map<String, String[]> getParameterMap()
    {
        if (allParameters == null)
        {
            allParameters = new TreeMap<String, String[]>();
            allParameters.putAll(super.getParameterMap());
            allParameters.putAll(modifiableParameters);
        }
        return Collections.unmodifiableMap(allParameters);
    }

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

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

最后添加一个具有适当web.xml配置的过滤器, doFilter()将如下所示

public void doFilter(ServletRequest request, ServletResponse reponse, FilterChain chain)
            throws IOException, ServletException {
        Map<String, String[]> params = request.getParameterMap();
        Map<String, String[]> extraParams = new TreeMap<String, String[]>();
        Iterator<String> i = params.keySet().iterator();

        while ( i.hasNext() )
          {
            String key = (String) i.next();
            String value = ((String[]) params.get( key ))[ 0 ];
            extraParams.put(key.toLowerCase(), new String[] {value});

          }
        HttpServletRequest wrappedRequest = new CustomWrappedRequest((HttpServletRequest)request, extraParams);

        chain.doFilter(wrappedRequest, reponse);

    }

在这里,过滤器会将参数修饰成小写形式并将其附加到您的自定义请求中。 然后使用可以在控制器代码中使用@ModelAttribute来获取所需的对象。

希望能帮助到你 :)

实际上,您必须根据bean变量名称更改CaseInsensitiveRequestFilter类中的内容。 在您的情况下,变量为valueName ,因此对于每个请求,它将根据您的变量设置方法驼峰式注入将其转换,然后根据您的请求进行匹配。 只需尝试您的自定义要求:

package biz.deinum.web.filter;

import java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;

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

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

        private CaseInsensitiveHttpServletRequestWrapper(HttpServletRequest request) {
            super(request);
            Map<String, String[]> map = request.getParameterMap();
            Set set = map.entrySet();
            Iterator it = set.iterator();
            Map<String, String[]> tempMap = new HashMap<String, String[]>(); 
            while (it.hasNext()) {
                Map.Entry<String, String[]> entry = (Entry<String, String[]>) it.next();
                String key = entry.getKey();
                // Keep your parameter bean name here in your case it is "valueName"
                String beanParamaterName = "valueName";
                if(key.equalsIgnoreCase(beanParamaterName)){
                    tempMap.put(key.toLowerCase(), entry.getValue());
                }
            }
            params.putAll(tempMap);
        }

        @Override
        public String getParameter(String name) {
            String[] values = getParameterValues(name);
            System.out.println(values.toString()+"-");
            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) {
            System.out.println(name);
            return (String[])params.get(name);
        }
    }
}

你的枚举参数:

enum YourEnum {
    ENUM1, ENUM2, ENUM3
}

添加此转换器 class:

class StringToEnumConverter implements Converter<String, YourEnum> {
    @Override
    YourEnum convert(String source) {
        return YourEnum.valueOf(source.toUpperCase());
    }
}

和这个配置:

class ApiWebConfiguration implements WebMvcConfigurer {

    @Override
    void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new StringToEnumConverter());
    }
...
}

瞧,不区分大小写的枚举参数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM