java Spring mvc.大小写不敏感的获取参数Map

nfs0ujit  于 2023-01-07  发布在  Java
关注(0)|答案(4)|浏览(136)

根据this answer我尝试写我的代码:
波约:

class MyBean{

    public String getValueName() {
        return valueName;
    }

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

    String valueName;
}

内部控制器:

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

在调试中,我看到过滤器方法被调用,但是我无法实现大小写不敏感的获取参数Map。
例如,localhost:8081/getMyBean?valueName=trololo工作,但localhost:8081/getMyBean?valuename=trololo不工作

tp5buhyn

tp5buhyn1#

我认为您的问题是@ModelAttribute,您要求Spring将参数Map到MyBean对象,而该对象中的属性是valueName
为了让Spring将参数反映给对象,它需要使用正确的大小写。
您有两个选项:

  • 在MyBean对象中将属性名更改为valuename,并将所有属性名更改为小写,在您的解决方案的帮助下应该可以正常工作。
  • 删除@ModelAttribute并为每个属性放置@RequestParam。如果你有很多 prop ,这可能会很痛苦。
r7knjye2

r7knjye22#

以下是您可以执行的操作...
创建变量全部小写的域(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来得到你想要的对象。
希望有帮助:)

jtw3ybtb

jtw3ybtb3#

实际上,你必须根据你的bean变量名来改变CaseInsensitiveRequestFilter类中的东西。在你的例子中,变量是valueName,所以对于每个请求,它都会根据你的变量setter方法驼峰大小写注入来转换它,然后根据你的请求来匹配。只是尝试一下你的自定义需求:

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

tct7dpnv4#

您的枚举参数:

enum YourEnum {
    ENUM1, ENUM2, ENUM3
}

添加此转换器类:

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

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

相关问题