Pergunta

Eu li que eu posso criar uma implementação de javax.ws.rs.ext.ExceptionMapper que irá mapear um lançada exceção de aplicativo para um Response objecto.

Eu criei um exemplo simples que lança uma exceção se o telefone comprimento é maior do que 20 caracteres quando persistir o objeto.Estou esperando a exceção a ser mapeada para um HTTP 400 (Bad Request) de resposta;no entanto, eu estou recebendo um HTTP 500 (Erro Interno do Servidor), com a seguinte exceção:

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

O que eu estou ausente?Qualquer conselho é muito apreciada.

Exceção mapeador:

@Provider
public class InvalidDataMapper implements ExceptionMapper<InvalidDataException> {

    @Override
    public Response toResponse(InvalidDataException arg0) {
        return Response.status(Response.Status.BAD_REQUEST).build();
    }

}

Classe de exceção:

public class InvalidDataException extends Exception {

    private static final long serialVersionUID = 1L;

    public InvalidDataException(String message) {
        super(message);
    }

    ...

}

Entidade de classe:

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

Serviço:

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

}
Foi útil?

Solução

É InvalidDataException ficar envolto em uma PersistenceException?Talvez você poderia fazer algo como o seguinte:

@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 {
           ...
        }
    } 

} 

Outras dicas

Cruz verifique você web.xml você precisa registrar o seu "PersistenceMapper" classe também, junto com os serviços.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top