Get the App
SLTechnology News&Howtos  ›  Internet Technology  › 

How to handle exceptions with @ RestControllerAdvice

Shulou Source: shulou.com Published: 2022-06-02 10:45:54 10月11日 Update

This article is about how to handle exceptions using @ RestControllerAdvice. The editor thinks it is very practical, so I share it with you. I hope you can learn something after reading this article. Let's take a look at it with the editor.

From the DispatcherServlet entrance, as follows:

Protected void doService (HttpServletRequest request, HttpServletResponse response) throws Exception {if (logger.isDebugEnabled ()) {String resumed = WebAsyncUtils.getAsyncManager (request) .hasConcurrentResult ()? " Resumed ":"; logger.debug ("DispatcherServlet with name'" + getServletName () + "'" + resumed + "processing" + request.getMethod () + "request for [" + getRequestUri (request) + "]");} / / Keep a snapshot of the request attributes in case of an include, / / to be able to restore the original attributes after the include. Map attributesSnapshot = null; if (WebUtils.isIncludeRequest (request)) {attributesSnapshot = new HashMap (); Enumeration attrNames = request.getAttributeNames (); while (attrNames.hasMoreElements ()) {String attrName = (String) attrNames.nextElement (); if (this.cleanupAfterInclude | | attrName.startsWith (DEFAULT_STRATEGIES_PREFIX)) {attributesSnapshot.put (attrName, request.getAttribute (attrName)) } / / Make framework objects available to handlers and view objects. Request.setAttribute (WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext ()); request.setAttribute (LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver); request.setAttribute (THEME_RESOLVER_ATTRIBUTE, this.themeResolver); request.setAttribute (THEME_SOURCE_ATTRIBUTE, getThemeSource ()); FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate (request, response); if (inputFlashMap! = null) {request.setAttribute (INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap (inputFlashMap)) } request.setAttribute (OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap ()); request.setAttribute (FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager); try {/ / look directly at this method doDispatch (request, response);} finally {if (! WebAsyncUtils.getAsyncManager (request). IsConcurrentHandlingStarted ()) {/ / Restore the original attribute snapshot, in case of an include. If (attributesSnapshot! = null) {restoreAttributesAfterInclude (request, attributesSnapshot);} protected void doDispatch (HttpServletRequest request, HttpServletResponse response) throws Exception {HttpServletRequest processedRequest = request; HandlerExecutionChain mappedHandler = null; boolean multipartRequestParsed = false; WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager (request); try {ModelAndView mv = null; Exception dispatchException = null; try {processedRequest = checkMultipart (request) MultipartRequestParsed = (processedRequest! = request) / / Determine handler for the current request. MappedHandler = getHandler (processedRequest); if (mappedHandler = = null | | mappedHandler.getHandler () = = null) {noHandlerFound (processedRequest, response); return;} / / Determine handler adapter for the current request. HandlerAdapter ha = getHandlerAdapter (mappedHandler.getHandler ()); / / Process last-modified header, if supported by the handler. String method = request.getMethod (); boolean isGet = "GET" .equals (method); if (isGet | | "HEAD" .equals (method)) {long lastModified = ha.getLastModified (request, mappedHandler.getHandler ()); if (logger.isDebugEnabled ()) {logger.debug ("Last-Modified value for [" + getRequestUri (request) + "] is:" + lastModified) } if (new ServletWebRequest (request, response) .checkNotModified (lastModified) & & isGet) {return;}} if (! mappedHandler.applyPreHandle (processedRequest, response)) {return;} / / Actually invoke the handler. Mv = ha.handle (processedRequest, response, mappedHandler.getHandler ()); if (asyncManager.isConcurrentHandlingStarted ()) {return;} applyDefaultViewName (processedRequest, mv); mappedHandler.applyPostHandle (processedRequest, response, mv);} catch (Exception ex) {dispatchException = ex } catch (Throwable err) {/ / As of 4.3, we're processing Errors thrown from handler methods as well, / / making them available for @ ExceptionHandler methods and other scenarios. DispatchException = new NestedServletException ("Handler dispatch failed", err);} / / handling result (including exception handling) processDispatchResult (processedRequest, response, mappedHandler, mv, dispatchException);} catch (Exception ex) {triggerAfterCompletion (processedRequest, response, mappedHandler, ex);} catch (Throwable err) {triggerAfterCompletion (processedRequest, response, mappedHandler, new NestedServletException ("Handler processing failed", err)) } finally {if (asyncManager.isConcurrentHandlingStarted ()) {/ / Instead of postHandle and afterCompletion if (mappedHandler! = null) {mappedHandler.applyAfterConcurrentHandlingStarted (processedRequest, response);}} else {/ / Clean up any resources used by a multipart request. If (multipartRequestParsed) {cleanupMultipart (processedRequest);}

Enter the place of exception handling

When you go to the resolveException method, there are three default parsers. The specific instantiation of ExceptionHandlerExceptionResolver,ResponseStatusExceptionResolver,DefaultHandlerExceptionResolver; is in the WebMvcConfigurationSupport#addDefaultHandlerExceptionResolvers method.

Protected final void addDefaultHandlerExceptionResolvers (List exceptionResolvers) {ExceptionHandlerExceptionResolver exceptionHandlerResolver = createExceptionHandlerExceptionResolver (); exceptionHandlerResolver.setContentNegotiationManager (mvcContentNegotiationManager ()); exceptionHandlerResolver.setMessageConverters (getMessageConverters ()); exceptionHandlerResolver.setCustomArgumentResolvers (getArgumentResolvers ()); exceptionHandlerResolver.setCustomReturnValueHandlers (getReturnValueHandlers ()); if (jackson2Present) {exceptionHandlerResolver.setResponseBodyAdvice (Collections. HandlerType) {for (Method method: MethodIntrospector.selectMethods (handlerType, EXCEPTION_HANDLER_METHODS)) {for (Class messageConverter: this.messageConverters) {if (messageConverter instanceof GenericHttpMessageConverter) {if (GenericHttpMessageConverter) messageConverter). CanWrite (declaredType, valueType, selectedMediaType)) {outputValue = (T) getAdvice (). BeforeBodyWrite (outputValue, returnType, selectedMediaType) (Class >) messageConverter.getClass (), inputMessage, outputMessage) If (outputValue! = null) {addContentDispositionHeader (inputMessage, outputMessage); ((GenericHttpMessageConverter) messageConverter) .write (outputValue, declaredType, selectedMediaType, outputMessage) If (logger.isDebugEnabled ()) {logger.debug ("Written [" + outputValue + "] as\"+ selectedMediaType +"\ "using [" + messageConverter + "]");} return } else if (messageConverter.canWrite (valueType, selectedMediaType)) {outputValue = (T) getAdvice (). BeforeBodyWrite (outputValue, returnType, selectedMediaType, (Class >) messageConverter.getClass (), inputMessage, outputMessage) If (outputValue! = null) {addContentDispositionHeader (inputMessage, outputMessage); ((HttpMessageConverter) messageConverter) .write (outputValue, selectedMediaType, outputMessage) If (logger.isDebugEnabled ()) {logger.debug ("Written [" + outputValue + "] as\"+ selectedMediaType +"\ "using [" + messageConverter + "]");} return }} if (outputValue! = null) {throw new HttpMediaTypeNotAcceptableException (this.allSupportedMediaTypes);}}

Before body writer, ResponseBodyAdvice match is called to do a layer of processing, that is to say,

@ RestControllerAdvicepublic class GlobalExceptionHandler extends ResponseEntityExceptionHandler implements ResponseBodyAdvice {} the above is how to handle exceptions using @ RestControllerAdvice. The editor believes that there are some knowledge points that we may see or use in our daily work. I hope you can learn more from this article. For more details, please follow the industry information channel.

Tags: Processing methods annotations places more knowledge articles e.g.practical that is portals instances that is work meetings interfaces articles times messages look. Apple Docker Huawei Linux macOS MariaDB Microsoft MySQL NVidia OPPO Reno Xiaomi vpn Shulou Tech Info OPPO Reno MariaDB