这是有关使用Spring进行REST异常处理的系列的第二篇文章。 在我以前的文章中,我描述了如何在REST服务中组织最简单的异常处理。 这次,我将更进一步,我将向您展示何时最好@ControllerAdvice级别使用异常处理

介绍

在开始本文的技术部分之前,我需要考虑一种情况,那就是我们最好在@ControllerAdvice级别上使用异常处理。
通常,一个控制器负责与一种类型的实体相关的整个逻辑。 就是说,如果我有一些EntityController类,它将包含与实体有关的所有CRUD(创建,读取,更新,删除)操作,如果需要的话,还可能包含一些额外的逻辑。 让我们检查三个操作:读取,更新,删除。

读取操作会根据ID(我们将其作为参数传递给它)返回一些特定的实体。 如果实体不存在,则读取操作将返回null。 更新/删除操作分别更新/删除特定实体。 这两个操作中的每一个都包含读取操作,因为在更新/删除实体之前,我们需要确保其存在于系统中。

在更新/删除操作过程中未找到实体时,应用程序将抛出EntityNotFoundException异常。 在这种情况下,异常处理将非常简单。 该应用程序必须将信息返回给客户端:

  • 响应标题:404
  • 导致异常的链接
  • 错误消息:没有ID为N的实体

对于此类异常,这是最简单的响应结构。 因此,无论您在一个应用程序中有多少个不同的实体类,因为您可以用相同的方式处理类似类型的异常(例如,没有此类实体)。 @ControllerAdvice批注使这成为可能。

@ControllerAdvice级别的异常处理

本文的实际部分将基于上一教程的申请表。

首先,我需要在message.properties文件中添加一条错误消息:

error.no.smartphone.id = There is no Smartphone with id:

之后,让我们看一下本文主题中对我们来说有趣的控制器方法。

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

这些方法包括SmartphoneService的调用。 而且SmartphoneService的实现包含可以引发SmartphoneNotFoundException的方法

@Service
@Transactional(rollbackFor = { SmartphoneNotFoundException.class })
public class SmartphoneServiceImpl implements SmartphoneService {@Autowiredprivate SmartphoneRepository smartphoneRepository;@Overridepublic Smartphone create(Smartphone sp) {return smartphoneRepository.save(sp);}@Overridepublic Smartphone get(Integer id) {Smartphone sp = null;if (id instanceof Integer)sp = smartphoneRepository.findOne(id);if (sp != null)return sp;throw new SmartphoneNotFoundException(id);}@Overridepublic List getAll() {return smartphoneRepository.findAll();}@Overridepublic Smartphone update(Smartphone sp) {Smartphone sPhoneToUpdate = get(sp.getId());sPhoneToUpdate.update(sp);return sPhoneToUpdate;}@Overridepublic Smartphone delete(Integer id) {Smartphone sPhone = get(id);smartphoneRepository.delete(id);return sPhone;}}

这是SmartphoneNotFoundException的代码:

public class SmartphoneNotFoundException extends RuntimeException {private static final long serialVersionUID = -2859292084648724403L;private final int smartphoneId;public SmartphoneNotFoundException(int id) {smartphoneId = id;}public int getSmartphoneId() {return smartphoneId;}}

最后,我可以移至@ControllerAdvice

@ControllerAdvice
public class RestExceptionProcessor {@Autowiredprivate MessageSource messageSource;@ExceptionHandler(SmartphoneNotFoundException.class)@ResponseStatus(value=HttpStatus.NOT_FOUND)@ResponseBodypublic ErrorInfo smartphoneNotFound(HttpServletRequest req, SmartphoneNotFoundException ex) {Locale locale = LocaleContextHolder.getLocale();String errorMessage = messageSource.getMessage("error.no.smartphone.id", null, locale);errorMessage += ex.getSmartphoneId();String errorURL = req.getRequestURL().toString();return new ErrorInfo(errorURL, errorMessage);}}

异常处理程序方法返回ErrorInfo对象。 您可以在上一则有关@Controller级别的异常处理的文章中了解有关它的更多信息。

这样,我们只需将额外的异常类添加到@ExceptionHandler批注中,就可以在一个地方收集所有类似的异常。 这种方法使整个应用程序内的代码维护更加容易。

示例说明:

注意:我发出了id值为356的请求,但是数据库中没有任何记录与此ID值相对应。 这种情况导致异常。

参考: Spring REST:异常处理卷。 2来自我们的JCG合作伙伴 Alexey Zvolinskiy,在Fruzenshtein的笔记博客中。

翻译自: https://www.javacodegeeks.com/2013/11/spring-rest-exception-handling-vol-2.html

Spring REST:异常处理卷。 2相关推荐

  1. Spring REST:异常处理卷。 1个

    目录 Spring REST:异常处理卷. 1个 Spring REST:异常处理卷. 2 Spring REST:异常处理卷. 3 大家好,是时候继续在我的博客中发布新文章了. 因此,我很高兴地宣布 ...

  2. Spring REST:异常处理卷。 3

    这是该系列中有关Spring REST异常处理的最后一篇文章. 最后,这次我将讨论在表单处理期间可能发生的REST异常的处理. 因此,在本教程中,您将看到与REST,表单和异常处理有关的所有内容. 客 ...

  3. rest spring_Spring REST:异常处理卷。 1个

    rest spring 目录 Spring REST:异常处理卷. 1个 Spring REST:异常处理卷. 2 Spring REST:异常处理卷. 3 大家好,是时候继续在我的博客中发布新文章了 ...

  4. rest spring_Spring REST:异常处理卷。 2

    rest spring 这是有关使用Spring进行REST异常处理的系列的第二篇文章. 在我以前的文章中,我描述了如何在REST服务中组织最简单的异常处理. 这次,我将更进一步,并向您展示何时最好在 ...

  5. rest spring_Spring REST:异常处理卷。 3

    rest spring 这是该系列中有关Spring REST异常处理的最后一篇文章. 最后,这次我将讨论在表单处理期间可能发生的REST异常的处理. 因此,在本教程中,您将看到与REST,表单和异常 ...

  6. Spring全局异常处理的三种方式

    在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的.不可预知的异常需要处理.每个过程都单独处理异常,系统的代码耦合度高,工作 ...

  7. Spring全局异常处理

    Spring全局异常处理 参考文章: (1)Spring全局异常处理 (2)https://www.cnblogs.com/snake23/p/10313612.html 备忘一下.

  8. java全局异常处理_详解Spring全局异常处理的三种方式

    在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的.不可预知的异常需要处理.每个过程都单独处理异常,系统的代码耦合度高,工作 ...

  9. Spring MVC异常处理 - @ ControllerAdvice,@ ExceptionHandler,HandlerExceptionResolver

    Spring MVC异常处理 - @ ControllerAdvice,@ ExceptionHandler,HandlerExceptionResolver Spring MVC异常处理对于确保您不 ...

最新文章

  1. 最新开源!TransReID:首个基于Transformer的ReID网络,各项任务全面领先!
  2. 祝「杭州程序媛」母亲节快乐!
  3. STM32使用串口IDLE中断的两种接收不定长数据的方式
  4. VTK:图片之ImageLuminance
  5. 苹果mac休眠快捷键_Mac技巧|如何高效使用苹果便笺?用便笺快捷键快速完成操作...
  6. android studio编译找不到程序包,【图片】哥哥们,android studio 打包的安装包手机无法识别怎么破【androidstudio吧】_百度贴吧...
  7. mysql先删后增并发时出现死锁_MySQL死锁案例分析一(先delete,再insert,导致死锁)...
  8. 用java创建窗口程序,创建窗口的应用程序
  9. SpringBoot 异常回滚 事务的使用___Springboot @Transactional 事务不回滚
  10. 《程序员代码面试指南》第二章 链表问题 反转部分单向链表
  11. Bootstrap 禁用某个菜单项
  12. MyQQ project
  13. Java扫码登录原理
  14. 弱监督学习和小目标检测
  15. 一篇读懂jvm垃圾回收
  16. CCED,一个时代的落幕
  17. 卸载python2_彻底卸载python
  18. 深度学习第19天_项目1_文本分类的介绍
  19. 大数据是人类福音还是洪水猛兽?
  20. huggingface.transformers任务简介

热门文章

  1. 【2】flink数据流转换算子
  2. http长/短轮询和WebSocket 的介绍和比较
  3. java分布式对象——远程方法中的参数和返回值+远程对象激活
  4. spring使用自定义注解_用Spring组成自定义注释
  5. jdk9与jdk11哪个好_JDK 9、10和11中的安全性增强
  6. 创建react应用程序_使用SpringWebFlux的React式Web应用程序
  7. java crud_Java 8流中的数据库CRUD操作
  8. 如何使用Java创建AWS Lambda函数
  9. java 8 集合分组_Java 8:按集合分组
  10. 在Ubuntu 18.04上实际安装OpenJDK 11