'Issue while getting custom message from @email annotation Spring Boot
I'm trying to get the message from my @Email annotation for my front-end . The issue is that it doesn't actually pass and I get an empty response. Nothing gets passed inside of the response . I just get a 400 bad request in the status in postman but nothing else happens. Each and every other violation of a constraint gives me a json object that contains the custom message that I typed in. I have 3 classes that do this validation I created a CustomExceptionHandler for this :
ApiError.java
import java.util.Arrays;
import java.util.List;
import org.springframework.http.HttpStatus;
public class ApiError {
private HttpStatus status;
private String message;
private List<String> errors;
public ApiError(HttpStatus status, String message, List<String> errors) {
super();
this.status = status;
this.message = message;
this.errors = errors;
}
public ApiError(HttpStatus status, String message, String error) {
super();
this.status = status;
this.message = message;
errors = Arrays.asList(error);
}
public HttpStatus getStatus() {
return status;
}
public void setStatus(HttpStatus status) {
this.status = status;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public List<String> getErrors() {
return errors;
}
public void setErrors(List<String> errors) {
this.errors = errors;
}
@Override
public String toString() {
return "ApiError [status=" + status + ", message=" + message + ", errors=" + errors + "]";
}
}
CustomRestHandler.java
import java.util.ArrayList;
import java.util.List;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import
org.springframework.messaging.handler.annotation.support.MethodArgumentNotValidException;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import com.neoexams.app.model.ApiError;
@ControllerAdvice
public class CustomRestExceptionHandler extends ResponseEntityExceptionHandler
{
protected ResponseEntity<Object> handleMethodArgumentNotValid(
MethodArgumentNotValidException ex,
HttpHeaders headers,
HttpStatus status,
WebRequest request) {
List<String> errors = new ArrayList<String>();
for (FieldError error : ex.getBindingResult().getFieldErrors()) {
errors.add(error.getField() + ": " + error.getDefaultMessage());
}
for (ObjectError error : ex.getBindingResult().getGlobalErrors()) {
errors.add(error.getObjectName() + ": " + error.getDefaultMessage());
}
ApiError apiError =
new ApiError(HttpStatus.BAD_REQUEST, ex.getLocalizedMessage(), errors);
return handleExceptionInternal(
ex, apiError, headers, apiError.getStatus(), request);
}
@Override
protected ResponseEntity<Object> handleMissingServletRequestParameter(
MissingServletRequestParameterException ex, HttpHeaders headers,
HttpStatus status, WebRequest request) {
String error = ex.getParameterName() + " parameter is missing";
ApiError apiError =
new ApiError(HttpStatus.BAD_REQUEST, ex.getLocalizedMessage(), error);
return new ResponseEntity<Object>(
apiError, new HttpHeaders(), apiError.getStatus());
}
@ExceptionHandler({ ConstraintViolationException.class })
public ResponseEntity<Object> handleConstraintViolation(
ConstraintViolationException ex, WebRequest request)
{
List<String> errors = new ArrayList<String>();
for (ConstraintViolation<?> violation : ex.getConstraintViolations()) {
errors.add(violation.getMessage());
}
ApiError apiError =
new ApiError(HttpStatus.BAD_REQUEST, ex.getLocalizedMessage(), errors);
return new ResponseEntity<Object>(
apiError, new HttpHeaders(), apiError.getStatus());
}
@ExceptionHandler({ MethodArgumentTypeMismatchException.class })
public ResponseEntity<Object> handleMethodArgumentTypeMismatch(
MethodArgumentTypeMismatchException ex, WebRequest request) {
String error =
ex.getName() + " should be of type " + ex.getRequiredType().getName();
ApiError apiError =
new ApiError(HttpStatus.BAD_REQUEST, ex.getLocalizedMessage(), error);
return new ResponseEntity<Object>(
apiError, new HttpHeaders(), apiError.getStatus());
}
}
User.java
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.hibernate.annotations.GenericGenerator;
import com.fasterxml.jackson.annotation.JsonIgnore;
@Entity
@Table(name = "users",
uniqueConstraints = {
@UniqueConstraint(columnNames = "email")
})
@DiscriminatorValue(value = "User")
public class User {
@Id
@GeneratedValue(generator = "increment")
@GenericGenerator(name = "increment", strategy = "increment")
private Long id;
@NotBlank(message = "Email obligatoire")
@Size(max = 50,message = "L'email ne doit pas dépasser les 50 caractères")
@Email(message ="Le format de l'email doit être respecté")
private String email;
@JsonIgnore
@NotBlank(message = "Mot de passe obligatoire")
@Size(max=2000, message ="La taille du mot de passe ne doit pas depasser les 2000 caractères")
private String password;
@NotBlank(message = "Prénom obligatoire")
private String firstName;
@NotBlank(message = "Nom obligatoire")
private String lastName;
@NotEmpty(message ="Rôle obligatoire")
@ManyToMany(fetch = FetchType.EAGER,cascade = CascadeType.ALL)
@JoinTable( name = "user_roles",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<Role> roles = new HashSet<>();
@NotNull(message = "Activation obligatoire")
private Boolean enabled;
public User() {
}
public User(@NotBlank(message = "Email obligatoire") @Size(max = 50,message = "L'email ne doit pas dépasser les 50 caractères") @Email(message ="Le format de l'email doit être respecté") String email,
@NotBlank(message = "Mot de passe obligatoire") @Size(max = 2000, message ="La taille du mot de passe ne doit pas depasser les 2000 caractères") String password,
@NotBlank(message = "Prénom obligatoire") String firstName,
@NotBlank(message = "Nom obligatoire") String lastName,
@NotNull(message = "Activation obligatoire") Boolean enabled) {
super();
this.email = email;
this.password = password;
this.firstName = firstName;
this.lastName = lastName;
this.enabled = enabled;
}
public User(@NotBlank(message = "Email obligatoire") @Size(max = 50,message = "L'email ne doit pas dépasser les 50 caractères") @Email(message ="Le format de l'email doit être respecté") String email,
@NotBlank(message = "Mot de passe obligatoire") @Size(max = 2000, message ="La taille du mot de passe ne doit pas depasser les 2000 caractères") String password) {
super();
this.email = email;
this.password = password;
}
public User(@NotBlank(message = "Email obligatoire") @Size(max = 50,message = "L'email ne doit pas dépasser les 50 caractères") @Email(message ="Le format de l'email doit être respecté") String email,
@NotBlank(message = "Mot de passe obligatoire") @Size(max = 2000, message ="La taille du mot de passe ne doit pas depasser les 2000 caractères") String password, Set<Role> roles) {
super();
this.email = email;
this.password = password;
this.roles = roles;
}
public User(@NotBlank(message = "Email obligatoire") @Size(max = 50,message = "L'email ne doit pas dépasser les 50 caractères") @Email(message ="Le format de l'email doit être respecté") String email,
@NotBlank(message = "Mot de passe obligatoire") @Size(max = 2000, message ="La taille du mot de passe ne doit pas depasser les 2000 caractères") String password,
@NotBlank(message = "Prénom obligatoire") String firstName,
@NotBlank(message = "Nom obligatoire") String lastName,@NotEmpty(message="Rôle obligatoire") Set<Role> roles,
@NotNull(message = "Activation obligatoire") Boolean enabled) {
super();
this.email = email;
this.password = password;
this.firstName = firstName;
this.lastName = lastName;
this.roles = roles;
this.enabled = enabled;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Boolean getEnabled() {
return enabled;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Set<Role> getRoles() {
return roles;
}
public void setEnabled(Boolean enabled) {
this.enabled = enabled;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
}
Every message gets thrown properly from the backend except the email's message
Solution 1:[1]
Try to add an appropriate handler in your @ControllerAdvice
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public @ResponseBody String handleException(MethodArgumentNotValidException ex) {
return ex.getMessage();
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | meridbt |