使用spring RestTemplate消耗json+hal _embedded资源的问题。

问题描述 投票:3回答:1

我有一个简单的用例,在这个用例中,我想消耗一个用json+hal表示的资源集合。

我使用spring RestTemplate,并将其配置为使用Jackson2HalModule。当我调试我的代码时,我发现Response对象确实包含了准确的元数据(如页面和资源的数量)和响应头,但没有内容或链接。在过去的一天里,我在互联网上看了很多文章和指南,根据我的发现,我觉得我的自定义休息模板应该可以用于我的用例。

如果有人能在这方面提供任何启示,我将永远感激不尽。

我的服务代码如下。

@Service
public class EventServiceImpl extends BaseService implements EventService {

private static final String knownEntity = "59d786d642572853721728f6";

private static  String SERVICE_URL = "http://EVENTS-SERVER";

private static String EVENTS_PATH = "/events";


@Autowired
@LoadBalanced
protected RestTemplate restTemplate;

@Override
public ResponseEntity<PagedResources<Event>> fetchEventsList() {
    // acceptable media type
    List<MediaType> acceptableMediaTypes = Arrays.asList(HAL_JSON);

    // header
    HttpHeaders headers = new HttpHeaders();
    headers.setAccept(acceptableMediaTypes);

    HttpEntity<String> entity = new HttpEntity<String>(null, headers);

    ResponseEntity<PagedResources<Event>> response = getRestTemplateWithHalMessageConverter()
            .exchange(SERVICE_URL + EVENTS_PATH, HttpMethod.GET, entity, new ParameterizedTypeReference<PagedResources<Event>>(){});
    return response;
}

public RestTemplate getRestTemplateWithHalMessageConverter() {
    List<HttpMessageConverter<?>> existingConverters = restTemplate.getMessageConverters();
    List<HttpMessageConverter<?>> newConverters = new ArrayList<>();
    newConverters.add(getHalMessageConverter());
    newConverters.addAll(existingConverters);
    restTemplate.setMessageConverters(newConverters);
    return restTemplate;
}

private HttpMessageConverter getHalMessageConverter() {
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.registerModule(new Jackson2HalModule());
    MappingJackson2HttpMessageConverter halConverter = new TypeConstrainedMappingJackson2HttpMessageConverter(ResourceSupport.class);
    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    halConverter.setSupportedMediaTypes(Arrays.asList(HAL_JSON));
    halConverter.setObjectMapper(objectMapper);
    return halConverter;
}

我的简单模型是:

public class Event {

private String name;
private String location;
private int capacity;

public String getName() {
    return name;
}

public String getLocation() {
    return location;
}

public int getCapacity() {
    return capacity;
}

}

为了完整起见,这里是我试图消耗的hal+json的形状的样本。

{
"_embedded": {
    "events": [
        {
            "name": null,
            "location": null,
            "capacity": 0,
            "currentState": "CANCELLED",
            "_links": {
                "self": {
                    "href": "http://192.168.1.6:2221/events/59d786d642572853721728f6"
                },
                "event": {
                    "href": "http://192.168.1.6:2221/events/59d786d642572853721728f6"
                },
                "reinstate": {
                    "href": "http://192.168.1.6:2221/events/59d786d642572853721728f6/reinstate"
                },
                "reschedule": {
                    "href": "http://192.168.1.6:2221/events/59d786d642572853721728f6/reschedule"
                }
            }
        },
        {
            "name": null,
            "location": null,
            "capacity": 0,
            "currentState": "ADVERTISED",
            "_links": {
                "self": {
                    "href": "http://192.168.1.6:2221/events/59d7f14342572812ceca7fc6"
                },
                "event": {
                    "href": "http://192.168.1.6:2221/events/59d7f14342572812ceca7fc6"
                },
                "cancel": {
                    "href": "http://192.168.1.6:2221/events/59d7f14342572812ceca7fc6/cancel"
                },
                "reschedule": {
                    "href": "http://192.168.1.6:2221/events/59d7f14342572812ceca7fc6/reschedule"
                }
            }
        },
        {
            "name": null,
            "location": null,
            "capacity": 0,
            "currentState": "ADVERTISED",
            "_links": {
                "self": {
                    "href": "http://192.168.1.6:2221/events/59d7f14742572812ceca7fc7"
                },
                "event": {
                    "href": "http://192.168.1.6:2221/events/59d7f14742572812ceca7fc7"
                },
                "cancel": {
                    "href": "http://192.168.1.6:2221/events/59d7f14742572812ceca7fc7/cancel"
                },
                "reschedule": {
                    "href": "http://192.168.1.6:2221/events/59d7f14742572812ceca7fc7/reschedule"
                }
            }
        },
        {
            "name": null,
            "location": null,
            "capacity": 0,
            "currentState": "ADVERTISED",
            "_links": {
                "self": {
                    "href": "http://192.168.1.6:2221/events/59d7f14c42572812ceca7fc8"
                },
                "event": {
                    "href": "http://192.168.1.6:2221/events/59d7f14c42572812ceca7fc8"
                },
                "cancel": {
                    "href": "http://192.168.1.6:2221/events/59d7f14c42572812ceca7fc8/cancel"
                },
                "reschedule": {
                    "href": "http://192.168.1.6:2221/events/59d7f14c42572812ceca7fc8/reschedule"
                }
            }
        }
    ]
},
"_links": {
    "self": {
        "href": "http://192.168.1.6:2221/events{?page,size,sort}",
        "templated": true
    },
    "profile": {
        "href": "http://192.168.1.6:2221/profile/events"
    }
},
"page": {
    "size": 20,
    "totalElements": 4,
    "totalPages": 1,
    "number": 0
}

}

EDIT:我可以毫无问题地消费一个单独的Event,但我有一个简单的用例,我想消费一个用json+hal表示的资源集合。

java rest spring-boot jackson resttemplate
1个回答
0
投票

我有一个类似的问题,我最终使用了 org.springframework.hateoas.Resources

在我下面的例子中,这个对象位于 org.springframework.hateoas:spring-hateoas:jar:0.25.2.RELEASE牵引而来的 org.springframework.boot:spring-boot-starter-data-rest:jar:2.1.7.RELEASE所以很有可能它已经在你的classpath中,假设你声明了 spring-boot-starter-data-rest 依赖关系。

这是一个简单的例子(使用你的信息)。

RestTemplate restTemplate = new RestTemplate();
Resources<Event> resourceEvents = restTemplate.getForObject("http://192.168.1.6:2221/events", Resources.class);
List<Event> events = new ArrayList<>(resourceEvents.getContent());

可能会有一些问题让这个问题变得不那么直接,但希望这能为解决你的问题提供一个开始。

© www.soinside.com 2019 - 2024. All rights reserved.