在SpringMvc开发过程中,我们通常会用一种注解的参数校验法。因为用起来很方便。所以很受欢迎。今天就扒一扒这个注解异常校验的流程。作者通过不断的debug,终于找到北了。它在dispatchservlet中,总的调度入口如图所示。
最后在InvocableHandlerMethod类中获取传入的参数。
代码语言:javascript复制 protected Object[] getMethodArgumentValues(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {
MethodParameter[] parameters = this.getMethodParameters();
if (ObjectUtils.isEmpty(parameters)) {
return EMPTY_ARGS;
} else {
Object[] args = new Object[parameters.length];
for(int i = 0; i < parameters.length; i) {
MethodParameter parameter = parameters[i];
parameter.initParameterNameDiscovery(this.parameterNameDiscoverer);
args[i] = findProvidedArgument(parameter, providedArgs);
if (args[i] == null) {
//查看是否有何时的解析器
if (!this.resolvers.supportsParameter(parameter)) {
throw new IllegalStateException(formatArgumentError(parameter, "No suitable resolver"));
}
try {
//开始解析这个传入的参数
args[i] = this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory);
} catch (Exception var10) {
if (logger.isDebugEnabled()) {
String exMsg = var10.getMessage();
if (exMsg != null && !exMsg.contains(parameter.getExecutable().toGenericString())) {
logger.debug(formatArgumentError(parameter, exMsg));
}
}
throw var10;
}
}
}
return args;
}
}
在此类的开头,我们看到这里可以设置很多解析器
代码语言:javascript复制
代码语言:javascript复制public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgumentResolver {
private final ListargumentResolvers =new ArrayList();
private final Map, HandlerMethodArgumentResolver> argumentResolverCache = new ConcurrentHashMap(256);
public HandlerMethodArgumentResolverComposite() {
}
//添加解析器
public HandlerMethodArgumentResolverComposite addResolver(HandlerMethodArgumentResolver resolver) {
this.argumentResolvers.add(resolver);
return this;
}
//添加解析器
public HandlerMethodArgumentResolverComposite addResolvers(@Nullable HandlerMethodArgumentResolver... resolvers) {
if (resolvers != null) {
Collections.addAll(this.argumentResolvers, resolvers);
}
return this;
}
我们看到这块选出来的是ServletModelAttributeMethodProcessor,然后使用这个解析器进行参数校验。
写了一下午,没保存.....
上边写的这些其实还是没有分析到精髓上,我们大概的了解了一下流程,但是对于像@NotNull等注解的具体解析都没有找到,当然也不知道如何自定义一个注解解析器,并添加到viltaler中。所以上边的分析并不是很好,迷迷糊糊的。但是作者在DispatchServlet中发现了一个异常处理器。其是可以定义多个的,而且会轮询去执行,知道出现一个可以处理该异常的解析器就停止。
作者查看源码,发现在DispatchServlet初始化的时候,从Spring上下文中获取了这些解析器,代码如下图所示。
这块的意思就是说咋通过实现接口HandlerExceptionResolver,然后将其注入到SpringIoc中即可让SpringMvc去执行我们自定义的异常处理机制。也就是全局异常处理,但势必需要让我们自定义的异常处理器执行的比较早。所以我们实践一下。
代码语言:javascript复制@Component
public class MyHand implements HandlerExceptionResolver, Ordered {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
System.out.println("12");
e.printStackTrace();
System.out.println(o.toString());
return null;
}
@Override
public int getOrder() {
return 0;
}
}
我们看一下效果:
最近优点懒,睡得的挺好,一天能睡很久。文章好久都没更了,这是一个坏味道。希望早日回归正常态。
天气很热,注意开空调,节约用电~