如何使用Jackson /其他库将json响应对象映射到首选格式?

时间:2016-02-04 02:38:21

标签: java json spring spring-boot jackson

我从第三方网络服务获得以下JSON响应格式:

{
    "meta": {
        "code": 200,
        "requestId": "1"
    },
    "response": {
        "locations": [
            {
                "id": "1",
                "name": "XXX",
                "contact": {
                    phone: '123',
                    email: 'abc'
                },
                "location": {
                    "address": [
                        "Finland"
                    ]
                }
            },
            {
                // another location
            }
        ]
    }
}

以下是我应该从我自己的网络服务回复的内容:

[
    {
        "id": "1",
        "name": "XXX",
        "phone": '123',
        "address": "Finland"
    },
    {
        // another location
    }
]

我该怎么办?我已经阅读了一些关于杰克逊的好东西但是只有几个简单的例子,你将一些简单的JSON obj映射到POJO。在我的例子中,我需要删除一些节点,并在层次结构中更深入地遍历以获取嵌套值。到目前为止,这是我在春季启动应用中的宝贝步骤:

    @GET
    @Path("{query}")
    @Produces("application/json")
    public String getVenues(@PathParam("query") String query){
        return client.target(url).queryParam("query",query).request(...).get(String.class)
    }

欢迎任何帮助,指示和建议!

2 个答案:

答案 0 :(得分:4)

您正在使用JAX-RS注释而不是Spring Web服务注释。你可以使这个工作,但我建议使用默认的Spring注释,因为如果你使用spring boot starter依赖项,那些都是为你自动配置的。

首先 - 您需要创建像请求和响应一样设置的类。像这样:

public class ThirdPartyResponse {   
    MetaData meta;
    Response response;
}

public class Response {
    List<Location> locations;
}

public class MetaData {
    String code;
    String requestId;    
}

public class Location {
    String id;
    String name;
    Contact contact;
    LocationDetails location;
}

public class Contact {
    String phone;
    String email;
}

public class LocationDetails {
    List<String> address;
}

您可以使用Jackson注释来自定义反序列化,但默认情况下,它会按照名称和您可能期望的类型逻辑映射到字段(名为&#34的JSON列表;位置&#34;映射到您的列表中对象名为&#34; locations&#34;等。)

接下来,您将要为您的服务使用@RestController带注释的类,这会使用RestTemplate向第三方服务进行服务调用,例如:

@RestController
public class Controller {

    @Value("${url}")
    String url;

    @RequestMapping("/path"
            method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public List<Location> locations(@RequestParam String query) {

        // RestTemplate will make the service call and handle the 
        // mapping from JSON to Java object

        RestTemplate restTemplate = new RestTemplate();
        ThirdPartyResponse response = restTemplate.getForObject(url, ThirdPartyResponse.class);

        List<Location> myResponse = new List<>();            

        // ... do whatever processing you need here ...

        // this response will be serialized as JSON "automatically"
        return myResponse;
    }
}

正如您所看到的,Spring Boot抽象了许多JSON处理并使其变得非常轻松。

看看Spring的指南非常有帮助:

使用RestTemplate消费服务 http://spring.io/guides/gs/consuming-rest/

使用@RestController创建Web服务 https://spring.io/guides/gs/rest-service/

答案 1 :(得分:0)

这可以使用google api JacksonFactory 来完成。 以下是我建议的解决方案。

首先,你应该创建一个与你收到的json数据和你想要转换的json数据相对应的pojo类。

使用google api客户端将密钥映射到pojo。

以下是与你收到的json数据相对应的pojo类。

 import com.google.api.client.util.Key;
 Class Response{
 @Key("locations")
 List<FromLocations> fromLocations;
 }


 import com.google.api.client.util.Key;
 Class FromLocations
 {
 @Key("id")
 String id;
 @Key("name")
 String name;
 @Key("contact")
 Contact contact;
 @Key("location")
 Location location;
 }  

此处Contact和Loaction将是另一个使用相同策略的类;

以下是与你要转换的json相对应的pojo。

 Class ToLocations{
 String id;
 String name;
 String phone;
 String address;
 }

现在你可以将包含json objec的requset解析为fromLocations类,如下所示。

String responseMeta = response.parseAsString();
JSONObject queryJsonObject = new JSONObject(responseMeta);
if(queryJsonObject.has("locations")){
Response response = JacksonFactory.getDefaultInstance().fromString(responseMeta,Response.class);
List<FromLocations> fromLocationsList = response.getFromLocations();
}   

下一步是迭代列表fromLocationsList并从每个FromLocations对象中获取所需的值,并将其添加到ToLocations对象。

接下来,ToLocations对象可以将其添加到列表中并将其转换为json。