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); } }