JAX-RS usando mapeadores de excepción


He leído que puedo crear una implementación de javax.ws.rs.ext.ExceptionMapper que mapeará 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 mayor de 20 caracteres al persistir el objeto. Estoy esperando que la excepción se asigne a una respuesta HTTP 400( Solicitud incorrecta); sin embargo, estoy recibiendo un HTTP 500 (Error Interno del Servidor) 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<InvalidDataException> {

    @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<Person> personJaxb) {
        Person person = personJaxb.getValue();
        em.persist(person);
        em.flush();
        URI personUri = uriInfo.getAbsolutePathBuilder().
        path(person.getId().toString()).build();
        return Response.created(personUri).build();  
    }

}
Author: Jordan Allan, 2010-07-20

2 answers

¿InvalidDataException se envuelve en una PersistenceException? Tal vez usted podría hacer algo como lo siguiente:

@Provider 
public class PersistenceMapper implements ExceptionMapper<PersistenceException> { 

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

} 
 31
Author: Blaise Doughan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-07-28 18:45:05

Cruza tu web.xml necesita registrar su clase "PersistenceMapper" también junto con los servicios.

 -1
Author: user3542372,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-11 17:30:29