[英]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个选择:
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.