2010-07-20 5 views
29

Ich habe gelesen, dass ich eine Implementierung von javax.ws.rs.ext.ExceptionMapper erstellen kann, die eine ausgelöste Anwendung Ausnahme auf ein Response Objekt zuordnen wird.JAX-RS mit Ausnahme Mapper

Ich habe ein einfaches Beispiel erstellt, das eine Ausnahme auslöst, wenn die Telefonlänge mehr als 20 Zeichen beträgt, wenn das Objekt persistiert. Ich erwarte, dass die Ausnahme einer HTTP 400 (Bad Request) Antwort zugeordnet wird; Ich empfange jedoch ein HTTP 500 (Interner Serverfehler) mit der folgenden Ausnahme:

Was fehlt mir? Jeder Rat wird sehr geschätzt.

Exception-Mapper:

@Provider 
public class InvalidDataMapper implements ExceptionMapper<InvalidDataException> { 

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

} 

Ausnahmeklasse:

public class InvalidDataException extends Exception { 

    private static final long serialVersionUID = 1L; 

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

    ... 

} 

Entity Klasse:

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

Service:

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

} 

Antwort

31

Wird InvalidDataException in eine PersistenceException eingeschlossen? Vielleicht könnten Sie etwas tun, wie folgt aus:

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

} 
+2

Danke Blaise, das hat funktioniert. Warum muss ich InvalidDataException in eine PersistenceException umbrechen? Laut einer der Bücher, die ich habe, heißt es, die JAX-RS-Laufzeit wird jede ausgelöste Ausnahme behandeln, wenn ein Ausnahme-Mapper registriert ist. In meinem Fall habe ich einen Ausnahme-Mapper für InvalidDataException registriert ... –

+4

Die JPA-Implementierung wird InvalidDataException abfangen und in PersistenceException umbrechen. Dann wird Ihre JAX-RS-Implementierung eine PersistenceException erhalten. Deshalb müssen Sie es auspacken. –

+0

Siehe auch http://stackoverflow.com/questions/3249495/call-exceptionmapper-from-another-exceptionmapper-in-jax-rs –

-1

Kreuz überprüfen Sie web.xml Sie Ihre „PersistenceMapper“ Klasse registrieren müssen auch zusammen mit den Dienstleistungen.