介绍
HandlerMethodArgumentResolver是用来为处理器解析参数的,主要用在HandlerMethod中,每个Resolver对应一种类型的参数,其实现类特别的多。
接口定义
- supportsParameter 用于判断是否支持对某种参数的解析
- resolveArgument 将请求中的参数值解析为某种对象
public interface HandlerMethodArgumentResolver {
/**
* Whether the given {@linkplain MethodParameter method parameter} is
* supported by this resolver.
* @param parameter the method parameter to check
* @return {@code true} if this resolver supports the supplied parameter;
* {@code false} otherwise
*/
boolean supportsParameter(MethodParameter parameter);
/**
* Resolves a method parameter into an argument value from a given request.
* A {@link ModelAndViewContainer} provides access to the model for the
* request. A {@link WebDataBinderFactory} provides a way to create
* a {@link WebDataBinder} instance when needed for data binding and
* type conversion purposes.
* @param parameter the method parameter to resolve. This parameter must
* have previously been passed to {@link #supportsParameter} which must
* have returned {@code true}.
* @param mavContainer the ModelAndViewContainer for the current request
* @param webRequest the current request
* @param binderFactory a factory for creating {@link WebDataBinder} instances
* @return the resolved argument value, or {@code null} if not resolvable
* @throws Exception in case of errors with the preparation of argument values
*/
@Nullable
Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception;
}
例子实现
自定义注解
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface JsonParam {
String value();
boolean required() default true;
String defaultValue() default "";
}
实现 HandlerMethodArgumentResolver
public class JsonPathArgumentResolver implements HandlerMethodArgumentResolver {
private static final String JSON_REQUEST_BODY = "JSON_REQUEST_BODY";
//判断是否支持要转换的参数类型
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(JsonParam.class);
}
//当支持后进行相应的转换
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
String body = getRequestBody(webRequest);
Object val = null;
try {
val = JsonPath.read(body, parameter.getParameterAnnotation(JsonParam.class).value());
if (parameter.getParameterAnnotation(JsonParam.class).required() && val == null) {
throw new ParamCheckException(parameter.getParameterAnnotation(JsonParam.class).value() + "不能为空");
}
} catch (PathNotFoundException exception) {
System.out.println(exception.getStackTrace());
if (parameter.getParameterAnnotation(JsonParam.class).required()) {
// throw new ParamCheckException(parameter.getParameterAnnotation(JsonParam.class).value() + "不能为空");
throw exception;
}
}
return val;
}
private String getRequestBody(NativeWebRequest webRequest) {
HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
String jsonBody = (String) servletRequest.getAttribute(JSON_REQUEST_BODY);
if (jsonBody == null) {
try {
jsonBody = IOUtils.toString(servletRequest.getInputStream());
servletRequest.setAttribute(JSON_REQUEST_BODY, jsonBody);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return jsonBody;
}
}