2017-07-21 3 views
0

Je suis nouveau en utilisant Java et Spring boot, j'essaye de valider une entrée json qui sera stockée en DB, la validation se passe bien, le problème est le format de réponse, je pense que ce n'est pas lisible pour un client comme angulaire JS, dans le besoin de savoir comment changer le format de sortie de celle-ci:Format de message de validation d'erreur Spring boot

{ 
"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]" 
}} 

à cette

{ 
"error": { 
    "description" : "Description cannot be null", 
    "email": "Email cannot be null", 
    "phone": "Phone cannot be null" 
} } 

Ceci est mon contrôleur

@PostMapping 
public ResponseEntity<?> create(@RequestBody Ticket ticket) 
{ 
    return new ResponseEntity<>(this.ticketService.create(ticket), HttpStatus.CREATED); 
} 

Service:

public Ticket create(Ticket ticket) 
{ 
    return this.ticketRepository.save(ticket); 
} 

Repository:

@Repository 
public interface TicketRepository extends JpaRepository<Ticket, Integer>, Serializable 
{} 

Entité

@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; 
    } 
} 

Répondre

2

Votre exception est un ConstraintValidationException, cela signifie que le code passe par le contrôleur, mais n'a pas pu sauver la données sur la base de données en raison de la validation. Ma recommandation est que vous validiez les données avant cela, validez vos données avant qu'elles n'atteignent le Contrôleur. Alors, serait comme ceci:

@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); 
    } 
} 

Et votre contrôleur devrait avoir cette annotation @Valid:

@PostMapping 
public ResponseEntity<?> create(@RequestBody @Valid Ticket ticket) { 
    return new ResponseEntity<>(this.ticketService.create(ticket), HttpStatus.CREATED); 
} 

Ensuite, validateurs sur Ticket comme @NotNull et @Size etc seront validés.

MAIS, si vous ne voulez pas valider comme ça et vous ne souhaitez que traiter ConstraintValidationException, vous pouvez le faire:

@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); 
    } 
} 
+0

Merci, ça a marché! –