{"id":996,"date":"2012-05-06T15:04:37","date_gmt":"2012-05-06T13:04:37","guid":{"rendered":"http:\/\/doanduyhai.wordpress.com\/?p=996"},"modified":"2012-05-06T15:04:37","modified_gmt":"2012-05-06T13:04:37","slug":"spring-mvc-part-v-exception-handling","status":"publish","type":"post","link":"https:\/\/www.doanduyhai.com\/blog\/?p=996","title":{"rendered":"Spring MVC part V: Exception handling"},"content":{"rendered":"<p>Today we&#8217;ll dig into the exception handling mechanism of <strong>Spring MVC 3.1<\/strong><\/p>\n<p><!--more--><\/p>\n<blockquote><p>All the code mentioned in this article is based on <strong>Spring MVC 3.1<\/strong>. If you are using previous version of Spring MVC some assertions may not hold.<\/p><\/blockquote>\n<blockquote><p>Please note that all the examples in this post can be found in a demo application on GitHub <a title=\"Spring MVC Exception Handling Demo\" href=\"https:\/\/github.com\/doanduyhai\/SpringMVCExceptionGHandling\" target=\"_blank\">https:\/\/github.com\/doanduyhai\/SpringMVCExceptionGHandling<\/a><\/p><\/blockquote>\n<p>&nbsp;<\/p>\n<h1>I Exception handling infrastructure<\/h1>\n<h3>A Main classes<\/h3>\n<p> To manage exceptions, Spring MVC 3.1 offers by default the following classes:<\/p>\n<ul>\n<li><strong>ExceptionHandlerExceptionResolver<\/strong>: generic exception handler<\/li>\n<li><strong>DefaultHandlerExceptionResolver<\/strong>: exception handler supporting a set of predefined exceptions<\/li>\n<li><strong>SimpleMappingExceptionResolver<\/strong>: good old exception handler (available since 2003!) to map a custom exception to a specific error page<\/li>\n<\/ul>\n<p> It is possible to use those 3 handlers, all we need to do is to declare a <strong>HandlerExceptionResolverComposite<\/strong> which is basically a container of Exception handlers and delegates the exception handling to each of the registered handler.<\/p>\n<pre class=\"brush: xml; title: ; wrap-lines: false; notranslate\" title=\"\">\n\t&amp;lt;bean id=&amp;quot;compositeExceptionResolver&amp;quot; class=&amp;quot;org.springframework.web.servlet.handler.HandlerExceptionResolverComposite&amp;quot;&amp;gt;\n\t\t&amp;lt;property name=&amp;quot;exceptionResolvers&amp;quot;&amp;gt;\n\t\t\t&amp;lt;list&amp;gt;\n  \t\t\t\t&amp;lt;bean class=&amp;quot;exceptionHandler1&amp;quot;\/&amp;gt;\n  \t\t\t\t&amp;lt;bean class=&amp;quot;exceptionHandler2&amp;quot;\/&amp;gt;\n  \t\t\t\t&amp;lt;bean class=&amp;quot;...&amp;quot;\/&amp;gt;\n  \t\t\t&amp;lt;\/list&amp;gt;\n\t\t&amp;lt;\/property&amp;gt;\n\t\t&amp;lt;property name=&amp;quot;order&amp;quot; value=&amp;quot;0&amp;quot;\/&amp;gt;\n\t&amp;lt;\/bean&amp;gt;\n<\/pre>\n<p>With this configuration, each exception handler wil be invoked <strong>with respect to their declaration order<\/strong> (a list is ordered by nature)<\/p>\n<p>&nbsp;<\/p>\n<h3>B Detailed description<\/h3>\n<h5><strong>1) ExceptionHandlerExceptionResolver<\/strong><\/h5>\n<p> This exception handler is the default handler and covers 80% of the use cases. On startup the class is registered in the Spring context with a set of default method argument resolvers and method return values handlers:<\/p>\n<p>Default argument resolvers<\/p>\n<ul>\n<li><strong>ServletRequestMethodArgumentResolver<\/strong>: supports the following types as method arguments\n<ul>\n<li>WebRequest<\/li>\n<li>ServletRequest<\/li>\n<li>MultipartRequest<\/li>\n<li>HttpSession<\/li>\n<li>Principal (for security)<\/li>\n<li>Locale<\/li>\n<li>InputStream<\/li>\n<li>Reader<\/li>\n<\/ul>\n<\/li>\n<li><strong>ServletResponseMethodArgumentResolver<\/strong>: supports the following types as method arguments\n<ul>\n<li>ServletResponse<\/li>\n<li>OutputStream<\/li>\n<li>Writer<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>In addition to these method arguments, this handler also handle the following return types and method annotations:<\/p>\n<ul>\n<li><strong>Return types<\/strong>:\n<ul>\n<li>ModelAndView<\/li>\n<li>Model<\/li>\n<li>View<\/li>\n<li>String: simple view name return<\/li>\n<li>Map<\/li>\n<li>HttpEntity: to customize Http request body as well as header<\/li>\n<\/ul>\n<\/li>\n<li><strong>Annotations<\/strong>:\n<ul>\n<li>@ModelAttribute<\/li>\n<li>@RequestBody<\/li>\n<li>@ResponseBody<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h5><strong>2) DefaultHandlerExceptionResolver<\/strong><\/h5>\n<p>This class simply handles the following default exceptions:<\/p>\n<p>&nbsp;<\/p>\n<div style=\"text-align:center;margin:auto;\">\n<table style=\"width:80%;margin:auto;border:thin;border-collapse:collapse;\">\n<thead>\n<tr>\n<td style=\"text-align:center;\"><strong>Exception<\/strong><\/td>\n<td style=\"text-align:center;\"><strong>Http Code<\/strong><\/td>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><strong>NoSuchRequestHandlingMethodException<\/strong><\/td>\n<td>404 (Not Found)<\/td>\n<\/tr>\n<tr>\n<td><strong>HttpRequestMethodNotSupportedException<\/strong><\/td>\n<td>405 (Method Not Allowed)<\/td>\n<\/tr>\n<tr>\n<td><strong>HttpMediaTypeNotSupportedException<\/strong><\/td>\n<td>415 (Unsupported Media Type)<\/td>\n<\/tr>\n<tr>\n<td><strong>MissingServletRequestParameterException<\/strong><\/td>\n<td>400 (Bad Request)<\/td>\n<\/tr>\n<tr>\n<td><strong>ServletRequestBindingException<\/strong><\/td>\n<td>400 (Bad Request)<\/td>\n<\/tr>\n<tr>\n<td><strong>ConversionNotSupportedException<\/strong><\/td>\n<td>500 (Internal Server Error)<\/td>\n<\/tr>\n<tr>\n<td><strong>TypeMismatchException<\/strong><\/td>\n<td>400 (Bad Request)<\/td>\n<\/tr>\n<tr>\n<td><strong>HttpMessageNotReadableException<\/strong><\/td>\n<td>400 (Bad Request)<\/td>\n<\/tr>\n<tr>\n<td><strong>HttpMessageNotWritableException<\/strong><\/td>\n<td>500 (Internal Server Error)<\/td>\n<\/tr>\n<tr>\n<td><strong>MethodArgumentNotValidException<\/strong><\/td>\n<td>400 (Bad Request)<\/td>\n<\/tr>\n<tr>\n<td><strong>MissingServletRequestPartException<\/strong><\/td>\n<td>400 (Bad Request)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p> You need not declare any method with <strong>@ExceptionHandler<\/strong> for the above exceptions, they will be handled automatically by the class.<\/p>\n<p>&nbsp;<\/p>\n<h5><strong>3) SimpleMappingExceptionResolver<\/strong><\/h5>\n<p>&nbsp;<br \/>\n This class lets you map an exception to an view. Simply define its &#8220;exceptionMappings&#8221; property by providing a list of exception\/view pair values:<\/p>\n<pre class=\"brush: xml; title: ; wrap-lines: false; notranslate\" title=\"\">\n&amp;lt;bean class=&amp;quot;org.springframework.web.servlet.handler.SimpleMappingExceptionResolver&amp;quot;&amp;gt;\n\t&amp;lt;property name=&amp;quot;exceptionMappings&amp;quot;&amp;gt;\n\t\t&amp;lt;props&amp;gt;\n\t\t\t&amp;lt;prop key=&amp;quot;java.lang.ClassNotFoundException&amp;quot;&amp;gt;pages\/classNotFoundException&amp;lt;\/prop&amp;gt;\n\t\t\t&amp;lt;prop key=&amp;quot;java.lang.CloneNotSupportedException&amp;quot;&amp;gt;pages\/cloneNotSupportedException&amp;lt;\/prop&amp;gt;\n\t\t&amp;lt;\/props&amp;gt;\n\t&amp;lt;\/property&amp;gt;\n&amp;lt;\/bean&amp;gt;\n<\/pre>\n<p> Above, we map the <strong>ClassNotFoundException<\/strong> to the view &#8220;<em>pages\/classNotFoundException<\/em>&#8221; and <strong>CloneNotSupportedException<\/strong> to &#8220;<em>pages\/cloneNotSupportedException<\/em>&#8220;. Of course you must ensure that the view declaration is correct and the actual pages exist.<\/p>\n<p>&nbsp;<\/p>\n<h1>II Exception handling strategies<\/h1>\n<p> In this chapter we discuss about various strategies to handle exceptions.<\/p>\n<h3>A Return an error message to be displayed<\/h3>\n<p> This is the simplest use case for exception handling:<\/p>\n<pre class=\"brush: java; title: ; wrap-lines: false; notranslate\" title=\"\">\n@RequestMapping(value = &amp;quot;rest\/exception1&amp;quot;)\npublic String exception1()\n{\n\tthrow new NullPointerException(&amp;quot;Exception1 as plain text with &amp;lt;strong&amp;gt;html&amp;lt;\/strong&amp;gt; tags&amp;quot;);\n}\n\n@ExceptionHandler(NullPointerException.class)\n@ResponseBody\npublic String handleException1(NullPointerException ex)\n{\n\treturn ex.getMessage();\n}\n<\/pre>\n<p>Above, on <strong>NullPointerException<\/strong> detection, we return the source message. Since the handler method is annotated with <strong>@ResponseBody<\/strong>, the source message will be simply put in the response body.<\/p>\n<p> On the client side, some Javascript to display an error panel with the message:<\/p>\n<pre class=\"brush: jscript; highlight: [6]; title: ; wrap-lines: false; notranslate\" title=\"\">\nfunction exception1()\n{\n\t$.ajax({\n\t\ttype: 'GET',\n\t\turl: &amp;quot;rest\/exception1&amp;quot;,\n        success: function(data)\n        {\n        \t$('#messagePanel').empty().html(data).show();\n        }\n    });\n\t\n\treturn false;\n}\n<\/pre>\n<p> Please notice that the returned exception message is handled by a <strong>success function (line 6)<\/strong> in Javascript. Indeed even if an Exception occured at the server side, <strong>as long as the Http response status is 200 the client side will consider it as a success<\/strong>.<\/p>\n<p><a href=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/springmvcexceptionhandling-exception11.png\"><img loading=\"lazy\" src=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/springmvcexceptionhandling-exception11.png\" alt=\"springmvcexceptionhandling-exception1\" title=\"springmvcexceptionhandling-exception1\" width=\"361\" height=\"45\" class=\"aligncenter size-full wp-image-1036\" srcset=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/springmvcexceptionhandling-exception11.png 361w, https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/springmvcexceptionhandling-exception11-300x37.png 300w\" sizes=\"(max-width: 361px) 100vw, 361px\" \/><\/a><br \/>\n&nbsp;<\/p>\n<h3>B Return a dedicated error page<\/h3>\n<p> This strategy simply returns a generic error page and hides all the exception details from the end user.<\/p>\n<pre class=\"brush: java; highlight: [10]; title: ; wrap-lines: false; notranslate\" title=\"\">\n@RequestMapping(value = &amp;quot;http\/exception2&amp;quot;, method = RequestMethod.GET)\npublic String exception2()\n{\n\tthrow new IndexOutOfBoundsException();\n}\n\n@ExceptionHandler(IndexOutOfBoundsException.class)\npublic String handleException2(IndexOutOfBoundsException ex)\n{\n\treturn &amp;quot;pages\/errorPage&amp;quot;;\n}\n<\/pre>\n<p> Please note that <strong>there is no redirect<\/strong>, we simply render a generic error page instead of the normal target page.<\/p>\n<p><a href=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/springmvcexceptionhandling-exception2.png\"><img loading=\"lazy\" src=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/springmvcexceptionhandling-exception2.png\" alt=\"\" title=\"springmvcexceptionhandling-exception2\" width=\"379\" height=\"69\" class=\"aligncenter size-full wp-image-1020\" srcset=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/springmvcexceptionhandling-exception2.png 379w, https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/springmvcexceptionhandling-exception2-300x55.png 300w\" sizes=\"(max-width: 379px) 100vw, 379px\" \/><\/a><br \/>\n&nbsp;<\/p>\n<h3>C Return an error code with custom message<\/h3>\n<p>In this strategy, we let Spring build an generic error page based on the Http code we provide with a custom message.<\/p>\n<pre class=\"brush: java; highlight: [7]; title: ; wrap-lines: false; notranslate\" title=\"\">\n@RequestMapping(value = &amp;quot;http\/exception3&amp;quot;, method = RequestMethod.GET)\npublic String exception3()\n{\n\tthrow new IllegalStateException(&amp;quot;Exception3 with response status&amp;quot;);\n}\n@ExceptionHandler(IllegalStateException.class)\n@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR, reason = &amp;quot;exception3&amp;quot;)\npublic void handleException3(IllegalStateException ex, HttpServletResponse response) throws IOException\n{\n\n}\n<\/pre>\n<p> Please note the definition of Http code and custom error message with the <strong>@ResponseStatus<\/strong> annotation at <strong>line 7<\/strong>. This strategy is quite equivalent to defining the error page at <strong>servlet level<\/strong> in the <strong>web.xml<\/strong>:<\/p>\n<pre class=\"brush: xml; title: ; wrap-lines: false; notranslate\" title=\"\">\n &amp;lt;error-page&amp;gt;\n\t&amp;lt;error-code&amp;gt;404&amp;lt;\/error-code&amp;gt;\n\t&amp;lt;location&amp;gt;\/pages\/404.html&amp;lt;\/location&amp;gt;\n  &amp;lt;\/error-page&amp;gt;\n<\/pre>\n<p> The result:<br \/>\n<a href=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/springmvcexceptionhandling-exception3.png\"><img loading=\"lazy\" src=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/springmvcexceptionhandling-exception3.png\" alt=\"springmvcexceptionhandling-exception3\" title=\"springmvcexceptionhandling-exception3\" width=\"465\" height=\"111\" class=\"aligncenter size-full wp-image-1024\" srcset=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/springmvcexceptionhandling-exception3.png 465w, https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/springmvcexceptionhandling-exception3-300x72.png 300w\" sizes=\"(max-width: 465px) 100vw, 465px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<h3>D Redirect to a custom page with custom error message<\/h3>\n<p>In this strategy, we do a real HTTP redirect to a custom error page with a custom error message.<\/p>\n<pre class=\"brush: java; highlight: [11,16]; title: ; wrap-lines: false; notranslate\" title=\"\">\n@RequestMapping(value = &amp;quot;http\/exception4&amp;quot;, method = RequestMethod.GET)\npublic String exception4() throws FunctionalException\n{\n\tthrow new FunctionalException(&amp;quot;Functional exception&amp;quot;);\n}\n\n@ExceptionHandler(FunctionalException.class)\npublic RedirectView handleException4(FunctionalException ex, HttpServletRequest request) throws IOException\n{\n\tRedirectView redirectView = new RedirectView(&amp;quot;..\/errorRedirectPage&amp;quot;);\n\tredirectView.addStaticAttribute(&amp;quot;errorMessage&amp;quot;, ex.getMessage());\n\treturn redirectView;\n}\n\n@RequestMapping(value = &amp;quot;errorRedirectPage&amp;quot;)\npublic String errorRedirectPage(HttpServletRequest request, Model model, @RequestParam(&amp;quot;errorMessage&amp;quot;) String errorMessage)\n{\n\tmodel.addAttribute(&amp;quot;errorMessage&amp;quot;, errorMessage);\n\treturn &amp;quot;pages\/errorRedirectPage&amp;quot;;\n}\n<\/pre>\n<p> The above code has some hacks. First in the exception handler we put the error message as static attribute of the redirect view object (<strong>line 11<\/strong>). It will end up being appended in the query string:<\/p>\n<p> <em>errorRedirectPage?errorMessage=xxxx<\/em><\/p>\n<p> Then in the error message method handler, we extract it from the query with <strong>@RequestParam(&#8220;errorMessage&#8221;)<\/strong>  (<strong>line 16<\/strong>)and put it back into the model object.<\/p>\n<p> Why such a hack ? Why don&#8217;t we use the <strong>RedirectAttribute<\/strong> map that exists in <strong>Spring MVC 3.1<\/strong> ? Simply because the <strong>ExceptionHandlerExceptionResolver<\/strong> class does not support this method argument.<\/p>\n<p> Of course we could have added the <strong>RedirectAttributesMethodArgumentResolver<\/strong> as <strong>custom argument resolver<\/strong> but it would require a <strong>binderFactory<\/strong> (<a href=\"http:\/\/grepcode.com\/file\/repository.springsource.com\/org.springframework\/org.springframework.web.servlet\/3.1.0\/org\/springframework\/web\/servlet\/mvc\/method\/annotation\/RedirectAttributesMethodArgumentResolver.java#53\" title=\"RedirectAttributesMethodArgumentResolver:53\" target=\"_blank\">RedirectAttributesMethodArgumentResolver:53<\/a>) and the current infrastructure of <strong>ExceptionHandlerExceptionResolver<\/strong> does not support.<\/p>\n<p><a href=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/springmvcexceptionhandling-exception4.png\"><img loading=\"lazy\" src=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/springmvcexceptionhandling-exception4.png\" alt=\"\" title=\"springmvcexceptionhandling-exception4\" width=\"585\" height=\"169\" class=\"aligncenter size-full wp-image-1030\" srcset=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/springmvcexceptionhandling-exception4.png 585w, https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/springmvcexceptionhandling-exception4-300x87.png 300w\" sizes=\"(max-width: 585px) 100vw, 585px\" \/><\/a><br \/>\n&nbsp;<\/p>\n<h3>E Return an exception wrapper object in JSON format, AJAX response<\/h3>\n<p>In this strategy, we return an exception wrapper object serialized with JSON format back to the client<\/p>\n<pre class=\"brush: java; highlight: [8,9]; title: ; wrap-lines: false; notranslate\" title=\"\">\n@RequestMapping(value = &amp;quot;rest\/exception5&amp;quot;, method = RequestMethod.GET)\npublic String exception5(HttpSession session)\n{\n\tthrow new IllegalArgumentException(&amp;quot;Test exception 5 with ExceptionVO as JSON data&amp;quot;);\n}\n\n@ExceptionHandler(IllegalArgumentException.class)\n@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)\n@ResponseBody\npublic ExceptionVO handleException5(IllegalArgumentException ex, HttpServletResponse response) throws IOException\n{\n\tExceptionVO exceptionVO = new ExceptionVO(&amp;quot;handleException5()&amp;quot;, &amp;quot;HomeController&amp;quot;, ex.getMessage());\n\n\treturn exceptionVO;\n\n}\n<\/pre>\n<p> To achieve this, we need to add a <strong>@ResponseBody<\/strong> annotation to the exception handler method but also a <strong>@ResponseStatus<\/strong> annotation to send an Http error code.<\/p>\n<p> Unlike the strategy described at <strong>A<\/strong>, in this case <strong>we want to trigger the error listener at client-side<\/strong> so we need to send back an Http status other than 200.<\/p>\n<pre class=\"brush: jscript; highlight: [6,9]; title: ; wrap-lines: false; notranslate\" title=\"\">\nfunction exception5()\n{\n\t$.ajax({\n\t\ttype: 'GET',\n\t\turl: &amp;quot;rest\/exception5&amp;quot;,\n\t\tdataType: 'application\/json; charset=UTF-8',\n\t\terror: function(jqXHR, textStatus, errorThrown) \n\t\t{\n\t\t\tvar exceptionVO = jQuery.parseJSON(jqXHR.responseText);\n\t\t   \n\t\t\t$('#errorModal')\n\t\t\t.find('.modal-header h3').html(jqXHR.status+' error').end()\n\t\t\t.find('.modal-body p&amp;gt;strong').html(exceptionVO.clazz).end()\n\t\t\t.find('.modal-body p&amp;gt;em').html(exceptionVO.method).end()\n\t\t\t.find('.modal-body p&amp;gt;span').html(exceptionVO.message).end()\n\t\t\t.modal('show');\n\t\t   \n\t\t}\n    });\n\t\n\treturn false;\n}\n<\/pre>\n<p> In the error handler function, we need to extract the exception wrapper object from the body of the returned page (<strong>jqXHR.responseText, line 9<\/strong>) and convert it to an JSON object.<\/p>\n<p> Next we can extract various exception information from the wrapper object and display them in a modal panel. The way to display the error details is up to you (modal panel, custom message box &#8230;)<\/p>\n<p><a href=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/springmvcexceptionhandling-exception5.png\"><img loading=\"lazy\" src=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/springmvcexceptionhandling-exception5.png\" alt=\"springmvcexceptionhandling-exception5\" title=\"springmvcexceptionhandling-exception5\" width=\"582\" height=\"166\" class=\"aligncenter size-full wp-image-1034\" srcset=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/springmvcexceptionhandling-exception5.png 582w, https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/springmvcexceptionhandling-exception5-300x86.png 300w\" sizes=\"(max-width: 582px) 100vw, 582px\" \/><\/a><br \/>\n&nbsp;<\/p>\n<h1>III Demo application<\/h1>\n<p> The demo application can be found on GitHub at <a href=\"https:\/\/github.com\/doanduyhai\/SpringMVCExceptionGHandling\" title=\"SpringMVCExceptionHandling\" target=\"_blank\">https:\/\/github.com\/doanduyhai\/SpringMVCExceptionGHandling<\/a><\/p>\n<p> The main demo page displays a list of buttons to trigger an exception. There is one button for each exception handling strategy described above.<\/p>\n<p> I also added some test cases for the <strong>DefaultHandlerExceptionResolver<\/strong> and <strong>SimpleMappingExceptionResolver<\/strong> handlers.<\/p>\n<p><a href=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/springmvcexceptionhandling-demo.png\"><img loading=\"lazy\" src=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/springmvcexceptionhandling-demo.png\" alt=\"springmvcexceptionhandling-demo\" title=\"springmvcexceptionhandling-demo\" width=\"630\" height=\"809\" class=\"aligncenter size-full wp-image-1039\" srcset=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/springmvcexceptionhandling-demo.png 632w, https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/springmvcexceptionhandling-demo-233x300.png 233w\" sizes=\"(max-width: 630px) 100vw, 630px\" \/><\/a><\/p>\n<p>&nbsp;<br \/>\n&nbsp;<br \/>\n&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today we&#8217;ll dig into the exception handling mechanism of Spring MVC 3.1<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[14,31,19],"tags":[],"_links":{"self":[{"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/996"}],"collection":[{"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=996"}],"version-history":[{"count":0,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/996\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=996"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=996"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=996"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}