Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用SpringHateOAS反序列化包含(_链接和_嵌入)的JSON_Java_Json_Spring_Jackson_Spring Hateoas - Fatal编程技术网

Java 使用SpringHateOAS反序列化包含(_链接和_嵌入)的JSON

Java 使用SpringHateOAS反序列化包含(_链接和_嵌入)的JSON,java,json,spring,jackson,spring-hateoas,Java,Json,Spring,Jackson,Spring Hateoas,我尝试调用返回以下格式数据的非常简单的json Web服务: { "_embedded": { "users": [{ "identifier": "1", "firstName": "John", "lastName": "Doe", "_links": { "self": { "href": "http

我尝试调用返回以下格式数据的非常简单的json Web服务:

{
    "_embedded": {
        "users": [{
            "identifier": "1",
            "firstName": "John",
            "lastName": "Doe",
            "_links": {
                "self": {
                    "href": "http://localhost:8080/test/users/1"
                }
            }
        },
        {
            "identifier": "2",
            "firstName": "Paul",
            "lastName": "Smith",
            "_links": {
                "self": {
                    "href": "http://localhost:8080/test/users/2"
                }
            }
        }]
    },
    "_links": {
     "self": {
       "href": "http://localhost:8080/test/users"
     }
   },
   "page": {
     "size": 20,
     "totalElements": 2,
     "totalPages": 1,
     "number": 0
   }
}
正如你所看到的,这是非常直截了当的。 我在解析链接时没有问题,我的POJO扩展了表单ResourceSupport。 下面是它们的样子:

UsersJson(根元素)

问题是,我希望jackson和spring能够足够聪明地解析_embedded属性并填充我的UsersJson.users属性,但事实并非如此

我尝试了在互联网上找到的各种方法,但我唯一能正常工作的方法是创建一个新类,充当_嵌入式包装器:

UsersJson(根元素)

嵌入式“包装器”

public类UsersEmbeddedListJson扩展了资源支持{
私人名单用户;
[…接受者和接受者…]
}
它能用,但我觉得很难看

然而,我认为RestTemplate的以下配置会起作用(特别是当我在Jackson2HalModule中看到EmbeddedMapper时),但它没有起作用:

        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        mapper.registerModule(new Jackson2HalModule());

        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        converter.setSupportedMediaTypes(MediaType.parseMediaTypes("application/hal+json"));
        converter.setObjectMapper(mapper);

        RestTemplate restTemplate = new RestTemplate(Collections.singletonList(converter));

        ResponseEntity<UsersJson> result = restTemplate.getForEntity("http://localhost:8089/test/users", UsersJson.class, new HashMap<String, Object>());
        System.out.println(result);
ObjectMapper mapper=new ObjectMapper();
configure(在未知属性上反序列化feature.FAIL,false);
registerModule(新Jackson2HalModule());
MappingJackson2HttpMessageConverter=新的MappingJackson2HttpMessageConverter();
setSupportedMediaTypes(MediaType.parseMediaTypes(“application/hal+json”);
setObjectMapper(映射器);
RestTemplate RestTemplate=新的RestTemplate(Collections.singletonList(converter));
ResponseEntity结果=restTemplate.getForEntity(“http://localhost:8089/test/users,UsersJson.class,new HashMap());
系统输出打印项次(结果);

有人能告诉我我缺少什么吗?

最后,我找到了一种更好的方法来使用这些应用程序/hal+jsonapi

SpringHateoas实际上提供了一个几乎可以随时使用的客户端:org.springframework.hateoas.client.Traverson

Traverson traverson = new Traverson(new URI("http://localhost:8080/test"), MediaTypes.HAL_JSON);
TraversalBuilder tb = traverson.follow("users");
ParameterizedTypeReference<Resources<UserJson>> typeRefDevices = new ParameterizedTypeReference<Resources<UserJson>>() {};
Resources<UserJson> resUsers = tb.toObject(typeRefDevices);
Collection<UserJson> users= resUsers .getContent();
Traverson-Traverson=new-Traverson(新URIhttp://localhost:8080/test),MediaTypes.HAL_JSON);
TraversalBuilder tb=traverson.follow(“用户”);
ParameterizedTypeReference typeRefDevices=新的ParameterizedTypeReference(){};
资源恢复者=tb.toObject(typeRefDevices);
集合用户=resUsers.getContent();
如您所见,我去掉了UsersJson和UsersEmbeddedListJson

下面是我添加的maven依赖项

    <dependency>
        <groupId>org.springframework.hateoas</groupId>
        <artifactId>spring-hateoas</artifactId>
        <version>0.19.0.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.plugin</groupId>
        <artifactId>spring-plugin-core</artifactId>
        <version>1.2.0.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>com.jayway.jsonpath</groupId>
        <artifactId>json-path</artifactId>
        <version>2.0.0</version>
    </dependency>

org.springframework.hateoas
春风
0.19.0.0发布
org.springframework.plugin
spring插件核心
1.2.0.1发布
com.jayway.jsonpath
json路径
2.0.0

必须将此添加到我的DTO中:

@JsonProperty("_links")
public void setLinks(final Map<String, Link> links) {
    links.forEach((label, link) ->  add(link.withRel(label)) );
}
@JsonProperty(“\u链接”)
公共无效设置链接(最终地图链接){
links.forEach((标签,链接)->添加(link.withRel(标签));
}

由于ResourceSupport没有链接的POJO标准/Json信号setter/constructor

我不得不使用自定义setter扩展我的DTO POJO,通过使用jackson作为映射器在REST客户端解析Spring Hateos的生成输出:

HREF=“HREF”和REL作为常量为“REL”

@JsonProperty("link")
public void setLink(final List<Map<String, String>> links) {
    if (links != null) {
        links.forEach(l ->
                {
                    final String[] rel = new String[1];
                    final String[] href = new String[1];
                    l.entrySet().stream().filter((e) -> e.getValue() != null)
                            .forEach(e -> {
                                if (e.getKey().equals(REL)) {
                                    rel[0] = e.getValue();
                                }
                                if (e.getKey().equals(HREF)) {
                                    href[0] = e.getValue();
                                }
                            });
                    if (rel[0] != null && href[0] != null) {
                        add(new Link(href[0], rel[0]));
                    }
                }
        );
    }
}
@JsonProperty(“链接”)
公共无效设置链接(最终列表链接){
如果(链接!=null){
链接。forEach(l->
{
最终字符串[]rel=新字符串[1];
最终字符串[]href=新字符串[1];
l、 entrySet().stream().filter((e)->e.getValue()!=null)
.forEach(e->{
如果(例如getKey().equals(REL)){
rel[0]=e.getValue();
}
如果(例如getKey().equals(HREF)){
href[0]=e.getValue();
}
});
如果(rel[0]!=null&&href[0]!=null){
添加(新链接(href[0],rel[0]);
}
}
);
}
}

默认情况下,Jackson不支持HAL\u嵌入式链接。您的包装器看起来是一个很好的方法。这也是值得一看的注释,但我没有使用它,所以不知道它是否有用。我面临着与您相同的问题。当我尝试你的建议使用
restemplate.follow(“用户”)
时,我得到了一个类似
的错误,期望在响应中找到与rel“users”相关的链接。从某种意义上说,这个错误是有意义的,因为我假设
follow
api期望它指向某个URL,但在本例中它不是。不确定我是否在这里做错了您的答案中没有使用变量
traverson
。此答案中的代码片段没有任何意义。this.restemplate.follow:这是什么。follow不是restTemplate的方法
Traverson traverson = new Traverson(new URI("http://localhost:8080/test"), MediaTypes.HAL_JSON);
TraversalBuilder tb = traverson.follow("users");
ParameterizedTypeReference<Resources<UserJson>> typeRefDevices = new ParameterizedTypeReference<Resources<UserJson>>() {};
Resources<UserJson> resUsers = tb.toObject(typeRefDevices);
Collection<UserJson> users= resUsers .getContent();
    <dependency>
        <groupId>org.springframework.hateoas</groupId>
        <artifactId>spring-hateoas</artifactId>
        <version>0.19.0.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.plugin</groupId>
        <artifactId>spring-plugin-core</artifactId>
        <version>1.2.0.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>com.jayway.jsonpath</groupId>
        <artifactId>json-path</artifactId>
        <version>2.0.0</version>
    </dependency>
@JsonProperty("_links")
public void setLinks(final Map<String, Link> links) {
    links.forEach((label, link) ->  add(link.withRel(label)) );
}
@JsonProperty("link")
public void setLink(final List<Map<String, String>> links) {
    if (links != null) {
        links.forEach(l ->
                {
                    final String[] rel = new String[1];
                    final String[] href = new String[1];
                    l.entrySet().stream().filter((e) -> e.getValue() != null)
                            .forEach(e -> {
                                if (e.getKey().equals(REL)) {
                                    rel[0] = e.getValue();
                                }
                                if (e.getKey().equals(HREF)) {
                                    href[0] = e.getValue();
                                }
                            });
                    if (rel[0] != null && href[0] != null) {
                        add(new Link(href[0], rel[0]));
                    }
                }
        );
    }
}