1

希望我得到了正确的标题,但我正在尝试使用 JAX-RS@Path注释将请求映射到基于实体参数的不同方法。

我认为示例代码会更容易:

超级班:

public class Geothing {
    private int thingId;
    private String status;

    // Ctor, getters and setters
}

PolygonGeothing 扩展了 Geothing:

@XmlRootElement
public class PolygonGeothing extends Geothing {
    private Coordinates coordinates;

    // Ctor, getters and setters
}

CircleGeothing 扩展了 Geothing:

@XmlRootElement
public class CircleGeothing extends Geothing {
    private Coordinate center;
    private int radius;

    // Ctor, getters and setters
}

服务接口:

@Path("/geothing/{id}")
public interface GeothingService extends CoService {
    @POST
    Response createGeothing(@PathParam("{id}") Long id, PolygonGeothing geothing);

    @POST
    Response createGeothing(@PathParam("{id}") Long id, CircleGeothing geothing);
}

我的期望是,如果我为 PolygonGeothing 或 CircleGeothing 发布 XML,那么它将起作用。但是,它仅在我发布 PolygonGeothing XML 并且如果我发布 CircleGeothing XML 然后我得到一个 JAXBException 时才有效:
JAXBException occurred : unexpected element (uri:"", local:"circleGeothing"). Expected elements are <{}polygonGeothing>.

是否可以正确映射此映射而无需为 CircleGeothing 和 PolygonGeothing 指定单独的 URI 路径?此外,是否可以有如下接口,我可以在其中使用超类作为参数?我测试了返回类型 Geothing,如果我创建一个 PolygonGeothing 或 CircleGeothing 并返回它,那么它工作正常......但如果我尝试将 PolygonGeothing 或 CircleGeothing 作为参数类型为 Geothing 的参数传递,则不会。

@Path("/geothing/{id}")
public interface GeothingService extends CoService {
    @POST
    Response createGeothing(@PathParam("{id}") Long id, Geothing geothing);
}
4

1 回答 1

1

这样做是不可能的。原因很简单:CXF(与任何其他 JAX-RS 框架一样)基于 REST 定义而不是基于面向对象的原则来路由响应。我的意思是它根据 URL、生产内容类型和消费内容类型选择方法。(这是简化的描述,具体算法请参见 JSR311)。但这与您期望的对象无关。只有在选择了方法之后,对象才会被序列化。这就是您收到异常的原因:createGeothing(@PathParam("{id}") Long id, PolygonGeothing geothing)被选中,因此它尝试序列化错误的类。

您可以执行以下操作:

Response createGeothing(@PathParam("{id}") Long id, Geothing geothing)

而不是强制转换并调用相关方法。
当然,您需要确保 JAXB 上下文已知 Geothing。

于 2011-02-03T07:08:52.280 回答