JAX-RS usando mapeadores de excepciones

He leído que puedo crear una implementación de javax.ws.rs.ext.ExceptionMapper que javax.ws.rs.ext.ExceptionMapper una excepción de aplicación lanzada a un objeto Response .

He creado un ejemplo simple que arroja una excepción si la longitud del teléfono es superior a 20 caracteres al persistir el objeto. Espero que la excepción se asigne a una respuesta HTTP 400 (Solicitud incorrecta); sin embargo, recibo un HTTP 500 (Internal Server Error) con la siguiente excepción:

 java.lang.ClassCastException: com.example.exception.InvalidDataException cannot be cast to java.lang.Error 

¿Qué me estoy perdiendo? Cualquier consejo es muy apreciado.

Mapeador de excepciones:

 @Provider public class InvalidDataMapper implements ExceptionMapper { @Override public Response toResponse(InvalidDataException arg0) { return Response.status(Response.Status.BAD_REQUEST).build(); } } 

Clase de excepción:

 public class InvalidDataException extends Exception { private static final long serialVersionUID = 1L; public InvalidDataException(String message) { super(message); } ... } 

Clase de entidad:

 @Entity @Table(name="PERSON") @XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement public class Person { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name="ID") private Long id; @Column(name="NAME") private String name; @Column(name="PHONE") private String phone; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } @PrePersist public void validate() throws InvalidDataException { if (phone != null) { if (phone.length() > 20) { throw new InvalidDataException("Phone number too long: " + phone); } } } } 

Servicio:

 @Path("persons/") @Produces(MediaType.APPLICATION_XML) @Consumes(MediaType.APPLICATION_XML) @Stateless public class PersonResource { @Context private UriInfo uriInfo; @PersistenceContext(name="simple") private EntityManager em; @POST public Response createPerson(JAXBElement personJaxb) { Person person = personJaxb.getValue(); em.persist(person); em.flush(); URI personUri = uriInfo.getAbsolutePathBuilder(). path(person.getId().toString()).build(); return Response.created(personUri).build(); } } 

¿InvalidDataException está envuelto en PersistenceException? Tal vez podrías hacer algo como lo siguiente:

 @Provider public class PersistenceMapper implements ExceptionMapper { @Override public Response toResponse(PersistenceException arg0) { if(arg0.getCause() instanceof InvalidDataException) { return Response.status(Response.Status.BAD_REQUEST).build(); } else { ... } } } 

Revise su web.xml para registrar su clase “PersistenceMapper” junto con los servicios.