错误验证消息格式 Spring 启动
Error validation message format Spring boot
我是使用 Java 和 Spring 引导的新手,我正在尝试验证将存储在数据库中的 json 输入,验证进行得很好,问题是响应格式,我认为客户端不可读为 Angular JS,需要知道如何更改输出格式:
{
"error": {
"code": 400,
"message": "Validation failed for classes [com.company.customerhelpcenter.domain.Ticket] during persist time for groups [javax.validation.groups.Default, ]\nList of constraint violations:[\n\tConstraintViolationImpl{interpolatedMessage='Descripción no puede ser null', propertyPath=description, rootBeanClass=class com.company.customerhelpcenter.domain.Ticket, messageTemplate='Descripción no puede ser null'}\n\tConstraintViolationImpl{interpolatedMessage='not a well-formed email address', propertyPath=email, rootBeanClass=class com.company.customerhelpcenter.domain.Ticket, messageTemplate='{org.hibernate.validator.constraints.Email.message}'}\n\tConstraintViolationImpl{interpolatedMessage='Número de teléfono no puede ser null', propertyPath=phone, rootBeanClass=class com.company.customerhelpcenter.domain.Ticket, messageTemplate='Número de teléfono no puede ser null'}\n]"
}}
至此
{
"error": {
"description" : "Description cannot be null",
"email": "Email cannot be null",
"phone": "Phone cannot be null"
} }
这是我的控制器
@PostMapping
public ResponseEntity<?> create(@RequestBody Ticket ticket)
{
return new ResponseEntity<>(this.ticketService.create(ticket), HttpStatus.CREATED);
}
服务:
public Ticket create(Ticket ticket)
{
return this.ticketRepository.save(ticket);
}
存储库:
@Repository
public interface TicketRepository extends JpaRepository<Ticket, Integer>, Serializable
{}
实体
@Entity
@Table(name = "ticket")
public class Ticket implements Serializable
{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id")
private Integer id;
@Basic(optional = false)
@NotNull(message = "Descripción no puede ser null")
@Size(min = 1, max = 255)
@Column(name = "description")
private String description;
@Basic(optional = false)
@NotNull(message = "Número de teléfono no puede ser null")
@Size(min = 1, max = 20)
@Column(name = "phone")
private String phone;
@Basic(optional = false)
@NotNull(message = "Email no puede ser null")
@Size(min = 1, max = 80)
@Email
@Column(name = "email")
private String email;
@Basic(optional = false)
@NotNull
@Column(name = "locked")
private boolean locked;
@JoinColumn(name = "ticket_type_id", referencedColumnName = "id")
@ManyToOne(optional = false, fetch = FetchType.EAGER)
@Exclude
private TicketType ticketType;
@OneToMany(mappedBy = "ticket")
private Set<TicketHistory> ticketHistories = new HashSet<TicketHistory>();
public Integer getId()
{
return this.id;
}
public String getDescription()
{
return this.description;
}
public String getPhone()
{
return this.phone;
}
public String getEmail()
{
return this.email;
}
public TicketType getTicketType()
{
return this.ticketType;
}
public boolean isLocked()
{
return this.locked;
}
public Set<TicketHistory> getTicketHistories()
{
return this.ticketHistories;
}
}
您的异常是 ConstraintValidationException
,这意味着代码通过了控制器,但由于验证无法将数据保存到数据库中。我的建议是您在此之前验证数据,在数据获取控制器之前验证您的数据。所以,会是这样的:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler({MethodArgumentNotValidException.class})
public ResponseEntity<Map<String, Object>> yourExceptionHandler(MethodArgumentNotValidException e) {
Map<String, Object> response = new HashMap<String, Object>();
Map<String, String> errors = new HashMap<String, String>();
BindingResult bindingResult = e.getBindingResult();
List<FieldError> fieldErrors = bindingResult.getFieldErrors();
for (FieldError fieldError : fieldErrors) {
errors.put(fieldError.getField(), fieldError.getDefaultMessage());
}
response.put("error", errors);
return new ResponseEntity<Map<String, Object>>(response, HttpStatus.BAD_REQUEST);
}
}
你的控制器应该有这个 @Valid
注释:
@PostMapping
public ResponseEntity<?> create(@RequestBody @Valid Ticket ticket) {
return new ResponseEntity<>(this.ticketService.create(ticket), HttpStatus.CREATED);
}
然后,您对 @NotNull
和 @Size
等 Ticket 的验证将被验证。
但是,如果您不想这样验证,而只想处理 ConstraintValidationException
,您可以这样做:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler({ ConstraintViolationException.class})
public ResponseEntity<Map<String, Object>> yourExceptionHandler(ConstraintViolationException e) {
Map<String, Object> response = new HashMap<String, Object>();
Map<String, String> errors = new HashMap<String, String>();
Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations();
for (ConstraintViolation<?> constraintViolation : constraintViolations) {
errors.put(constraintViolation.getPropertyPath().toString() , constraintViolation.getMessage());
}
response.put("error", errors);
return new ResponseEntity<Map<String, Object>>(response, HttpStatus.BAD_REQUEST);
}
}
我是使用 Java 和 Spring 引导的新手,我正在尝试验证将存储在数据库中的 json 输入,验证进行得很好,问题是响应格式,我认为客户端不可读为 Angular JS,需要知道如何更改输出格式:
{
"error": {
"code": 400,
"message": "Validation failed for classes [com.company.customerhelpcenter.domain.Ticket] during persist time for groups [javax.validation.groups.Default, ]\nList of constraint violations:[\n\tConstraintViolationImpl{interpolatedMessage='Descripción no puede ser null', propertyPath=description, rootBeanClass=class com.company.customerhelpcenter.domain.Ticket, messageTemplate='Descripción no puede ser null'}\n\tConstraintViolationImpl{interpolatedMessage='not a well-formed email address', propertyPath=email, rootBeanClass=class com.company.customerhelpcenter.domain.Ticket, messageTemplate='{org.hibernate.validator.constraints.Email.message}'}\n\tConstraintViolationImpl{interpolatedMessage='Número de teléfono no puede ser null', propertyPath=phone, rootBeanClass=class com.company.customerhelpcenter.domain.Ticket, messageTemplate='Número de teléfono no puede ser null'}\n]"
}}
至此
{
"error": {
"description" : "Description cannot be null",
"email": "Email cannot be null",
"phone": "Phone cannot be null"
} }
这是我的控制器
@PostMapping
public ResponseEntity<?> create(@RequestBody Ticket ticket)
{
return new ResponseEntity<>(this.ticketService.create(ticket), HttpStatus.CREATED);
}
服务:
public Ticket create(Ticket ticket)
{
return this.ticketRepository.save(ticket);
}
存储库:
@Repository
public interface TicketRepository extends JpaRepository<Ticket, Integer>, Serializable
{}
实体
@Entity
@Table(name = "ticket")
public class Ticket implements Serializable
{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id")
private Integer id;
@Basic(optional = false)
@NotNull(message = "Descripción no puede ser null")
@Size(min = 1, max = 255)
@Column(name = "description")
private String description;
@Basic(optional = false)
@NotNull(message = "Número de teléfono no puede ser null")
@Size(min = 1, max = 20)
@Column(name = "phone")
private String phone;
@Basic(optional = false)
@NotNull(message = "Email no puede ser null")
@Size(min = 1, max = 80)
@Email
@Column(name = "email")
private String email;
@Basic(optional = false)
@NotNull
@Column(name = "locked")
private boolean locked;
@JoinColumn(name = "ticket_type_id", referencedColumnName = "id")
@ManyToOne(optional = false, fetch = FetchType.EAGER)
@Exclude
private TicketType ticketType;
@OneToMany(mappedBy = "ticket")
private Set<TicketHistory> ticketHistories = new HashSet<TicketHistory>();
public Integer getId()
{
return this.id;
}
public String getDescription()
{
return this.description;
}
public String getPhone()
{
return this.phone;
}
public String getEmail()
{
return this.email;
}
public TicketType getTicketType()
{
return this.ticketType;
}
public boolean isLocked()
{
return this.locked;
}
public Set<TicketHistory> getTicketHistories()
{
return this.ticketHistories;
}
}
您的异常是 ConstraintValidationException
,这意味着代码通过了控制器,但由于验证无法将数据保存到数据库中。我的建议是您在此之前验证数据,在数据获取控制器之前验证您的数据。所以,会是这样的:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler({MethodArgumentNotValidException.class})
public ResponseEntity<Map<String, Object>> yourExceptionHandler(MethodArgumentNotValidException e) {
Map<String, Object> response = new HashMap<String, Object>();
Map<String, String> errors = new HashMap<String, String>();
BindingResult bindingResult = e.getBindingResult();
List<FieldError> fieldErrors = bindingResult.getFieldErrors();
for (FieldError fieldError : fieldErrors) {
errors.put(fieldError.getField(), fieldError.getDefaultMessage());
}
response.put("error", errors);
return new ResponseEntity<Map<String, Object>>(response, HttpStatus.BAD_REQUEST);
}
}
你的控制器应该有这个 @Valid
注释:
@PostMapping
public ResponseEntity<?> create(@RequestBody @Valid Ticket ticket) {
return new ResponseEntity<>(this.ticketService.create(ticket), HttpStatus.CREATED);
}
然后,您对 @NotNull
和 @Size
等 Ticket 的验证将被验证。
但是,如果您不想这样验证,而只想处理 ConstraintValidationException
,您可以这样做:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler({ ConstraintViolationException.class})
public ResponseEntity<Map<String, Object>> yourExceptionHandler(ConstraintViolationException e) {
Map<String, Object> response = new HashMap<String, Object>();
Map<String, String> errors = new HashMap<String, String>();
Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations();
for (ConstraintViolation<?> constraintViolation : constraintViolations) {
errors.put(constraintViolation.getPropertyPath().toString() , constraintViolation.getMessage());
}
response.put("error", errors);
return new ResponseEntity<Map<String, Object>>(response, HttpStatus.BAD_REQUEST);
}
}