3

I have a very simple controller the makes an HTTP request and receives some resources in HATEOAS format.

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;
    }
}

Is there an existing prefered or standard way of converting Links to Objects?

See here for details on the EmployeeDTO: https://gist.github.com/Xerosigma/64469a30355f5de0228a

Nestor Ledon
  • 1,925
  • 2
  • 23
  • 36
  • 1
    Can we see the EmployeeDTO class? It would be helpful to see the target class we're trying to instantiate. – david.joyce13 Sep 13 '14 at 00:36
  • Sure! Here's a Gist, I've also included my latest controller, which includes my failed attempts unfortunately. https://gist.github.com/Xerosigma/64469a30355f5de0228a – Nestor Ledon Sep 13 '14 at 06:00

2 Answers2

5

A couple ways to do this with Jackson:

Without custom converter:

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);

With custom converter:

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);
Nestor Ledon
  • 1,925
  • 2
  • 23
  • 36
  • I tried the 2nd option (with custom convertor), but the variables in the EmployeeDTO object are all null. Do you know why I am getting null? Thanks in advance. – mona Nov 06 '14 at 21:30
  • @mona could you make a Gist of all relevent classes so I can take a look? Thanks. – Nestor Ledon Nov 06 '14 at 22:00
  • 1
    @mona I am getting the exact same scenario. Did you ever produce that Gist? – Christian Bongiorno Apr 19 '16 at 18:07
  • 1
    @Xerosigma I also tried option 2, and Jackson is complaining about unknown fields in my Dto -- which is definitely not correct. This might also explain the null problem mona and I are having – Christian Bongiorno Apr 19 '16 at 18:08
  • @ChristianBongiorno let's see if we can figure this one out, could you post a Gist of the stacktrace so I can have a look? – Nestor Ledon Apr 21 '16 at 14:52
-1

You can register some MessageConverters in the constructor of the RestTemplate or use the setMessageConverters. Both take a List of HttpMessageConverters as a parameter. If you have it configured like that, you can use the exchange or the getForObject-method with your expected resource-type. The RestTemplate will run through all the converters and check if it can convert the json/xml/... to your object.

Here is an example:

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);