2014-09-16 3 views
1
public class RESTDataServiceClient{  
    private Client client; 
    private String dataServiceUri; 
    private String dataServiceResource;  
    private CustomData customData; 

    public RESTDataServiceClient(String dataServiceUri, String dataServiceResource, Client client){ 
     this.client = client; 
     this.dataServiceUri = dataServiceUri; 
     this.dataServiceResource = dataServiceResource; 
    } 

    @Override 
    public CustomData getCustomData() { 
     WebTarget dataServiceTarget = client.target(dataServiceUri).path(dataServiceResource); 
     Invocation.Builder invocationBuilder = dataServiceTarget.request(MediaType.APPLICATION_JSON_TYPE); 
     Response response = invocationBuilder.get(); 
     myCustomData = response.readEntity(CustomData.class); 
     return myCustomData; 
    } 
} 

CustomData.java 
public class CustomData{ 
     private TLongObjectMap<Map<String, TIntIntMap>> data; 
     public CustomData() { 
      this.data = new TLongObjectHashMap<>(); 
    } 
    //getter and setter 
} 

échantillon contenu JSONclient Jersey lire la réponse JSON en objet personnalisé

{"50000":{"testString":{"1":10}},"50001":{"testString1":{"2":11}} } 

Je suis en train d'obtenir des données à partir d'un service de données qui va renvoyer les données dans un format JSON. J'essaye d'écrire un client pour lire ce JSON dans un objet personnalisé. CustomData contient une structure de données de carte en grappe imbriquée. nous avons écrit un sérialiseur personnalisé pour cela et la partie serveur fonctionne correctement. Je suis incapable d'obtenir le client de repos lire les données dans un objet, mais la lecture dans la chaîne fonctionne. J'ai essayé au-dessus du code collé avec les données d'échantillon et j'obtiens l'erreur ci-dessous.

javax.ws.rs.ProcessingException: Error reading entity from input stream. 
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:866) 
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:783) 
    at org.glassfish.jersey.client.ClientResponse.readEntity(ClientResponse.java:326) 
    at org.glassfish.jersey.client.InboundJaxrsResponse$1.call(InboundJaxrsResponse.java:111) 
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315) 
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297) 
    at org.glassfish.jersey.internal.Errors.process(Errors.java:228) 
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:399) 
    at org.glassfish.jersey.client.InboundJaxrsResponse.readEntity(InboundJaxrsResponse.java:108) 
    at com.sample.data.RESTDataServiceClient.getCustomData(RESTDataServiceClient.java:42) 

Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "50000" (class com.sample.data.CustomData), not marked as ignorable (0 known properties: ]) 
at [Source: org.glassfish.jersey.me[email protected]2cb89281; line: 1, column: 14] (through reference chain: com.sample.data.CustomData["50000"]) 
    at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:51) 
    at com.fasterxml.jackson.databind.DeserializationContext.reportUnknownProperty(DeserializationContext.java:671) 
    at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:773) 
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1297) 
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1275) 
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:247) 
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:118) 
    at com.fasterxml.jackson.databind.ObjectReader._bind(ObjectReader.java:1233) 
    at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:677) 
    at com.fasterxml.jackson.jaxrs.base.ProviderBase.readFrom(ProviderBase.java:777) 
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.invokeReadFrom(ReaderInterceptorExecutor.java:264) 
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:234) 
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:154) 
    at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1124) 
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:851) 
    ... 38 more 
+0

Quelle version de trove utilisez-vous? –

+0

J'utilise trove4j 3.0.3 – srini

Répondre

1

TLongObjectMap n'est pas deserializable hors de la boîte, alors comment vous avez fait un sérialiseur personnalisé vous devez également mettre en œuvre un désérialiseur personnalisé. Vous pouvez les intégrer dans un module et l'ajouter à votre ObjectMapper.

It looks like there is a Trove module in development right now, que vous pouvez télécharger et ajouter à votre ObjectMapper comme dans l'exemple ci-dessous. L'implémentation TIntObjectMapDeserializer dans ce lien est beaucoup plus robuste que ma solution, donc je recommanderais d'utiliser cette classe dans votre projet si possible.

Si vous voulez essayer d'écrire vous-même, voici un point de départ qui correctement désérialise votre exemple fourni:

public class FakeTest { 
    @Test 
    public void test() throws Exception { 
     ObjectMapper om = new ObjectMapper(); 
     om.registerModule(new CustomModule()); 
     String s = "{\"50000\":{\"testString\":{\"1\":10}},\"50001\":{\"testString1\":{\"2\":11}} }"; 
     CustomData cd = om.readValue(s, CustomData.class); 
     System.out.println(cd.getData()); 
    } 

    public static class CustomData { 
     private TLongObjectMap<Map<String, TIntIntMap>> data; 

     public CustomData() { 
      this.data = new TLongObjectHashMap<>(); 
     } 

     public TLongObjectMap<Map<String, TIntIntMap>> getData() { return data; } 

     public void setData(TLongObjectMap<Map<String, TIntIntMap>> data) { this.data = data; } 
    } 

    public static class CustomModule extends SimpleModule { 
     public CustomModule() { 
      addSerializer(CustomData.class, new CustomSerializer()); 
      addDeserializer(CustomData.class, new CustomDeserializer()); 
     } 

     public static class CustomSerializer extends JsonSerializer<CustomData> { 
      @Override 
      public void serialize(CustomData value, JsonGenerator jgen, SerializerProvider provider) throws IOException { 
       // add custom serializer here 
      } 
     } 

     public static class CustomDeserializer extends JsonDeserializer<CustomData> { 
      @Override 
      public CustomData deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { 
       TLongObjectMap<Map<String, TIntIntMap>> data = new TLongObjectHashMap<>(); 
       ObjectNode node = jsonParser.getCodec().readTree(jsonParser); 
       Iterator<Map.Entry<String,JsonNode>> fields = node.fields(); 
       while (fields.hasNext()) { 
        Map.Entry<String, JsonNode> entry = fields.next(); 
        ObjectNode value = (ObjectNode) entry.getValue(); 
        Map.Entry<String, JsonNode> innerField = value.fields().next(); 
        ObjectNode innerNode = (ObjectNode) innerField.getValue(); 
        Map.Entry<String, JsonNode> innerInnerField = innerNode.fields().next(); 
        TIntIntMap intMap = new TIntIntHashMap(); 
        intMap.put(Integer.parseInt(innerInnerField.getKey()), innerInnerField.getValue().asInt()); 
        Map<String, TIntIntMap> innerMap = Collections.singletonMap(innerField.getKey(), intMap); 
        data.put(Long.parseLong(entry.getKey()), innerMap); 
       } 
       CustomData customData = new CustomData(); 
       customData.setData(data); 
       return customData; 
      } 
     } 
    } 
} 
Questions connexes