2016-07-13 9 views
1

Während Frühling REST-Client zu entwickeln, scheinen ein Problem:Wie RestTemplate Parse Antwort

  1. Ich habe nächste json:


{ 
"return": [ 
{ 
    "admin": false, 
    "alias": "", 
    "email": "", 
    "emailId": {"value": 0}, 
    "groups": [], 
    "id": {"value": 1}, 
    "locked": false, 
    "loggedInCount": 0, 
    "master": true, 
    "sms": "", 
    "smsId": {"value": 0}, 
    "type": "POWER", 
    "username": "NGCP" 
}, 
{ 
    "admin": false, 
    "alias": "", 
    "email": "", 
    "emailId": {"value": 0}, 
    "groups": [{"value": 2}], 
    "id": {"value": 3}, 
    "locked": false, 
    "loggedInCount": 0, 
    "master": false, 
    "sms": "", 
    "smsId": {"value": 0}, 
    "type": "POWER", 
    "username": "POLICY" 
} 
     ] 
} 

Modellklasse Benutzer zu speichern:

@JsonIgnoreProperties(ignoreUnknown = true) 
public class User { 

    public User(){ 

    } 

    private boolean admin; 

    private String alias; 

    private String email; 

    private String emailId; 

    private ArrayList<String> groups; 

    private String id; 

    private boolean locked; 

    private int loggedInCount; 

    private boolean master; 

    private String sms; 

    private String smsId; 

    private String type; 

    private String userName; 

//getter and setters 
} 

Jetzt verwende ich "RestTemplate", um das Ergebnis zu erhalten.

RestTemplate restTemplate = new RestTemplate(); 
ResponseEntity<User[]> response = restTemplate.exchange(URL_GET,HttpMethod.GET,request, User[].class); 

Und Fehler. Ich weiß, dass der Hauptschlüssel "result" ist, aber kann ich angeben, von wo restTemplate diesen JSON parsen soll?

Und es ist möglich, auf fileds liks "emailId" anzugeben, um direkten Wert zu erhalten? einige Vorlagen?

+0

Was meinst du mit „direct Wert erhalten“? –

+0

In diesem Feld habe ich wieder Paar, "Schlüssel - Wert". Ich muss nur den Wert – GVArt

+0

nehmen, was ist der Fehler? und was bedeutet "Hauptschlüssel ist Ergebnis"? –

Antwort

3
  1. Wie der "Hauptschlüssel ist Ergebnis":

    ein. Ich würde eine Wrapper-Klasse für die tatsächliche Nutzlast erstellen, wenn Sie mit nur einem dieser Art von Web-Service beschäftigen:

    b. Wenn Sie mit mehreren Webdiensten behandeln, in denen tatsächliche Nutzlast ist in „Rückkehr“ Feld würde ich eine generische Wrapper-Klasse erstellen:

    public class Return<T>{ 
        // Class property cannot be called "return" because it is Java reserved name. 
        @JsonProperty("return") 
        private T[] array; 
        .... getter and setter 
    } 
    

    Anruf zu RestRemplate:

    ResponseEntity<Return<User>> response = restTemplate.exchange(URL_GET, 
         HttpMethod.GET, request, new ParameterizedTypeReference<Return<User>>(){}); 
    User[] usersArray = response2.getBody().getArray(); 
    
  2. Ab dem Eigenschaftswertes in JSON Attribute "Wert" genannt Ich würde zwei benutzerdefinierte JsonDeserializer (s) erstellen: eine für Einzelwert und eine für Array von Werten und kommentieren jede Eigenschaft mit @JsonDeserialize, wo es gilt:

    Einzelwert dereria lizer:

    public class StringValueDeserializer extends JsonDeserializer<String>{ 
    
        @Override 
        public String deserialize(JsonParser parser, DeserializationContext ctxt) 
          throws IOException, JsonProcessingException { 
         ObjectCodec codec = parser.getCodec(); 
         TreeNode node = codec.readTree(parser); 
         JsonNode value = (JsonNode)node.get("value"); 
    
         if (value != null){ 
          return value.asText(); 
         } 
         return null; 
        } 
    } 
    

    Array von Werten derializer:

    public class StringArrayValueDeserializer extends JsonDeserializer<List<String>>{ 
    
        @Override 
        public List<String> deserialize(JsonParser parser, DeserializationContext ctxt) 
         throws IOException, JsonProcessingException { 
    
         List<String> ret = new ArrayList<>(); 
    
         ObjectCodec codec = parser.getCodec(); 
         TreeNode node = codec.readTree(parser); 
    
         if (node.isArray()){ 
          for (JsonNode n : (ArrayNode)node){ 
           JsonNode value = n.get("value"); 
           if (value != null){ 
            ret.add(value.asText()); 
           } 
          } 
         } 
         return ret; 
        } 
    } 
    

    Sie sind hier neue User.class:

    public class User { 
    
        private boolean admin; 
    
        private String alias; 
    
        private String email; 
    
        @JsonDeserialize(using = StringValueDeserializer.class) 
        private String emailId; 
    
        @JsonDeserialize(using = StringArrayValueDeserializer.class) 
        private ArrayList<String> groups; 
    
        @JsonDeserialize(using = StringValueDeserializer.class) 
        private String id; 
    
        private boolean locked; 
    
        private int loggedInCount; 
    
        private boolean master; 
    
        private String sms; 
    
        @JsonDeserialize(using = StringValueDeserializer.class) 
        private String smsId; 
    
        private String type; 
    
        private String username; 
        .... getter and setter 
    } 
    

Viel Glück!

+0

Ihre Antwort ist fantastisch, danke! – GVArt

+1

:) Sie sind herzlich willkommen! –

1

Sie können die Anmerkung @JsonRootName verwenden, um das Stammelement in Ihrer Antwort anzugeben. Also versuchen Sie dies:

@JsonIgnoreProperties(ignoreUnknown = true) 
@JsonRootName(value ="result") 
public class User { 

    public User(){ 

    } 

    private boolean admin; 

    .... 
} 
+0

Wenn Sie User-Objekt zum Erstellen oder Aktualisieren verwenden, was wird der Effekt von JSON-Root-Namen-Anotierung sein? Oder das nur zum Lesen von Daten. –

1

Sie können auch die JsonPath Bibliothek verwenden, um durch json zu navigieren:

String json = restTemplate.exchange(URL_GET,HttpMethod.GET,request, String.class); 
DocumentContext document = JsonPath.parse(content, json); 
List<User> users = document.read("$.return.*", new TypeRef<List<User>>() {});