我有一个关于Spring引导的问题。当我想从我的数据库中获取特定用户时,一切都没问题,但是我如何处理空响应(没有这样的用户)?我想将null的返回值处理为响应实体,但是当有一个具有该id的用户时,我需要返回用户详细信息。所以我不能将返回值设置为响应实体。这是问题的截图:
这是代码:
@GetMapping("get/{id}")
public User findById(@PathVariable int id) throws Exception {
try {
if(userMapper.findById(id) != null) {
return userMapper.findById(id);
}else {
throw new Exception("YOK ULAN YOK");
}
}catch (Exception e) {
// TODO: Make perfect
return new User(-1);
}
}
这是返回值:
{
"email": null,
"username": null,
"password": null,
"name": null,
"surname": null,
"age": 0,
"photoLink": null,
"dateOfBirth": null,
"phoneNumber": null,
"city": null,
"country": null,
"friendList": null,
"plan": null,
"id": -1,
"planned": false
}
我不想发送-1用户,我想发送用户未找到响应。我该如何处理?
谢谢,
您可以使用异常处理程序来处理此类异常。要做到这一点,您可以首先返回可选
@GetMapping(value = "/get/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<User> findById(@PathVariable int id) {
return ResponseEntity
.status(HttpStatus.OK)
.body(userMapper.findById(id)
.orElseThrow(UserNotFoundException::new);
}
UserNotFoundException
是一个自定义类。您可以从RuntimeException
扩展,以便异常不受检查。
public class UserNotFoundException extends RuntimeException {}
然后你可以创建一个ErrorResponse
类。您可以自由添加您喜欢的字段,但它可能如下所示:
@Getter
@Setter
public class ErrorResponse {
private int code;
private String description;
}
然后,您可以在ExceptionHandler
中处理这个UserNotFoundException
:
@RestControllerAdvice
@Slf4j
public class ApplicationNameExceptionHandler {
@ExceptionHandler
public ResponseEntity<ErrorResponse> handleException(UserNotFoundException e) {
log.info("User not found");
ErrorResponse errorResponse = new ErrorResponse();
errorResponse.setCode(HttpStatus.NOT_FOUND.value());
errorResponse.setDescription("User not found");
return ResponseEntity
.status(HttpStatus.NOT_FOUND)
.contentType(MediaType.APPLICATION_PROBLEM_JSON)
.body(errorResponse);
}
这种方法的优点是您可以保持控制器简洁整洁,并且所有控制器异常都可以在同一个类中处理(ApplicationNameExceptionHandler
)。
最好的方法是将方法返回类型从User
更改为Response seEntity
@GetMapping("get/{id}")
public ResponseEntity<?> findById(@PathVariable int id) throws Exception {
User user = userMapper.findById(id);
if (user == null) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok(user);
}
或使用可选:
@GetMapping("get/{id}")
public ResponseEntity<?> findById(@PathVariable int id) throws Exception {
return Optional.ofNullable(userMapper.findById(id))
.map(ResponseEntity::ok)
.orElseGet(ResponseEntity.notFound()::build);
}
我们可以尝试定义一个具有响应状态的异常。
@ResponseStatus(value = HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {
}
然后在你的控制器里抛出这个异常
throw new ResourceNotFoundException()
或者,直接设置Response
的状态即可。
BTW,更好的方法是定义我们的业务代码来实现它。