java.lang.IllegalArgumentException:使用 Spring 自定义参数解析器时参数类型不匹配
java.lang.IllegalArgumentException: argument type mismatch while using Spring Custom Argument Resolver
我得到 java.lang.IllegalArgumentException:使用 Spring 参数解析器和 HandlerMethodArgumentResolver 时参数类型不匹配。多次调试我的代码,但能够找到出现此异常的原因。如果有人可以帮助我,那就太好了。
这是我的代码。
public final class SpringArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return CommonHeader.class.isAssignableFrom(parameter.getParameterType());
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
CommonHeader commonHeader = new CommonHeader();
String user_id = webRequest.getHeader("UserID");
commonHeader.setUser_id(user_id);
return commonHeader;
}
配置class:
@Configuration
@EnableWebMvc
public class SpringWebMvcConfig implements WebMvcConfigurer {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new SpringArgumentResolver());
}
}
CommonHeader class:
public class CommonHeader {
private String user_id;
private String ip_address;
private String request_id;
public CommonHeader(String user_id) {
this.user_id = user_id;
}
public CommonHeader(){}
public String getUser_id() {
return user_id;
}
public void setUser_id(String user_id) {
this.user_id = user_id;
}
}
控制器:
@GetMapping("user_data")
public DeferredResult<ResponseEntity<JsonNode>> getUserPreferenceData(GetDataRequest getDataRequest) {
DeferredResult<ResponseEntity<JsonNode>> deferredResult = new DeferredResult<>();
// some logic
// some logic
return deferredResult;
}
请求 class 扩展 CommonHeader class:
@Getter
@Setter
public class GetDataRequest extends CommonHeader {
private String name1;
private String name2;
}
你的SpringArgumentResolver
是错误的。 GetDataRequest
是 CommonHeader
,但 CommonHeader
不是 GetDataRequest
。你的 SpringArgumentResolver
always return 是一个 CommonDataHeader
不能 cast/turned 变成 GetDataRequest
因此错误。
CommonHeader header = new CommonHeader();
GetDataRequest request = (GetDataRequest) header;
基本上就是您所期望的自动发生的情况。现在这在常规 java 中不起作用(导致 ClassCastException
),为什么它在 Spring 中起作用? Spring 检查生成的对象是否可以分配给该方法参数,在这种情况下不能,因为 GetDataRequest.isAssignableFrom(CommonHeader.class);
将 return false
(尽管相反是正确的!).
您应该在 SpringArgumentResolver
中做的是动态确定 class 并实例化它,将其转换为 CommonHeader
并设置字段。
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
CommonHeader commonHeader = BeanUtils.instantiateClass(parameter.getParameterType(), CommonHeader.class);
String user_id = webRequest.getHeader("UserID");
commonHeader.setUser_id(user_id);
return commonHeader;
}
这将使用方法参数的实际类型来创建实例,从而消除 ClassCastException
,对于 Spring,IllegalArgumentException
。
我得到 java.lang.IllegalArgumentException:使用 Spring 参数解析器和 HandlerMethodArgumentResolver 时参数类型不匹配。多次调试我的代码,但能够找到出现此异常的原因。如果有人可以帮助我,那就太好了。 这是我的代码。
public final class SpringArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return CommonHeader.class.isAssignableFrom(parameter.getParameterType());
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
CommonHeader commonHeader = new CommonHeader();
String user_id = webRequest.getHeader("UserID");
commonHeader.setUser_id(user_id);
return commonHeader;
}
配置class:
@Configuration
@EnableWebMvc
public class SpringWebMvcConfig implements WebMvcConfigurer {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new SpringArgumentResolver());
}
}
CommonHeader class:
public class CommonHeader {
private String user_id;
private String ip_address;
private String request_id;
public CommonHeader(String user_id) {
this.user_id = user_id;
}
public CommonHeader(){}
public String getUser_id() {
return user_id;
}
public void setUser_id(String user_id) {
this.user_id = user_id;
}
}
控制器:
@GetMapping("user_data")
public DeferredResult<ResponseEntity<JsonNode>> getUserPreferenceData(GetDataRequest getDataRequest) {
DeferredResult<ResponseEntity<JsonNode>> deferredResult = new DeferredResult<>();
// some logic
// some logic
return deferredResult;
}
请求 class 扩展 CommonHeader class:
@Getter
@Setter
public class GetDataRequest extends CommonHeader {
private String name1;
private String name2;
}
你的SpringArgumentResolver
是错误的。 GetDataRequest
是 CommonHeader
,但 CommonHeader
不是 GetDataRequest
。你的 SpringArgumentResolver
always return 是一个 CommonDataHeader
不能 cast/turned 变成 GetDataRequest
因此错误。
CommonHeader header = new CommonHeader();
GetDataRequest request = (GetDataRequest) header;
基本上就是您所期望的自动发生的情况。现在这在常规 java 中不起作用(导致 ClassCastException
),为什么它在 Spring 中起作用? Spring 检查生成的对象是否可以分配给该方法参数,在这种情况下不能,因为 GetDataRequest.isAssignableFrom(CommonHeader.class);
将 return false
(尽管相反是正确的!).
您应该在 SpringArgumentResolver
中做的是动态确定 class 并实例化它,将其转换为 CommonHeader
并设置字段。
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
CommonHeader commonHeader = BeanUtils.instantiateClass(parameter.getParameterType(), CommonHeader.class);
String user_id = webRequest.getHeader("UserID");
commonHeader.setUser_id(user_id);
return commonHeader;
}
这将使用方法参数的实际类型来创建实例,从而消除 ClassCastException
,对于 Spring,IllegalArgumentException
。