执行失败:javax.ws.rs.NotSupportedException:找不到类型的邮件正文阅读器:T 内容类型:application/xml

failed to execute: javax.ws.rs.NotSupportedException: Could not find message body reader for type: T of content type: application/xml

您好,我在尝试向 JAX-RS 服务 POST 发送 xml 消息时收到上述警告。我的代码如下:

实体:

@Entity(name = "rbac_group")
@NamedQueries({
    @NamedQuery(name = "Group.findById", query = "SELECT g FROM rbac_group g WHERE g.id = :id")
})
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Group implements Serializable {

    private static final long serialVersionUID = 1L;    

    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    @Column(name = "ID")
    @XmlAttribute(name = "id")
    private Long id;

    @Column(name = "GROUP_NAME", unique = true, nullable = false)
    @XmlElement(name = "Name", required = true)
    private String groupName;

    @Column(name = "DESCRIPTION")
    @XmlElement(name = "Description")
    private String groupDescription;

    public Group() {
    }

    // Getters and setters omitted    

}

控制器:

@Stateless
public class GroupController extends AbstractController<Group> {

    public GroupController() {
        super(Group.class);
    }

}

扩展了抽象控制器:

public abstract class AbstractController<T> {

    @PersistenceContext
    EntityManager em;

    private final Class<T> entityClass;

    public AbstractController(Class<T> entityClass) {
        this.entityClass = entityClass;
    }

    public T create(T entity) throws EJBAccessException, EntityExistsException, Exception {
        em.persist(entity);
        return entity;
    }
}

和 REST 资源:

@Path("group")
public class GroupResource extends AbstractResource {

    @Inject
    GroupController controller;

    public GroupResource() {
        super(Group.class);
    }

    @Override
    protected AbstractController getController() {
        return controller;
    }

}

扩展抽象资源:

public abstract class AbstractResource<T> {

    private final Class<T> entityClass;

    public AbstractResource(Class<T> entityClass) {
        this.entityClass = entityClass;
    }

    protected abstract AbstractController getController();

    public Type getType() {
        Type type = ((ParameterizedType) getClass().getGenericSuperclass())
                .getActualTypeArguments()[0];
        return new AbstractList(type);
    }

    @POST
    @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public Response post(T entity) {
        try {
            T returnedEntity = (T) getController()
                    .create(new GenericEntity(entity, getType()));
            return Response.status(Response.Status.CREATED)
                    .entity((T) new GenericEntity(returnedEntity, getType())).build();
        } catch (EJBAccessException ex) {
            Logger.getLogger(entityClass.getName())
                    .log(Level.INFO, ex.getMessage());
            return Response.status(Response.Status.FORBIDDEN)
                    .entity(ex.getMessage()).build();
        } catch (EntityExistsException ex) {
            Logger.getLogger(entityClass.getName())
                    .log(Level.INFO, ex.getMessage());
            return Response.status(Response.Status.BAD_REQUEST)
                    .entity(ex.getMessage()).build();
        } catch (Exception ex) {
            Logger.getLogger(entityClass.getName())
                    .log(Level.WARNING, ex.getMessage());
            return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
                    .entity(ex.getMessage()).build();
        }
    }

    private static class AbstractList implements ParameterizedType {

        Type type;

        public AbstractList(Type type) {
            this.type = type;
        }

        @Override
        public Type[] getActualTypeArguments() {
            return new Type[]{type};
        }

        @Override
        public Type getRawType() {
            return List.class;
        }

        @Override
        public Type getOwnerType() {
            return AbstractResource.class;
        }

    }

}

当我不使用抽象 classes 而是将所有内容直接放在 GroupController 和 GroupResource 中时,代码有效。然而,我有很多实体 classes 和方法(GET、PUT、DELETE),我想使代码易于管理。 当我将 public Response post(T entity) 更改为 public Response post() 时,错误发生在 public Response post() 上,不再有警告。 我如何从我的摘要 class 中告诉 JAX-RS,在扩展的 class 中,类型不是 T(如错误提示的那样)而是类型 Group?

你的class定义如下:

@Path("group")
public class GroupResource extends AbstractResource {

不应该这样定义吗?

@Path("group")
public class GroupResource extends AbstractResource<Group> {