zoukankan      html  css  js  c++  java
  • @ControllerAdvice + @ExceptionHandler 使用

    一、简介

    @ControllerAdvice,是spring3.2提供的新注解,意思是控制器增强。

    下面是它的解释。

    大致意思是,

    1、表示标有这个注解的类是一个Controller。它有一个默认行为:被注解的类会作用到所有已知的Controller上。

    2、它通常会和 @ExceptionHandler @InitBinder @ModelAttribute 等注解一起使用

    /**
     * Indicates the annotated class assists a "Controller".
     *
     * <p>Serves as a specialization of {@link Component @Component}, allowing for
     * implementation classes to be autodetected through classpath scanning.
     *
     * <p>It is typically used to define {@link ExceptionHandler @ExceptionHandler},
     * {@link InitBinder @InitBinder}, and {@link ModelAttribute @ModelAttribute}
     * methods that apply to all {@link RequestMapping @RequestMapping} methods.
     *
     * <p>One of {@link #annotations()}, {@link #basePackageClasses()},
     * {@link #basePackages()} or its alias {@link #value()}
     * may be specified to define specific subsets of Controllers
     * to assist. When multiple selectors are applied, OR logic is applied -
     * meaning selected Controllers should match at least one selector.
     *
     * <p>The default behavior (i.e. if used without any selector),
     * the {@code @ControllerAdvice} annotated class will
     * assist all known Controllers.
     *
     * <p>Note that those checks are done at runtime, so adding many attributes and using
     * multiple strategies may have negative impacts (complexity, performance).
     *
     * @author Rossen Stoyanchev
     * @author Brian Clozel
     * @author Sam Brannen
     * @since 3.2
     */

    在项目中与 @ExceptionHandler 一起使用的情况会比较多。

    下面是@ExceptionHandler 的解释。

    只截取了一部分,大致意思就是@ExceptionHandler标注的类或者方法是一个异常处理类或者方法。

    它非常灵活,可以使用value指定具体的异常类。

    /**
     * Annotation for handling exceptions in specific handler classes and/or
     * handler methods. Provides consistent style between Servlet and Portlet
     * environments, with the semantics adapting to the concrete environment.
     *
     * <p>Handler methods which are annotated with this annotation are allowed to
     * have very flexible signatures. They may have parameters of the following
     * types, in arbitrary order:
     * <ul>
     * <li>An exception argument: declared as a general Exception or as a more
     * specific exception. This also serves as a mapping hint if the annotation
     * itself does not narrow the exception types through its {@link #value()}.
     * <li>Request and/or response objects (Servlet API or Portlet API).
     * You may choose any specific request/response type, e.g.
     * {@link javax.servlet.ServletRequest} / {@link javax.servlet.http.HttpServletRequest}
     * or {@link javax.portlet.PortletRequest} / {@link javax.portlet.ActionRequest} /
     * {@link javax.portlet.RenderRequest}. Note that in the Portlet case,
     * an explicitly declared action/render argument is also used for mapping
     * specific request types onto a handler method (in case of no other
     * information given that differentiates between action and render requests).
     * <li>Session object (Servlet API or Portlet API): either
     * {@link javax.servlet.http.HttpSession} or {@link javax.portlet.PortletSession}.
     * An argument of this type will enforce the presence of a corresponding session.
     * As a consequence, such an argument will never be {@code null}.
     * <i>Note that session access may not be thread-safe, in particular in a
     * Servlet environment: Consider switching the
     * {@link org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#setSynchronizeOnSession
     * "synchronizeOnSession"} flag to "true" if multiple requests are allowed to
     * access a session concurrently.</i>
     * <li>{@link org.springframework.web.context.request.WebRequest} or
     * {@link org.springframework.web.context.request.NativeWebRequest}.
     * Allows for generic request parameter access as well as request/session
     * attribute access, without ties to the native Servlet/Portlet API.
     * <li>{@link java.util.Locale} for the current request locale
     * (determined by the most specific locale resolver available,
     * i.e. the configured {@link org.springframework.web.servlet.LocaleResolver}
     * in a Servlet environment and the portal locale in a Portlet environment).
     * <li>{@link java.io.InputStream} / {@link java.io.Reader} for access
     * to the request's content. This will be the raw InputStream/Reader as
     * exposed by the Servlet/Portlet API.
     * <li>{@link java.io.OutputStream} / {@link java.io.Writer} for generating
     * the response's content. This will be the raw OutputStream/Writer as
     * exposed by the Servlet/Portlet API.
     * <li>{@link org.springframework.ui.Model} as an alternative to returning
     * a model map from the handler method. Note that the provided model is not
     * pre-populated with regular model attributes and therefore always empty,
     * as a convenience for preparing the model for an exception-specific view.
     * </ul>
    * ...... *

    二、实践

    下面这段代码是我们项目中使用到的。用于处理业务中抛出自定义的异常ServiceException与通用异常的。

    /**
     * 全局的业务异常处理类.
     *
     * @author lkb
     */
    @ControllerAdvice
    public class GlobalExceptionHandler
    {
        
        /** The error code. */
        @Value("${errorCode:ERROR_10001}")
        private String errorCode;
        
        /**
         * 发生自定义业务异常时处理方法.
         *
         * @param req the req
         * @param e the e
         * @return the string
         * @throws Exception 从每个模块control获取,另外JSON格式从定义文档获取
         */
        @ExceptionHandler(value = ServiceException.class)
        @ResponseStatus(HttpStatus.CONFLICT)
        @ResponseBody
        public String defaultErrorHandler(HttpServletRequest req, ServiceException e)
            throws Exception
        {
            LogUtil.getInstance().error("+++++++++++++ServiceException Error Info+++++++++++++", e);
            //实例化异常对象
            ErrorInfo errorInfo = new ErrorInfo();
            if (e != null && StringUtils.isNotEmpty(e.getMessage()))
            {
                errorInfo.setErrorCode(e.getMessage());
                errorInfo.setErrorDesc("");
                errorInfo.setErrorInfoUrl("");
            }
            Map<String, Object> resultMap = CommonUtil.getInstance().getErrorData(errorInfo);
            return JSON.toJSONString(resultMap);
        }
        
        /**
         * 发生非业务异常时处理方法.
         *
         * @param req the req
         * @param e the e
         * @return the string
         * @throws Exception 未知异常,在配置文件定义;默认在上面定义接收
         */
        @ExceptionHandler(value = Exception.class)
        @ResponseStatus(HttpStatus.BAD_REQUEST)
        //@ResponseStatus()
        @ResponseBody
        public String defaultErrorHandler(HttpServletRequest req, Exception e)
            throws Exception
        {
            LogUtil.getInstance().error("+++++++++++++Exception Error Info+++++++++++++", e);
            //实例化异常对象
            ErrorInfo errorInfo = new ErrorInfo();
            errorInfo.setErrorCode(errorCode);
            errorInfo.setErrorDesc("");
            errorInfo.setErrorInfoUrl("");
            Map<String, Object> resultMap = CommonUtil.getInstance().getErrorData(errorInfo);
            return JSON.toJSONString(resultMap);
        }
    }
  • 相关阅读:
    后缀数组-另辟蹊径
    Project Euler 不定期更新
    Educational Codeforces Round 93 (Rated for Div. 2)
    Codeforces Round #664 (Div. 2)
    lower_bound和upper_bound的用法
    Codeforces Round #663 (Div. 2)
    Codeforces Round #661 (Div. 3)
    质数笔记
    C++运算符的优先级
    图的构建
  • 原文地址:https://www.cnblogs.com/cuglkb/p/8110045.html
Copyright © 2011-2022 走看看