Como tratar 错误 http 没有 Spring Boot
Tratamento de erros,独立于语言,永远是一个复杂的问题。春天的一切,存在推荐和本地激光雷达,比其他地方都好。
本教程使用Java 17和Spring boot 3.1.5。
Código completo usado 示例。
苏马里奥
情况
使用 Spring 验证书库的应用程序:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
DTO实体的验证Person
:
@Data
public class PersonDto {
@NotBlank(message = "name: Is required")
@Length(min = 3, max = 100, message = "title: Must be of 3 - 100 characters")
String name;
@NotBlank(message = "email: Is required")
@Email(message = "email: Invalid format")
String email;
@NotNull(message = "age: Is required")
@Min(value = 1, message = "age: Must be greater than 0")
@Max(value = 100, message = "age: Must be less than 100")
Integer age;
}
定义 DTO,代表控制器的主体,并且始终使用注释作为定义@Valid
acima 的注释:
@PostMapping
public ResponseEntity<Person> create(@RequestBody @Valid @NotNull PersonDto dto) {
return ResponseEntity.status(HttpStatus.CREATED).body(personService.create(dto));
}
哦问题
想要获得无效的价值,请执行以下操作:
{
"timestamp": "2023-10-27T00:03:21.577+00:00",
"status": 400,
"error": "Bad Request",
"trace": "org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public org.springframework.http.ResponseEntity<com.m1guelsb.springexceptions.entities.Person> com.m1guelsb.springexceptions.controllers.PersonController.create(com.m1guelsb.springexceptions.dtos.PersonDto) with 3 errors: [Field error in object 'personDto' on field 'email': rejected value [example]; codes [Email.personDto.email,Email.email,Email.java.lang.String,Email]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [...]"
}
有关错误的法律信息,请参阅有关描述400 Bad request
的内容和trace
价值message
。 Não sabemos quais foram os Campos incorretos, nem quais valores devem serenvados。
简单来说,就是使用 API 时,我们可以将其作为后端技术来使用。 Podemos 考虑到所有技术都存在安全问题。
重要的是,印度可能
MethodArgumentNotValidException
会犯一些错误。 Precisaremos desta informação adiante。
全球卓越过滤器
O Spring nos provê um jeito nativo para tratar exceções de modo global, o Controller Advice。我们可以使用注释@RestControllerAdvice
。
这是理想的解决错误问题的集中化方法和解决错误问题的方法:
@RestControllerAdvice
public class GlobalExceptionHandler {
private Map<String, List<String>> errorsMap(List<String> errors) {
Map<String, List<String>> errorResponse = new HashMap<>();
errorResponse.put("errors", errors);
return errorResponse;
}
}
我们的方法errorsMap
是接收列表String
并返回列表中的Map
值errors
。 JSON 序列的表示:
{
"errors": [
//lista de erros
]
}
接受和验证错误
Agora Finalmente escrevemos 或拦截错误的方法并返回 jeito queremos 的价值:
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Map<String, List<String>>> handleValidationErrors(MethodArgumentNotValidException ex) {
List<String> errors = ex.getBindingResult()
.getFieldErrors()
.stream()
.map(error -> error.getDefaultMessage())
.toList();
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorsMap(errors));
}
private Map<String, List<String>> errorsMap(List<String> errors) {
Map<String, List<String>> errorResponse = new HashMap<>();
errorResponse.put("errors", errors);
return errorResponse;
}
}
使用注释@ExceptionHandler()
,截取作为前面的MethodArgumentNotValidException
注释或注释trace
。
理解或方法handleValidationErrors(MethodArgumentNotValidException ex)
:
- Recebemos
ex
como paraâmetro do tito do nosso erro, iteramos emgetFieldErrors()
e em seguida, coletamos as mensagens de erro usandogetDefaultMessage()
para retornar uma lista com elas:
List<String> errors = ex.getBindingResult()
.getFieldErrors()
.stream()
.map(error -> error.getDefaultMessage())
.toList();
- 请注意以下错误列表或
errorsMap
恢复状态:body
ResponseEntity
BAD_REQUEST
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorsMap(errors));
Com isso,quando nosso 客户端 envirar bado incorretos:
{
"name": "Mi",
"email": "Invalid email",
"age": 0
}
回复linda 和 cheirosa :
{
"errors": [
"title: Must be of 3 - 100 characters",
"age: Must be greater than 0",
"email: Invalid format"
]
}
Meus caros leitores,isso aqui é o sonho de todo dev front-end! 🥰
犯其他类型的错误
继续或了解模型,然后执行错误提示的方法。
结束语 与常见的错误一样,我们404 NOT_FOUND
要采取的方法是通过以下方法来实现个性化的环境RuntimeException
:
public class NotFoundException extends RuntimeException {
public NotFoundException(String ex) {
super(ex);
}
}
E então, no nosso GlobalExceptionHandler
adicionamos or seguinte method:
@ExceptionHandler(NotFoundException.class)
public ResponseEntity<Map<String, List<String>>> handleNotFoundException(NotFoundException ex) {
List<String> errors = List.of(ex.getMessage());
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errorsMap(errors));
}
前面的方法有以下不同之处:
- Trocamos 或 parâmetro classe do
ExceptionHandler
para agora 激光雷达 com a nossa classeNotFoundException
- Agora coletamos a mensagem de erro criando uma lista contro o seu valor:
List.of(ex.getMessage())
.
如果您遇到一些错误,请参阅示例404
方法:findById
PersonService
public Person findById(Long id) throws NotFoundException {
return personRepository.findById(id)
.orElseThrow(() -> new NotFoundException("Person with id " + id + " not found"));
}
Dessa forma, quando nosso client tentar acessar um Person que não Existe, ele receberá a mensagem que inserimos ao instanciar a classe:
{
"errors": [
"Person with id 999 not found"
]
}
由于不重要,请过滤掉以下错误Exception
:RuntimeException
@ExceptionHandler(Exception.class)
public final ResponseEntity<Map<String, List<String>>> handleGeneralExceptions(Exception ex) {
List<String> errors = List.of(ex.getMessage());
return ResponseEntity
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(errorsMap(errors));
}
@ExceptionHandler(RuntimeException.class)
public final ResponseEntity<Map<String, List<String>>> handleRuntimeExceptions(RuntimeException ex) {
List<String> errors = List.of(ex.getMessage());
return ResponseEntity
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(errorsMap(errors));
}
接下来,如果您遇到错误,请立即返回,以确保您的信息安全。 🥳🎉
Por hoje é isso! Acha que faltou alguma informationação importante or descobriu algum bug? Sinta-se livre para me mandar uma mensagem no Twitter/X。
感谢阅读!💝
鏂囩珷鏉ユ簮锛�https://dev.to/m1guelsb/como-tratar-erros-http-no-spring-boot-41de