JAX-RS и CXF отображают запрос на метод, основанный на XML - PullRequest
1 голос
/ 02 февраля 2011

Надеюсь, я правильно понял заголовок, но я пытаюсь отобразить запросы с помощью аннотаций JAX-RS @Path на разные методы, основанные на параметре entity.

Думаю, пример кода облегчит задачу:

Суперкласс:

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

Я ожидал, что если я отправлю XML для PolygonGeothing или CircleGeothing, то это будет работать.Тем не менее, это работает, только если я POST PolygonGeothing XML и если я POST CircleGeothing XML, я получаю JAXBException:
JAXBException occurred : unexpected element (uri:"", local:"circleGeothing"). Expected elements are <{}polygonGeothing>.

Можно ли правильно отобразить это без необходимости указывать отдельный путь URIдля CircleGeothing и PolygonGeothing?Кроме того, возможно ли иметь интерфейс, такой как следующий, где я могу использовать суперкласс в качестве параметра?Я протестировал возвращаемый тип Geothing, и если я создаю PolygonGeothing или CircleGeothing и возвращаю его, тогда он работает нормально ... но не в том случае, если я пытаюсь передать PolygonGeothing или CircleGeothing в качестве параметра, где типом параметра является Geothing.

1 Ответ

1 голос
/ 03 февраля 2011

Невозможно сделать это таким образом.Причина проста: CXF (как любая другая структура JAX-RS) маршрутизирует ответы на основе определений REST, а не на объектно-ориентированных принципалах.Я имею в виду, что он выбирает метод на основе URL, производимого типа контента и используемого типа контента.(Это упрощенное описание, точный алгоритм см. В JSR311).Но это не имеет ничего общего с объектами, которые вы ожидаете.Объекты сериализуются только после того, как метод уже выбран.По этой причине вы получаете исключение: выбрано createGeothing(@PathParam("{id}") Long id, PolygonGeothing geothing), поэтому оно пытается сериализовать неправильный класс.

Вы можете сделать следующее:

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

, а затем выполнить приведение ивызовите соответствующий метод.
Конечно, вам нужно убедиться, что Geothing известно контексту JAXB.

...