如何正确处理服务异常(spring boot rest)
How to correctly handle exceptions from the service (spring boot rest)
当使用 spring 引导构建 rest api 时,从服务级别处理异常并将它们传递 到控制器的最佳方法是什么,所以客户端收到 自定义 json 错误消息 .
{
"message": "some error"
}
来自控制器的端点
@PostMapping("/login")
public String login(@RequestBody @Valid LoginDto loginDto) {
return gson.toJson(userService.login(loginDto.getUsername(), loginDto.getPassword()));
}
服务级别代码
public LoginResponseDto login(String username, String password) {
try {
//performs some checks
...
return new LoginResponseDto(token.get());
} catch (AuthenticationException e){
LOGGER.info("Log in failed for user {}", username);
}
return new LoginResponseDto("login failed");
}
LoginResponseDto class
String token;
String message;
public LoginResponseDto(String message) {
this.message = message;
}
目前它显然返回了正确的消息但不是正确的状态代码,它将显示状态 200 和 json 中的错误消息。
您有一些选择:
1) 返回消息:
如果你想return这样的消息,
{
"message": "some error"
}
您可以做的是:
选项 1:创建自定义 POJO class 用于错误消息和 return 对该 POJO 对象的引用 class。
像这样:
ErrorMessage.java
package org.example;
public class ErrorMessage {
private String message;
public ErrorMessage(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
控制器中的请求处理程序方法:
@GetMapping("/login{?username, password}")
public ErrorMessage isUserAuthenticated(@RequestParam String username, @RequestParam String password) {
if (username.toLowerCase().contentEquals("root") && password.contentEquals("system")) {
return new ErrorMessage("authenticated");
}
return null;
}
选项 2:创建一个映射并插入您希望在消息中包含的键值对。
像这样:
@GetMapping("/login{?username, password}")
public Map<String, String> isUserAuthenticated(@RequestParam String username, @RequestParam String password) {
Map<String, String> message = new HashMap<>();
if (username.toLowerCase().contentEquals("root") && password.contentEquals("system")) {
message.put("message", "authenticated");
}
return message;
}
2) 返回错误状态码(我强烈推荐):
您可以为此目的使用 ResponseEntity。
@GetMapping("/login{?username, password}")
public ResponseEntity<?> isUserAuthenticated(@RequestParam String username, @RequestParam String password) {
if (username.toLowerCase().contentEquals("root") && password.contentEquals("system")) {
return new ResponseEntity<>(HttpStatus.OK);
}
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
当使用 spring 引导构建 rest api 时,从服务级别处理异常并将它们传递 到控制器的最佳方法是什么,所以客户端收到 自定义 json 错误消息 .
{
"message": "some error"
}
来自控制器的端点
@PostMapping("/login")
public String login(@RequestBody @Valid LoginDto loginDto) {
return gson.toJson(userService.login(loginDto.getUsername(), loginDto.getPassword()));
}
服务级别代码
public LoginResponseDto login(String username, String password) {
try {
//performs some checks
...
return new LoginResponseDto(token.get());
} catch (AuthenticationException e){
LOGGER.info("Log in failed for user {}", username);
}
return new LoginResponseDto("login failed");
}
LoginResponseDto class
String token;
String message;
public LoginResponseDto(String message) {
this.message = message;
}
目前它显然返回了正确的消息但不是正确的状态代码,它将显示状态 200 和 json 中的错误消息。
您有一些选择:
1) 返回消息:
如果你想return这样的消息,
{
"message": "some error"
}
您可以做的是:
选项 1:创建自定义 POJO class 用于错误消息和 return 对该 POJO 对象的引用 class。
像这样:
ErrorMessage.java
package org.example;
public class ErrorMessage {
private String message;
public ErrorMessage(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
控制器中的请求处理程序方法:
@GetMapping("/login{?username, password}")
public ErrorMessage isUserAuthenticated(@RequestParam String username, @RequestParam String password) {
if (username.toLowerCase().contentEquals("root") && password.contentEquals("system")) {
return new ErrorMessage("authenticated");
}
return null;
}
选项 2:创建一个映射并插入您希望在消息中包含的键值对。
像这样:
@GetMapping("/login{?username, password}")
public Map<String, String> isUserAuthenticated(@RequestParam String username, @RequestParam String password) {
Map<String, String> message = new HashMap<>();
if (username.toLowerCase().contentEquals("root") && password.contentEquals("system")) {
message.put("message", "authenticated");
}
return message;
}
2) 返回错误状态码(我强烈推荐):
您可以为此目的使用 ResponseEntity。
@GetMapping("/login{?username, password}")
public ResponseEntity<?> isUserAuthenticated(@RequestParam String username, @RequestParam String password) {
if (username.toLowerCase().contentEquals("root") && password.contentEquals("system")) {
return new ResponseEntity<>(HttpStatus.OK);
}
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}