当前位置:首页 > 服务端 > SPRING IN ACTION 第4版笔记-第七章Advanced Spring MVC-005- 异常处理@ResponseStatus、@ExceptionHandler、@ControllerAdvice

SPRING IN ACTION 第4版笔记-第七章Advanced Spring MVC-005- 异常处理@ResponseStatus、@ExceptionHandler、@ControllerAdvice

No matter what happens, good or bad, the outcome of a servlet request is a servlet response. If an exception occurs during request processing, the outcome is still a servlet response. Somehow, the exception must be translated into a response.

Spring offers a handful of ways to translate exceptions to responses:
 Certain Spring exceptions are automatically mapped to specific HTTP status codes.
 An exception can be annotated with @ResponseStatus to map it to an HTTP status code.
 A method can be annotated with @ExceptionHandler to handle the exception.

 

一、利用HTTP status codes的便利性

1.让Spring自动匹配Spring的自定义异常

SPRING IN ACTION 第4版笔记-第七章Advanced Spring MVC-005- 异常处理@ResponseStatus、@ExceptionHandler、@ControllerAdvice _ JavaClub全栈架构师技术笔记

 

The exceptions in table 7.1 are usually thrown by Spring itself as the result of something going wrong in DispatcherServlet or while performing validation. For example, if DispatcherServlet can’t find a controller method suitable to handle a request,a NoSuchRequestHandlingMethodException will be thrown, resulting in a response
with a status code of 404 (Not Found).

2.自己来匹配

(1)假设consider the following request-handling method from SpittleController that could result in an HTTP 404 status (but doesn’t):

 1   @RequestMapping(value="/{spittleId}", method=RequestMethod.GET)
 2   public String spittle(
 3       @PathVariable("spittleId") long spittleId, 
 4       Model model) {
 5     Spittle spittle = spittleRepository.findOne(spittleId);
 6     if (spittle == null) {
 7       throw new SpittleNotFoundException();
 8     }
 9     model.addAttribute(spittle);
10     return "spittle";
11   }

if findOne() returns null , then a SpittleNotFoundException is thrown. For now, SpittleNotFoundException is a simple unchecked exception that looks like this:

package spittr.web;

public class SpittleNotFoundException extends RuntimeException {}

If the spittle() method is called on to handle a request, and the given ID comes up empty, the SpittleNotFoundException will (by default) result in a response with a 500 (Internal Server Error) status code. In fact, in the event of any exception that isn’t otherwise mapped, the response will always have a 500 status code. But you can change that by mapping SpittleNotFoundException otherwise.
When SpittleNotFoundException is thrown, it’s a situation where a requested resource isn’t found. The HTTP status code of 404 is precisely the appropriate response status code when a resource isn’t found. So, let’s use @ResponseStatus to
map SpittleNotFoundException to HTTP status code 404.

1 package spittr.web;
2 
3 import org.springframework.http.HttpStatus;
4 import org.springframework.web.bind.annotation.ResponseStatus;
5 
6 @ResponseStatus(value=HttpStatus.NOT_FOUND, reason="Spittle Not Found")
7 public class SpittleNotFoundException extends RuntimeException {
8 
9 }

After introducing this @ResponseStatus annotation, if a SpittleNotFoundException were to be thrown from a controller method, the response would have a status code of 404 and a reason of Spittle Not Found.

运行结果:

SPRING IN ACTION 第4版笔记-第七章Advanced Spring MVC-005- 异常处理@ResponseStatus、@ExceptionHandler、@ControllerAdvice _ JavaClub全栈架构师技术笔记

二、在controller级别处理异常@ExceptionHandler

1.自定义异常

package spittr.web;

public class DuplicateSpittleException extends RuntimeException {

}

 

2.抛出异常

suppose that SpittleRepository ’s save() method throws a DuplicateSpittleException if a user attempts to create a Spittle with text identical to one they’ve already created. That means the saveSpittle() method of SpittleController might need to deal with that exception. As shown in the following listing,saveSpittle() could directly handle the exception.

 1 @RequestMapping(method = RequestMethod.POST)
 2 public String saveSpittle(SpittleForm form, Model model) {
 3     try {
 4         spittleRepository.save(
 5             new Spittle(null, form.getMessage(), new Date(),
 6                 form.getLongitude(), form.getLatitude()));
 7         return "redirect:/spittles";
 8     } catch (DuplicateSpittleException e) {
 9         return "error/duplicate";
10     }
11 }

It works fine, but the method is a bit complex. Two paths can be taken, each with a different outcome. It’d be simpler if saveSpittle() could focus on the happy path and let some other method deal with the exception.First, let’s rip the exception-handling code out of saveSpittle() :很怀疑这里是不是会自己抛出异常DuplicateSpittleException,当保存的id重复时????

1 @RequestMapping(method = RequestMethod.POST)
2 public String saveSpittle(SpittleForm form, Model model) {
3     spittleRepository.save(
4         new Spittle(null, form.getMessage(), new Date(),
5             form.getLongitude(), form.getLatitude()));
6     return "redirect:/spittles";
7 }

Now let’s add a new method to SpittleController that will handle the case where DuplicateSpittleException is thrown:

@ExceptionHandler(DuplicateSpittleException.class)
public String handleDuplicateSpittle() {
    return "error/duplicate";
}

If @ExceptionHandler methods can handle exceptions thrown from any handler method in the same controller class, you might be wondering if there’s a way they can handle exceptions thrown from handler methods in any controller. As of Spring 3.2 they certainly can, but only if they’re defined in a controller advice class.

 

三、在application级别处理异常@ControllerAdvice

A controller advice is
any class that’s annotated with @ControllerAdvice and has one or more of the following kinds of methods:
 @ExceptionHandler -annotated
 @InitBinder -annotated
 @ModelAttribute -annotated
Those methods in an @ControllerAdvice -annotated class are applied globally across all @RequestMapping -annotated methods on all controllers in an application.
The @ControllerAdvice annotation is itself annotated with @Component . Therefore,an @ControllerAdvice -annotated class will be picked up by component-scanning, just like an @Controller -annotated class.

处理应用中所有异常

 1 package spittr.web;
 2 
 3 import org.springframework.web.bind.annotation.ControllerAdvice;
 4 import org.springframework.web.bind.annotation.ExceptionHandler;
 5 
 6 @ControllerAdvice
 7 public class AppWideExceptionHandler {
 8 
 9   @ExceptionHandler(DuplicateSpittleException.class)
10   public String handleNotFound() {
11     return "error/duplicate";
12   }
13 
14 }

 

作者:shamgod
来源链接:https://www.cnblogs.com/shamgod/p/5246787.html

版权声明:
1、Java侠(https://www.javaxia.com)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。





本文链接:https://www.javaxia.com/server/125520.html

分享给朋友:

“SPRING IN ACTION 第4版笔记-第七章Advanced Spring MVC-005- 异常处理@ResponseStatus、@ExceptionHandler、@ControllerAdvice” 的相关文章