栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

Spring MVC中的异常处理程序

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring MVC中的异常处理程序

(我在Spring 3.1中找到了实现它的方法,此答案的第二部分对此进行了描述)

请参见第16.11章处理 Spring
Reference的异常

  • 您可以实现HandlerExceptionResolver( 使用servlet而不是portlet包 )-这是某种全局@ExceptionHandler
  • 如果您没有针对异常的特定逻辑,而只是特定视图,则可以使用SimpleMappingExceptionResolver,它至少是的实现
    HandlerExceptionResolver
    ,您可以在其中指定异常名称模式和视图(jsp),当引发异常。例如:
        <bean   p:defaultErrorView="uncaughtException">       <property name="exceptionMappings"><props>    <prop key=".DataAccessException">dataAccessFailure</prop>    <prop key=".TypeMismatchException">resourceNotFound</prop>    <prop key=".AccessDeniedException">accessDenied</prop> </props>        </property>     </bean>

Spring 3.2+中,
可以使用注释类

@ControllerAdvice
,该类中的所有
@ExceptionHandler
方法都以全局方式工作。


Spring 3.1 中没有

@ControllerAdvice
。但是只要稍加修改,就可以具有类似的功能。

关键是对工作方式的理解

@ExceptionHandler
。在Spring
3.1中有一个类
ExceptionHandlerExceptionResolver
。此类(在其超类的帮助下)实现接口
HandlerExceptionResolver
并负责调用
@ExceptionHandler
方法。

HandlerExceptionResolver
接口只有一种方法:

    ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex);`.

当请求由Spring3.x控制器方法处理时,该方法(由表示

org.springframework.web.method.HandlerMethod
)就是
handler
参数。

ExceptionHandlerExceptionResolver
用途
handler
HandlerMethod
),以获得控制器类和扫描它用于与所注解的方法
@ExceptionHandler
。如果其中一个方法与例外(
ex
)相符,则会调用此方法以处理该例外。(否则
null
返回此信号是为了表示此异常解析器不承担任何责任)。

第一个想法是实现一个

HandlerExceptionResolver
行为类似于的自己
ExceptionHandlerExceptionResolver
,但
@ExceptionHandler
与其在控制器类中进行搜索,不如在控制器类中进行搜索。缺点是,
ExceptionHandlerExceptionResolver
必须手动配置(复制(或子类),并且必须)所有不错的消息转换器,参数解析器和返回值处理程序(真正的配置,并且仅
ExceptionHandlerExceptionResolver
由spring自动完成)。所以我想到了另一个想法:

实现一个简单的

HandlerExceptionResolver
“将”异常“转发”到THE(已配置)
ExceptionHandlerExceptionResolver
,但将其修改后
handler
指向包含全局Exception处理程序的Bean(我称它们为Global,因为它们对所有控制器都起作用)。

这是实现:

GlobalMethodHandlerExeptionResolver

    import java.util.List;    import java.util.concurrent.ConcurrentHashMap;    import java.util.concurrent.ConcurrentMap;    import javax.servlet.http.HttpServletRequest;    import javax.servlet.http.HttpServletResponse;    import org.springframework.beans.factory.NoSuchBeanDefinitionException;    import org.springframework.beans.factory.annotation.Autowired;    import org.springframework.core.Ordered;    import org.springframework.util.StringUtils;    import org.springframework.web.method.HandlerMethod;    import org.springframework.web.servlet.HandlerExceptionResolver;    import org.springframework.web.servlet.ModelAndView;    import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;    public class GlobalMethodHandlerExeptionResolver      implements HandlerExceptionResolver, Ordered {        @Override        public int getOrder() { return -1; //        }        private ExceptionHandlerExceptionResolver realExceptionResolver;        private List<GlobalMethodExceptionResolverContainer> containers;        @Autowired        public GlobalMethodHandlerExeptionResolver(     ExceptionHandlerExceptionResolver realExceptionResolver,     List<GlobalMethodExceptionResolverContainer> containers) { this.realExceptionResolver = realExceptionResolver; this.containers = containers;        }        @Override        public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {    for (GlobalMethodExceptionResolverContainer container : this.containers) {         ModelAndView result = this.realExceptionResolver.resolveException(  request,  response,  handlerMethodPointingGlobalExceptionContainerBean(container),  ex);     if (result != null)         return result; } // we feel not responsible return null;        }        protected HandlerMethod handlerMethodPointingGlobalExceptionContainerBean(  GlobalMethodExceptionResolverContainer container) { try {     return new HandlerMethod(container,        GlobalMethodExceptionResolverContainer.class.  getMethod("fakeHanderMethod"));  } catch (NoSuchMethodException | SecurityException e) {     throw new RuntimeException(e); }         }    }

全局处理程序必须实现此接口(以便找到并实现

fakeHanderMethod
用于
handler

    public interface GlobalMethodExceptionResolverContainer {        void fakeHanderMethod();    }

全局处理程序的示例:

    @Component    public class JsonGlobalExceptionResolver      implements GlobalMethodExceptionResolverContainer {        @Override        public void fakeHanderMethod() {        }        @ExceptionHandler(MethodArgumentNotValidException.class)        @ResponseStatus(HttpStatus.BAD_REQUEST)        @ResponseBody        public ValidationErrorDto handleMethodArgumentNotValidException(         MethodArgumentNotValidException validationException,         Locale locale) {  ...    return validationErrorDto;        }    }

顺便说一句:您不需要注册,

GlobalMethodHandlerExeptionResolver
因为spring会自动注册所有
HandlerExceptionResolver
为异常解析器实现的bean
。如此简单
<bean />
就足够了。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/408583.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号