目录
- Spring REST:异常处理卷。 1个
- Spring REST:异常处理卷。 2
- Spring REST:异常处理卷。 3
大家好,是时候继续在我的博客中发布新文章了。 因此,我很高兴地宣布,我计划编写一系列技术文章。 在当前文章中,我将开始讨论Spring REST Exception处理。 Spring向我们建议了REST异常处理的几种方法,但我想将您的注意力集中在其中两种方法上:
- @Controller级别的@ExceptionHandler
- @ControllerAdvice级别上的@ExceptionHandler
所有代码示例都将使用我在之前有关REST服务的文章中使用的应用程序开发。 JQuery将在客户端提供与REST服务的交互。
因此,在简要介绍之后,我要进行总结。 我们将考虑REST异常处理程序的三个示例。 这三种情况中的每一种都将描述在任何项目中可能发生的某些实际情况的解决方案。 所有开发将在已经存在的应用程序之上进行。
制备
我想做的第一件事–是将 MessageSource 添加到应用程序中。 这不是很难,我不想在此停止详细介绍,因为我已经在另一篇文章中解释了如何执行此操作。 MessageSource的目的是存储错误消息,如果抛出异常,我想返回给客户端。
因此,这是一个messages.properties文件:
error.bad.smartphone.id = Smartphone can't have id:
成功添加MessageSource之后,我们可以在@Controller级别继续进行异常处理。
异常处理
在这一段中,我想重点介绍可能发生异常的代码段。 让我们检查来自SmartphoneController的一些方法。
...@RequestMapping(value="/edit/{id}", method=RequestMethod.GET)public ModelAndView editSmartphonePage(@PathVariable int id) {ModelAndView mav = new ModelAndView("phones/edit-phone");Smartphone smartphone = smartphoneService.get(id);mav.addObject("sPhone", smartphone);return mav;}
...@RequestMapping(value="/edit/{id}", method=RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE,consumes = MediaType.APPLICATION_JSON_VALUE)@ResponseBodypublic Smartphone editSmartphone(@PathVariable int id, @Valid @RequestBody Smartphone smartphone) {smartphone.setId(id);return smartphoneService.update(smartphone);}
...@RequestMapping(value="/delete/{id}", method=RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_VALUE,consumes = MediaType.APPLICATION_JSON_VALUE)@ResponseBodypublic Smartphone deleteSmartphone(@PathVariable int id) {return smartphoneService.delete(id);}
...
这三种方法具有一个共同的功能– @PathVariable int id 。 这种情况很重要,因为Spring文档说,如果不能将使用@PathVariable注释的方法参数强制转换为指定的类型(在我们的示例中为int),则它将作为String公开。 因此,它可能导致TypeMismatchException 。
为了解决这个问题,我将在@Controller级别使用@ExceptionHandler批注。 这种方法最适合这种情况。 我只需要在SmartphoneController中进行2处更改:
- 添加MessageSource字段
- 添加异常处理程序方法
...@Autowiredprivate MessageSource messageSource;
...@ExceptionHandler(TypeMismatchException.class)@ResponseStatus(value=HttpStatus.NOT_FOUND)@ResponseBodypublic ErrorInfo handleTypeMismatchException(HttpServletRequest req, TypeMismatchException ex) {Locale locale = LocaleContextHolder.getLocale();String errorMessage = messageSource.getMessage("error.bad.smartphone.id", null, locale);errorMessage += ex.getValue();String errorURL = req.getRequestURL().toString();return new ErrorInfo(errorURL, errorMessage);}
...
让我们考虑一下方法。 @ExceptionHandler批注具有参数– TypeMismatchException ,这意味着在发生异常时将触发该方法。 @ResponseStatus批注用于指定特定的响应状态代码。
您可能已经注意到该方法返回ErrorInfo。 这很容易,因为它是任何类型的错误的类,需要通知客户有关错误原因的信息。 因此,该类如下所示:
public class ErrorInfo {private String url;private String message;public ErrorInfo(String url, String message) {this.url = url;this.message = message;}//Getters and setters are omitted}
此类的使用为我们提供了两个主要优点:我们可以提供引起异常的URL,并且可以提供适当的错误消息。
现在,让我们尝试看看当我尝试访问某些ID不可接受的URL时遇到的情况。
您可以在屏幕截图上看到,我在@Controller级别上指定的ID错误的URL已得到处理。 在下一篇文章中,我将讨论一些可以放在@ControllerAdvice级别的异常。
翻译自: https://www.javacodegeeks.com/2013/12/spring-rest-exception-handling-vol-1.html