如何为 Spring Boot Rest 使用自定义异常?
Posted
技术标签:
【中文标题】如何为 Spring Boot Rest 使用自定义异常?【英文标题】:How to use Custom Exception for Spring Boot Rest? 【发布时间】:2016-10-31 10:54:30 【问题描述】:我正在使用 Spring Boot 连接到 mysql 5 数据库(通过 JPA)以及用于服务器端的 Spring Rest。
我的 POJO:
@Entity
public class Employee
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String firstName;
private String lastName;
public String getFirstName()
return firstName;
public void setFirstName(String firstName)
this.firstName = firstName;
public String getLastName()
return lastName;
public void setLastName(String lastName)
this.lastName = lastName;
EmployeRespository:
@RepositoryRestResource(collectionResourceRel = "employee", path = "employee")
public interface EmployeeRepository extends PagingAndSortingRepository<Employee, Long>
Collection<Employee> findByLastName(@Param("name") String name);
员工服务:
@RestController
@RequestMapping("/employee")
public class EmployeeService
@Autowired
private EmployeeRepository employeeRepository;
@RequestMapping(value = "/findByLastName?lastName=", method = RequestMethod.GET)
Object getEmployees(@PathVariable String lastName)
Collection<Employee> result = this.employeeRepository.findByLastName(lastName);
if (result == null)
throw new EmployeeNotFoundException(lastName);
return result;
EmployeeNotFoundException:
public class EmployeeNotFoundException extends RuntimeException
private static final long serialVersionUID = 1L;
public EmployeeNotFoundException(String id)
super("Could not find Employee " + id);
现在当调用我的 REST API 时,我得到以下结果:
这个在我的数据库中不存在并且没有抛出 EmployeeNotFoundException:
curl -X GET -H "Content-Type:application/json" http://localhost:8080/employee/search/findByLastName?name="Smith"
结果:
"_embedded" :
"employee" : [ ]
,
"_links" :
"self" :
"href" : "http://localhost:8080/employee/search/findByLastName?name=Smith"
问题:
为什么会抛出我的 EmployeeNotFoundException?有没有更好的方法来实现这一点(可能还会显示 HTTP 状态代码)?
任何有关如何进行单元测试的 URL 都会很棒(以及最好的单元测试库)...
感谢您抽出宝贵时间阅读本文。
【问题讨论】:
【参考方案1】:如果您想知道 EmployeeNotFoundException
,它会被抛出但未被处理。
您至少需要一个 @ExceptionHandler
注释方法来处理它。
@ExceptionHandler(EmployeeNotFoundException.class)
public void handleException(EmployeeNotFoundException e)
// do something
像这样:
@RestController
@RequestMapping("/employee")
public class EmployeeService
@Autowired
private EmployeeRepository employeeRepository;
@RequestMapping(value = "/findByLastName?lastName=", method = RequestMethod.GET)
Object getEmployees(@PathVariable String lastName)
Collection<Employee> result = this.employeeRepository.findByLastName(lastName);
if (result == null)
throw new EmployeeNotFoundException(lastName);
return result;
@ExceptionHandler(EmployeeNotFoundException.class)
public void handleException(EmployeeNotFoundException e)
System.out.println("Exception triggered");
【讨论】:
抱歉,您的建议仍然无效...我在标准输出的任何地方都没有看到“异常触发”。【参考方案2】:这是因为,下一行返回的不是 null,而是一个空列表。
Collection<Employee> result = this.employeeRepository.findByLastName(lastName);
您既可以检查空列表是否抛出异常,也可以只返回空列表。我不建议为查找/搜索抛出异常。我个人,只为getById
之类的get 方法抛出任何NotFoundException
。否则我只返回空列表。
if (result == null || result.isEmpty())
throw new EmployeeNotFoundException(lastName);
另外,修改 Hey-men-wattsup 的代码以发送错误代码,而不是在 Controller 中抛出异常。这将发送 404,NotFound 代码。
@ExceptionHandler(EmployeeNotFoundException.class)
public void handleException(EmployeeNotFoundException e, , HttpServletResponse response)
response.sendError(HttpStatus.NOT_FOUND.value(), e.getMessage());
Spring Boot Test 的 MockMvc 类结合 Mockito 提供了对控制器进行单元测试所需的方法。
【讨论】:
以上是关于如何为 Spring Boot Rest 使用自定义异常?的主要内容,如果未能解决你的问题,请参考以下文章
如何为 Webflux、Spring-Security、okta-spring-boot-starter 和 Okta-React 正确使用 CORS?
如何为 ZuulException 自定义 Spring Boot 控制器 API 响应