简体   繁体   中英

Map JSON leaf to an object via RestTemplate postForObject

Working with restful api that returns a json string. The format is

{
  "status": "ok",
  "result": { <the method result> }
}

I am trying to map the response for user profile to UserProfile.class

MultiValueMap<String, String> parameters = new LinkedMultiValueMap<String, String>();
parameters.set("method", "currentUser");
URI url = buildUri("users/show.json");
UserProfile profile = this.getRestTemplate().postForObject(url, parameters, UserProfile.class );

User profile has all the fields from response result. if I add fields String status, UserProfile result, it maps the UserProfile to result and I can extract it from there, but that feels a little wrong.

I want postForObject function to map the JSON response relevant leaf "result" to UserProfile.class

To me the clearest approach would be to map the response result to an object which contains the user profile object. You would avoid unnecessary complication doing custom deserialization and allow you to access the status code. You could even make the response result object generic so it would work for any type of the content.

Here is an example using Jackon's object mapper. In Spring you would need to use ParameterizedTypeReference to pass the generic type information (see this answer ):

public class JacksonUnwrapped {

    private final static String JSON = "{\n" +
            "  \"status\": \"ok\",\n" +
            "  \"result\": { \"field1\":\"value\", \"field2\":123 }\n" +
            "}";


    public static class Result<T> {
        public final String status;
        public final T result;

        @JsonCreator
        public Result(@JsonProperty("status") String status,
                      @JsonProperty("result") T result) {
            this.status = status;
            this.result = result;
        }

        @Override
        public String toString() {
            return "Result{" +
                    "status='" + status + '\'' +
                    ", result=" + result +
                    '}';
        }
    }

    public static class UserProfile {
        public final String field1;
        public final int field2;

        @JsonCreator
        public UserProfile(@JsonProperty("field1") String field1,
                           @JsonProperty("field2") int field2) {
            this.field1 = field1;
            this.field2 = field2;
        }

        @Override
        public String toString() {
            return "UserProfile{" +
                    "field1='" + field1 + '\'' +
                    ", field2=" + field2 +
                    '}';
        }
    }

    public static void main(String[] args) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        Result<UserProfile> value = mapper.readValue(JSON, new TypeReference<Result<UserProfile>>() {});
        System.out.println(value.result);
    }

}

Output:

UserProfile{field1='value', field2=123}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM