#java #cxf #jax-rs
#java #cxf #jax-rs
Вопрос:
Я использую Apache CXF для своих веб-сервисов restful. У меня есть служба, определенная интерфейсом, который возвращает список моего компонента.
@Path("/")
@Produces("application/xml")
public interface MyService {
@GET
@Path("/test")
public List<MyBean> getBeans() throws IOException;
}
..и реализация сервиса как таковая;
public class MyServiceImpl implements MyService {
public List<MyBean> getBeans() {
ArrayList<MyBean> beans = new ArrayList<MyBean>();
beans.add(new MyBean("foo", "bar");
return beans;
}
}
Это развернуто на моем сервере и работает нормально. Я могу запустить службу в своем браузере и получить ожидаемый результат. Проблема заключается в том, когда я пытаюсь заставить CXF-клиент вызвать службу.
В моем клиентском приложении я объявляю клиент со следующей конфигурацией spring;
<jaxrs:client id="myClient" inheritHeaders="true"
address="myhost/test"
serviceClass="com.example.MyService">
<jaxrs:headers>
<entry key="Accept" value="application/xml"/>
</jaxrs:headers>
<jaxrs:providers>
<ref bean="myJaxbXmlProvider"/>
<ref bean="myJsonProvider"/>
</jaxrs:providers>
</jaxrs:client>
<bean id="myJaxbXmlProvider" class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
<property name="jaxbElementClassMap" ref="myElementClassMap"/>
</bean>
<bean id="myJsonProvider" class="org.apache.cxf.jaxrs.provider.JSONProvider">
<property name="jaxbElementClassMap" ref="myElementClassMap"/>
</bean>
<util:map id="myElementClassMap">
<entry key="com.example.MyBean" value="bean"/>
</util:map>
Когда вызывается клиент, я получаю эту трассировку стека;
org.apache.cxf.jaxrs.client.Исключение ClientWebApplicationException: .Проблема с чтением ответного сообщения, класс: интерфейс java.util.Список, тип содержимого: application / xml.
….
Вызвано: javax.ws.rs.WebApplicationException: java.lang.ClassCastException: com.example.MyBean не может быть приведен к org.apache.cxf.jaxrs.provider.AbstractJAXBProvider$CollectionWrapper
Есть идеи?
Ответ №1:
Одним из вариантов является внедрение WebClient и использование, в данном случае,
webClient.getCollection(MyBean.class);
Что касается этого исключения:
Какую версию CXF вы используете? У нас есть много тестов для чтения явных коллекций…
MBean не квалифицируется как XmlRootElement ?
Ответ №2:
В CXF JAX-RS может быть ошибка, связанная с чтением явных коллекций компонентов, у которых нет аннотаций @XmlRootElement, и изучением этого.
Комментарии:
1. Добавлены аннотации JAXB, и это, похоже, исправило это. Я надеялся, что мне не придется этого делать.
Ответ №3:
List<Object> providers = new ArrayList<Object>();
providers.add( new JacksonJaxbJsonProvider() );
WebClient client=WebClient.create("http://localhost:6969/CXF3/rest",providers);
client = client.accept("application/json").type("application/json").path("/service/getAll");
Collection<? extends Person> order=client.getCollection(Person.class);
for(Person p:order){
System.out.println(p.getEname() " " p.getEmpid() " " p.getEsal());
}
Ответ №4:
Эта проблема исправлена в CXF, квалифицируйте класс MBean как обходной путь