2016-08-12 6 views
0

JavaでRESTful Webサービスを作成しています。JerseyのGenericEntityを利用する

  • のGlassFish 3
  • エクリプスEEケプラー

注釈付き

  • JDK V7
  • ジャージー(アプリケーションサーバの一部)(ジャワ6に基づく):私が使用技術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() 
    

    、ここでは、クライアントの私の第二のバージョンを来て、今ジャージークライアント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) 
    

    、私が望むのは、クライアントのエンドポイントでサービスからの出力を読み取ることだけです。 Jersey/Java EEのイン・アンド・アウトをよりよく理解するために、GenericEntityオブジェクトを使用したいと思います。 この問題を回避する方法はありますか?

  • 答えて

    0

    これは、少なくともjersey-client.jar APIの点では解決策です。 私は、次の行を追加するために必要な:

    List<EntityJAXBxml> g = resource.get(new GenericType<List<EntityJAXBxml>>(){}); 
        EntityJAXBxml entity = g.get(1); 
        System.out.println(g.size()+" : "+entity.getdValue()+" : Element count: "+entity.getList().size()); 
        //Also valid 
        //ClientResponse response = resource.get(ClientResponse.class); 
        //List<EntityJAXBxml> entity = response.getEntity(new GenericType<List<EntityJAXBxml>>(){}); 
    
        //EntityJAXBxml g = entity.get(1); 
        //System.out.println(entity.size()+" : "+g.getdValue()+" : Element count: "+g.getList().size()); 
    

    をそしてあなたは、クライアント側での一般的な実体を読むことができます。

    関連する問題