Пользовательский преобразователь аргументов метода контроллера не совпадает, когда аргумент является картой - PullRequest
0 голосов
/ 07 марта 2019

Вот мой код.

Единственный контроллер имел метод с аргументом, аннотированным @UpperCase и напечатанным как StringWrapper.

// MainController.java

@RestController
@ResponseBody
public class MainController {
    @RequestMapping("/")
    public String get(@UpperCase("lowercase") StringWrapper upperCase){
        return upperCase.toString();
    }
}

Пользовательский тип StringWrapper просто деформирует строку в HashMap.

// StringWrapper.java

public class StringWrapper extends HashMap<String,String>  {
    public StringWrapper(String str) {
        this.put("data",str);
    }

    @Override
    public String toString() {
        return this.get("data");
    }
}

Определение аннотации и преобразователя.

// UpperCase.java

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface UpperCase {
    String value();
}


// UpperCaseResolver.java

public class UpperCaseResolver implements HandlerMethodArgumentResolver {
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(UpperCase.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        return new StringWrapper(parameter.getParameterAnnotation(UpperCase.class).value().toUpperCase());
    }
}


// UpperCaseResolverConfig.java

 @Configuration
public class UpperCaseResolverConfig implements WebMvcConfigurer {

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(new UpperCaseResolver());
    }
}

Сообщение об ошибке:

ERROR 7388 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.IllegalStateException: argument type mismatch
Controller [com.example.custom_parameter_resolver_demo.controller.MainController]
Method [public java.lang.String com.example.custom_parameter_resolver_demo.controller.MainController.get(com.example.common.annotation.pojo.StringWrapper)] with argument values:
 [0] [type=org.springframework.validation.support.BindingAwareModelMap] [value={}] ] with root cause

java.lang.IllegalArgumentException: argument type mismatch
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_191]
    at 

ВерсияSpring Boot, который я использую, это 2.1.3.RELEASE.

Кажется, что Spring MVC совпал с аргументом внутреннего распознавателя с именем MapMethodProcessor вместо моего собственного распознавателя.

package org.springframework.web.method.annotation;

public class MapMethodProcessor implements HandlerMethodArgumentResolver, HandlerMethodReturnValueHandler {

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return Map.class.isAssignableFrom(parameter.getParameterType());
    }

Он решаетпараметр соответствует самому себе, когда каждый раз, когда он является параметром Map, именно поэтому.

Я пытался повысить приоритет своего пользовательского преобразователя, но не могу понять, как это сделать.

Есть идеи для обхода этого?Большое спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...