利用泽西岛的GenericEntity

时间:2016-08-12 18:00:17

标签: rest jersey java-ee-6 glassfish-3 rest-client

我用Java编写RESTful Web服务。我使用的技术:

  • GlassFish 3(基于Java 6)
  • JDK v7
  • Jersey(应用程序服务器的一部分)
  • Eclipse EE Kepler

带注释的POJO:

     @XmlRootElement(name = "entity")
    @XmlType(propOrder={"stValue", "dValue", "list"})
    @XmlAccessorType(XmlAccessType.FIELD)
    public final class EntityJAXBxml {

        @XmlAttribute
        private int id

 = 0;
    @XmlElement
    private String stValue = "";
    @XmlElement
    private double dValue = 0.0;
    @XmlElement
    @XmlElementWrapper(name="elements")
    private List<Integer> list = null;

    public EntityJAXBxml(){}    

    public EntityJAXBxml(int id, String stValue, double dValue,
            List<Integer> list) {
        super();
        this.id = id;
        this.stValue = stValue;
        this.dValue = dValue;
        this.list = list;
    }
... Getters, setters

这是我的服务方式:

@GET
@Produces(MediaType.APPLICATION_XML)
@Path("/receiveXMLInGenericEntity")
public Response receiveXMLInGenericEntity(){
    EntityJAXBxml entity = new EntityJAXBxml(1, "String_value", 193.7, util.generateIntList());
    EntityJAXBxml entity_1 = new EntityJAXBxml(2, "New_string_value", 439.5, util.generateIntList());

    List<EntityJAXBxml> list = new ArrayList<>(2);
    list.add(entity);
    list.add(entity_1);

    GenericEntity<List<EntityJAXBxml>> generic = new GenericEntity<List<EntityJAXBxml>>(list){};        
    return Response.ok().entity(generic).build();
}

当我通过Web浏览器上的URI访问资源时,它会打印XML文档。因此,到目前为止它工作正常。 当我想通过非浏览器客户端从服务获得响应时出现问题。 例如,以下是我的客户端实现:

private void receiveXMLInGenericEntity(String strUrl, String method){
    HttpURLConnection connect = null;
    try {
        URL url = new URL(strUrl);
        connect = (HttpURLConnection)url.openConnection();

        connect.setRequestProperty("Accept", MediaType.APPLICATION_XML);// Accept from server
        connect.setRequestMethod(method);//GET

        connect.connect();
        Class cls = new GenericEntity<List<EntityJAXBxml>>(new ArrayList<EntityJAXBxml>()){}.getClass();

        GenericEntity<List<EntityJAXBxml>> generic = (GenericEntity<List<EntityJAXBxml>>)JAXB.unmarshal(connect.getInputStream(), cls);
        List<EntityJAXBxml> entity = generic.getEntity();

        System.out.println("GenericEntity: "+entity.size());
    }
    catch(IOException e){ e.printStackTrace();}
}

它给了我以下例外:

 Exception in thread "main" javax.xml.bind.DataBindingException: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
drill.rest.client.ClientXmlV6$1 is a non-static inner class, and JAXB can't handle those.
    this problem is related to the following location:
        at drill.rest.client.ClientXmlV6$1

    at javax.xml.bind.JAXB.unmarshal(JAXB.java:226)
    at drill.rest.client.ClientXmlV6.receiveXMLInGenericEntity(ClientXmlV6.java:199)
    at drill.rest.client.ClientXmlV6.main(ClientXmlV6.java:68)
Caused by: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
drill.rest.client.ClientXmlV6$1 is a non-static inner class, and JAXB can't handle those.
    this problem is related to the following location:
        at drill.rest.client.ClientXmlV6$1

    at com.sun.xml.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:106)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:466)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:298)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:141)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1163)
    at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:145)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:248)
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:235)
    at javax.xml.bind.ContextFinder.find(ContextFinder.java:432)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:637)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:584)
    at javax.xml.bind.JAXB$Cache.<init>(JAXB.java:112)
    at javax.xml.bind.JAXB.getContext(JAXB.java:139)
    at javax.xml.bind.JAXB.unmarshal(JAXB.java:223)
    ... 2 more

这意味着以下获取Class类型值的方法是错误的:

Class cls = new GenericEntity<List<EntityJAXBxml>>(new ArrayList<EntityJAXBxml>()){}.getClass();

但是我需要那个类型值,因为它需要通过以下方法输入:

JAXB.unmarshal()

现在,它来到我的第二个版本的客户端,现在利用Jersey客户端API:

private void receiveXMLInGenericEntityJerseyClient(String strUrl, String method){
    Client client = Client.create();
    WebResource resource = client.resource(strUrl);

    resource.accept(MediaType.APPLICATION_XML);
    resource.method(method);

    GenericType type = new GenericType(new ArrayList<EntityJAXBxml>(Collections.EMPTY_LIST).getClass()){};      
    GenericEntity<List<EntityJAXBxml>> generic = resource.get(type);
}

它有这个例外:

    Aug 12, 2016 6:45:48 PM com.sun.jersey.api.client.ClientResponse getEntity
SEVERE: A message body reader for Java class java.util.ArrayList, and Java type class java.util.ArrayList, and MIME media type application/xml was not found
Aug 12, 2016 6:45:48 PM com.sun.jersey.api.client.ClientResponse getEntity
SEVERE: The registered message body readers compatible with the MIME media type are:
application/xml ->
  com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$App
  com.sun.jersey.core.impl.provider.entity.DocumentProvider
  com.sun.jersey.core.impl.provider.entity.SourceProvider$StreamSourceReader
  com.sun.jersey.core.impl.provider.entity.SourceProvider$SAXSourceReader
  com.sun.jersey.core.impl.provider.entity.SourceProvider$DOMSourceReader
  com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$App
  com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$App
  com.sun.jersey.core.impl.provider.entity.XMLRootObjectProvider$App
*/* ->
  com.sun.jersey.core.impl.provider.entity.FormProvider
  com.sun.jersey.core.impl.provider.entity.MimeMultipartProvider
  com.sun.jersey.core.impl.provider.entity.StringProvider
  com.sun.jersey.core.impl.provider.entity.ByteArrayProvider
  com.sun.jersey.core.impl.provider.entity.FileProvider
  com.sun.jersey.core.impl.provider.entity.InputStreamProvider
  com.sun.jersey.core.impl.provider.entity.DataSourceProvider
  com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$General
  com.sun.jersey.core.impl.provider.entity.ReaderProvider
  com.sun.jersey.core.impl.provider.entity.DocumentProvider
  com.sun.jersey.core.impl.provider.entity.SourceProvider$StreamSourceReader
  com.sun.jersey.core.impl.provider.entity.SourceProvider$SAXSourceReader
  com.sun.jersey.core.impl.provider.entity.SourceProvider$DOMSourceReader
  com.sun.jersey.json.impl.provider.entity.JSONJAXBElementProvider$General
  com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$General
  com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$General
  com.sun.jersey.core.impl.provider.entity.XMLRootObjectProvider$General
  com.sun.jersey.core.impl.provider.entity.EntityHolderReader
  com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider$General
  com.sun.jersey.json.impl.provider.entity.JSONListElementProvider$General
  com.sun.jersey.moxy.MoxyMessageBodyWorker
  com.sun.jersey.moxy.MoxyListMessageBodyWorker

Exception in thread "main" com.sun.jersey.api.client.ClientHandlerException: A message body reader for Java class java.util.ArrayList, and Java type class java.util.ArrayList, and MIME media type application/xml was not found
    at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:550)
    at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:524)
    at com.sun.jersey.api.client.WebResource.handle(WebResource.java:686)
    at com.sun.jersey.api.client.WebResource.get(WebResource.java:196)
    at drill.rest.client.ClientXmlV6.receiveXMLInGenericEntityJerseyClient(ClientXmlV6.java:216)
    at drill.rest.client.ClientXmlV6.main(ClientXmlV6.java:69)

最后,我想要的只是在客户端点读取服务的输出。我想使用GenericEntity对象,以便更好地理解Jersey / Java EE的细节。 任何想法如何解决这个问题?

0 个答案:

没有答案