Правильный способ преобразования ссылки Spring HATEOAS на объект

У меня есть очень простой контроллер, который делает HTTP-запрос и получает некоторые ресурсы в формате HATEOAS.

package com.provider.spring.controller;

import java.util.List;

import org.springframework.hateoas.Link;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.client.RestTemplate;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.provider.employee.EmployeeDTO;
import com.provider.http.HttpComponentsClientHttpRequestFactoryBasicAuth;
import com.provider.spring.rest.Resource;

@Controller
public class EmployeeController {

    private static final String REL_SELF = "self";
    private static final String REL_SEARCH = "search";
    private static final String REL_EMPLOYEE = "employee";
    private static final String RESOURCE_URI = "http://localhost:8080/employees";

    private RestTemplate restTemplate = new RestTemplate(new HttpComponentsClientHttpRequestFactoryBasicAuth("user", "password"));
    private List<EmployeeDTO> employees;


    @RequestMapping("/employees")
    public String getAllEmployees() {

        String result = null;
        try {
            String resultBody = restTemplate.getForObject(RESOURCE_URI, String.class);
            ObjectMapper objectMapper = new ObjectMapper();
            Resource<EmployeeDTO> resource = objectMapper.readValue(resultBody, Resource.class);

            // Get objects with relation "employee"
            for(Link l : resource.getLinks()) {
                if(l.getRel().equals(REL_EMPLOYEE)) {
                    // TODO: Construct EmployeeDTO from Link.
                    // TODO: Add EmployeeDTO to list.
                }
            }
        }
        catch(Exception e) {
            e.printStackTrace();
            result = "error";
            return result;
        }
        return result;
    }
}

Существует ли предпочтительный или стандартный способ преобразования ссылок в объекты?

Подробнее о EmployeeDTO см. здесь: https://gist.github.com/Xerosigma/64469a30355f5de0228a


person Nestor Ledon    schedule 12.09.2014    source источник
comment
Можем ли мы увидеть класс EmployeeDTO? Было бы полезно увидеть целевой класс, экземпляр которого мы пытаемся создать.   -  person david.joyce13    schedule 13.09.2014
comment
Конечно! Вот Gist, я также включил свой последний контроллер, который, к сожалению, включает мои неудачные попытки. gist.github.com/Xerosigma/64469a30355f5de0228a   -  person Nestor Ledon    schedule 13.09.2014


Ответы (2)


Пара способов сделать это с Джексоном:

Без пользовательского конвертера:

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new Jackson2HalModule());
RestTemplate restTemplate= new RestTemplate();

String resultBody = restTemplate.getForObject(link.getHref(), String.class);
EmployeeDTO resource = objectMapper.readValue(resultBody, EmployeeDTO.class);

С пользовательским конвертером:

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new Jackson2HalModule());
RestTemplate restTemplate= new RestTemplate();

MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setObjectMapper(objectMapper);
restTemplate.setMessageConverters(Collections.<HttpMessageConverter<?>> singletonList(converter));
EmployeeDTO resource = restTemplate.getForObject(link.getHref(), EmployeeDTO.class);
person Nestor Ledon    schedule 18.09.2014
comment
Я попробовал второй вариант (с пользовательским преобразователем), но все переменные в объекте EmployeeDTO равны нулю. Вы знаете, почему я получаю ноль? Заранее спасибо. - person mona; 07.11.2014
comment
@mona, не могли бы вы составить список всех соответствующих классов, чтобы я мог взглянуть? Спасибо. - person Nestor Ledon; 07.11.2014
comment
@mona У меня точно такой же сценарий. Вы когда-нибудь создавали этот Gist? - person Christian Bongiorno; 19.04.2016
comment
@Xerosigma Я также попробовал вариант 2, и Джексон жалуется на неизвестные поля в моем Dto, что определенно неверно. Это также может объяснить нулевую проблему, с которой мы с Моной столкнулись. - person Christian Bongiorno; 19.04.2016
comment
@ChristianBongiorno, давайте посмотрим, сможем ли мы понять это, не могли бы вы опубликовать суть трассировки стека, чтобы я мог взглянуть? - person Nestor Ledon; 21.04.2016

Вы можете зарегистрировать некоторые MessageConverters в конструкторе RestTemplate или использовать setMessageConverters. Оба принимают список HttpMessageConverters в качестве параметра. Если вы настроили его таким образом, вы можете использовать обмен или метод getForObject с ожидаемым типом ресурса. RestTemplate будет проходить через все преобразователи и проверять, может ли он преобразовать json/xml/... в ваш объект.

Вот пример:

List<HttpMessageConverter<?>> converters = new LinkedList<>();
converters.add(new MappingJacksonHttpMessageConverter());
RestTemplate template = new RestTemplate(converters);
// or use the set method
template.setMessageConverters(converters);
// make url call
Resource<EmployeeDTO> resource = template.getForObject("url", Resource.class);
person Waldemar Schneider    schedule 16.09.2014