Spring mvc. нечувствительность к регистру
этот ответ Я пытаюсь написать свой код:
POJO:
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);
}
}
}
В отладке я вижу, что метод фильтра вызывается, но я не могу добиться того,
например localhost:8081/getMyBean?valueName=trololo
работает, но localhost:8081/getMyBean?valueName=trololo
- not
Ответы
Ответ 1
Ваша проблема, я считаю, составляет @ModelAttribute
. Вы запрашиваете Spring для сопоставления параметров объекту MyBean
, а свойство внутри этого объекта valueName
.
В порядке Spring, чтобы отразить параметры объекта, он должен быть в правильном случае.
У вас есть 2 варианта:
- измените имя свойства на
valueName
в вашем объекте MyBean и все имена свойств в нижнем регистре, он должен работать с вашим решением.
- удалите
@ModelAttribute
и поместите @RequestParam
для каждого свойства. Если у вас много реквизита, это может быть болезненно.
Ответ 2
Вот что вы можете сделать...
Создайте домен (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
в коде контроллера, чтобы получить желаемый объект.
Надеюсь, это поможет:)
Ответ 3
Собственно, вам нужно изменить вещи в классе CaseInsensitiveRequestFilter
в соответствии с вашим именем переменной bean. В вашем случае переменная 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);
}
}
}