代码之家  ›  专栏  ›  技术社区  ›  Jordan Allan

使用异常映射器的JAX-RS

  •  29
  • Jordan Allan  · 技术社区  · 15 年前

    我读到我可以创建 javax.ws.rs.ext.ExceptionMapper 将抛出的应用程序异常映射到 Response 对象。

    我创建了一个简单的示例,当持久化对象时,如果phone长度大于20个字符,就会抛出一个异常。我期望异常被映射到HTTP400(坏请求)响应;但是,我收到一个HTTP 500(内部服务器错误),异常如下:

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

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

    异常类:

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

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

    服务:

    @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();  
        }
    
    }
    
    2 回复  |  直到 11 年前
        1
  •  34
  •   bdoughan    15 年前

    InvalidDataException是否包装在PersistenceException中?也许你可以这样做:

    @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
  •  -2
  •   Ashish    9 年前

    交叉检查web.xml您需要注册“PersistenceMapper”类以及服务。