@ControllerAdvice + @ExceptionHandler 使用

1、簡介java

@ControllerAdvice,是spring3.2提供的新註解,意思是控制器加強。web

下面是它的解釋。spring

大體意思是,session

一、表示標有這個註解的類是一個Controller。它有一個默認行爲:被註解的類會做用到全部已知的Controller上。mvc

二、它一般會和 @ExceptionHandler @InitBinder @ModelAttribute 等註解一塊兒使用app

/**
 * 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 一塊兒使用的狀況會比較多。ide

下面是@ExceptionHandler 的解釋。flex

只截取了一部分,大體意思就是@ExceptionHandler標註的類或者方法是一個異常處理類或者方法。ui

它很是靈活,能夠使用value指定具體的異常類。this

/**
 * 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>
* ...... *

 

2、實踐

下面這段代碼是咱們項目中使用到的。用於處理業務中拋出自定義的異常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);
    }
}
相關文章
相關標籤/搜索