8

I am using spring-data-rest to expose REST API. One of my search method returns list of entities. The repository and rest response as follows

List<Order> findByKeywordContaining(String keyword);

Search Response:

{  
   "_embedded":{  
      "orders":[  
         {  
            "keyword":"Iron mattress",
            "name":"Hostel",
            "_links":{  
               "self":{  
                  "href":"http://localhost:8081/orders/2"
               },
               "order":{  
                  "href":"http://localhost:8081/orders/2"
               }
            }
         },
         {  
            "keyword":"Iron",
            "name":"Weat strong",
            "_links":{  
               "self":{  
                  "href":"http://localhost:8081/orders/40"
               },
               "order":{  
                  "href":"http://localhost:8081/orders/40"
               }
            }
         }
      ]
   },
   "_links":{  
      "self":{  
         "href":"http://localhost:8081/orders/search/findByKeywordContaining?keyword=iron"
      }
   }
}

Now I am using RestTemplate to consume this response to process in client side as follows

List<Order> orders = restOperations.exchange(new URI(url), HttpMethod.GET, null, new ParameterizedTypeReference<Resource<List<Order>>>() {}).getBody().getContent();

The above code works fine for a single object in response, but if the response contains multiple objects. The code throws the following error

org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Unrecognized field "_embedded" (class org.springframework.hateoas.Resource), not marked as ignorable (3 known properties: , "links", "content", "page"])
at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@6a2bc870; line: 2, column: 18] (through reference chain: org.springframework.hateoas.Resource["_embedded"]); nested exception is com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "_embedded" (class org.springframework.hateoas.Resource), not marked as ignorable (3 known properties: , "links", "content", "page"])

What I am missing here? How to consume the above response as a List?

Order.java

public class Order {
private int id;
private String name;
private String keyword;
private Agent agent;

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getKeyword() {
    return keyword;
}

public void setKeyword(String keyword) {
    this.keyword = keyword;
}

public Agent getAgent() {
    return agent;
}

public void setAgent(Agent agent) {
    this.agent = agent;
}

Full Error Stack

21:39:30.746 [http-bio-8080-exec-36] DEBUG c.o.x.o.accessor.XWorkMethodAccessor - Error calling method through OGNL: object: [com.ams.order.actions.ViewOrderSearchAction@5218c8df] method: [viewOrderSearch] args: [[]]
org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Unrecognized field "_embedded" (class org.springframework.hateoas.Resource), not marked as ignorable (2 known properties: , "links", "content"])
 at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@7583f177; line: 2, column: 18] (through reference chain: org.springframework.hateoas.Resource["_embedded"]); nested exception is com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "_embedded" (class org.springframework.hateoas.Resource), not marked as ignorable (2 known properties: , "links", "content"])
 at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@7583f177; line: 2, column: 18] (through reference chain: org.springframework.hateoas.Resource["_embedded"])
    at org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.readJavaType(MappingJackson2HttpMessageConverter.java:181) ~[spring-web-3.2.17.RELEASE.jar:3.2.17.RELEASE]
    at org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.read(MappingJackson2HttpMessageConverter.java:173) ~[spring-web-3.2.17.RELEASE.jar:3.2.17.RELEASE]
    at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:94) ~[spring-web-3.2.17.RELEASE.jar:3.2.17.RELEASE]
    at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:724) ~[spring-web-3.2.17.RELEASE.jar:3.2.17.RELEASE]
    at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:709) ~[spring-web-3.2.17.RELEASE.jar:3.2.17.RELEASE]
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:527) ~[spring-web-3.2.17.RELEASE.jar:3.2.17.RELEASE]
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:482) ~[spring-web-3.2.17.RELEASE.jar:3.2.17.RELEASE]
    at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:455) ~[spring-web-3.2.17.RELEASE.jar:3.2.17.RELEASE]
    at com.ams.service.OrderSearcherImpl.searchForName(OrderSearcherImpl.java:49) ~[classes/:na]
    at com.ams.order.actions.ViewOrderSearchAction.viewOrderSearch(ViewOrderSearchAction.java:61) ~[classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_101]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_101]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_101]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_101]
    at ognl.OgnlRuntime.invokeMethod(OgnlRuntime.java:891) [ognl-3.0.6.jar:na]
    at ognl.OgnlRuntime.callAppropriateMethod(OgnlRuntime.java:1293) [ognl-3.0.6.jar:na]
    at ognl.ObjectMethodAccessor.callMethod(ObjectMethodAccessor.java:68) ~[ognl-3.0.6.jar:na]
    at com.opensymphony.xwork2.ognl.accessor.XWorkMethodAccessor.callMethodWithDebugInfo(XWorkMethodAccessor.java:117) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.ognl.accessor.XWorkMethodAccessor.callMethod(XWorkMethodAccessor.java:108) [xwork-core-2.3.20.jar:2.3.20]
    at ognl.OgnlRuntime.callMethod(OgnlRuntime.java:1369) [ognl-3.0.6.jar:na]
    at ognl.ASTMethod.getValueBody(ASTMethod.java:90) [ognl-3.0.6.jar:na]
    at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212) [ognl-3.0.6.jar:na]
    at ognl.SimpleNode.getValue(SimpleNode.java:258) [ognl-3.0.6.jar:na]
    at ognl.Ognl.getValue(Ognl.java:494) [ognl-3.0.6.jar:na]
    at ognl.Ognl.getValue(Ognl.java:458) [ognl-3.0.6.jar:na]
    at com.opensymphony.xwork2.ognl.OgnlUtil$2.execute(OgnlUtil.java:309) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.ognl.OgnlUtil.compileAndExecute(OgnlUtil.java:340) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.ognl.OgnlUtil.getValue(OgnlUtil.java:307) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:423) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:287) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:250) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:191) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:167) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:265) [xwork-core-2.3.20.jar:2.3.20]
    at org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:76) [struts2-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:138) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:229) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:229) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:191) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) [xwork-core-2.3.20.jar:2.3.20]
    at org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:253) [struts2-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:145) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:171) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) [xwork-core-2.3.20.jar:2.3.20]
    at org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164) [struts2-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:229) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) [xwork-core-2.3.20.jar:2.3.20]
    at org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:73) [struts2-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) [xwork-core-2.3.20.jar:2.3.20]
    at org.apache.struts2.interceptor.DateTextFieldInterceptor.intercept(DateTextFieldInterceptor.java:125) [struts2-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) [xwork-core-2.3.20.jar:2.3.20]
    at org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:91) [struts2-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:139) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:193) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:189) [xwork-core-2.3.20.jar:2.3.20]
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) [xwork-core-2.3.20.jar:2.3.20]
    at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54) [struts2-core-2.3.20.jar:2.3.20]
    at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:564) [struts2-core-2.3.20.jar:2.3.20]
    at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:81) [struts2-core-2.3.20.jar:2.3.20]
    at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:99) [struts2-core-2.3.20.jar:2.3.20]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [catalina.jar:7.0.67]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.67]
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:186) [spring-security-web-3.2.4.RELEASE.jar:3.2.4.RELEASE]
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160) [spring-security-web-3.2.4.RELEASE.jar:3.2.4.RELEASE]
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:343) [spring-web-3.2.17.RELEASE.jar:3.2.17.RELEASE]
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:260) [spring-web-3.2.17.RELEASE.jar:3.2.17.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [catalina.jar:7.0.67]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.67]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [catalina.jar:7.0.67]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.67]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220) [catalina.jar:7.0.67]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) [catalina.jar:7.0.67]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505) [catalina.jar:7.0.67]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169) [catalina.jar:7.0.67]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) [catalina.jar:7.0.67]
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956) [catalina.jar:7.0.67]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) [catalina.jar:7.0.67]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423) [catalina.jar:7.0.67]
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079) [tomcat-coyote.jar:7.0.67]
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625) [tomcat-coyote.jar:7.0.67]
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318) [tomcat-coyote.jar:7.0.67]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_101]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_101]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-coyote.jar:7.0.67]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_101]
Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "_embedded" (class org.springframework.hateoas.Resource), not marked as ignorable (2 known properties: , "links", "content"])
 at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@7583f177; line: 2, column: 18] (through reference chain: org.springframework.hateoas.Resource["_embedded"])
    at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:79) ~[jackson-databind-2.2.2.jar:2.2.2]
    at com.fasterxml.jackson.databind.DeserializationContext.reportUnknownProperty(DeserializationContext.java:555) ~[jackson-databind-2.2.2.jar:2.2.2]
    at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:708) ~[jackson-databind-2.2.2.jar:2.2.2]
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1160) ~[jackson-databind-2.2.2.jar:2.2.2]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:315) ~[jackson-databind-2.2.2.jar:2.2.2]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121) ~[jackson-databind-2.2.2.jar:2.2.2]
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2888) ~[jackson-databind-2.2.2.jar:2.2.2]
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2094) ~[jackson-databind-2.2.2.jar:2.2.2]
    at org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.readJavaType(MappingJackson2HttpMessageConverter.java:178) ~[spring-web-3.2.17.RELEASE.jar:3.2.17.RELEASE]
    ... 105 common frames omitted
buræquete
  • 14,226
  • 4
  • 44
  • 89
Achaius
  • 5,904
  • 21
  • 65
  • 122
  • 1
    can you show your Order class ? – Derrick Oct 13 '16 at 12:48
  • updated Order class info in question – Achaius Oct 13 '16 at 12:55
  • @DerickDaniel Any idea??? – Achaius Oct 13 '16 at 13:09
  • Don't know if this will solve your problem, but it seems that it's not possible to return list from rest template, only arrays: https://javaspringframeworkcourse.wordpress.com/2015/08/06/spring-mvc-resttemplate-getforentity-returns-list-of-objects/. Maybe you could try. – amicoderozer Oct 13 '16 at 13:28
  • @Achaius see my answer – Derrick Oct 13 '16 at 13:35
  • Do you have an object which contains the List? If yes please Show it – Jens Oct 14 '16 at 05:13
  • No I dind't have any Object with List. I wrote a search method in spring-data-rest which returns List as a response Json. I am trying to consume this Json in my action class to render my jsp page using restTemplate. – Achaius Oct 14 '16 at 05:20
  • The response doesn't look like the one for a single object, so I wonder why you even try to use the same class for it (`Resource<>`). I don't think there's a predefined class that can be consumed. The reason is the individual collection property, in your case `"orders"`. Your best shot is probably something like `Resources>>>`. Or you create your own class. – a better oliver Oct 14 '16 at 06:55

5 Answers5

4

Problem is your Order class is not having all the fields mapped according to the response, so if you don't want all the fields, ignore them by using Jackson's annotation in your Order class -

    @JsonIgnoreProperties(ignoreUnknown = true)
    public class Order {
    ...
    }

EDIT: Create your response class like below (you can edit it according yo your json response)-

class Response{
    @JsonProperty("_embedded")
    private Embedded embedded;

    public Embedded getEmbedded() {
        return embedded;
    }

    public void setEmbedded(Embedded embedded) {
        this.embedded = embedded;
    }
}


class Embedded{
    @JsonProperty("orders")
    List<Order> orders = new ArrayList<Order>();

    public Embedded(){

    }

    public List<Order> getOrders() {
        return orders;
    }

    public void setOrders(List<Order> orders) {
        this.orders = orders;
    }
}


class Order {
    private int id;
    private String name;
    private String keyword;
    private Agent agent;

    @Override
    public String toString() {
        return "Order [id=" + id + ", name=" + name + ", keyword=" + keyword + "]";
    }

    public Order(){

    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getKeyword() {
        return keyword;
    }

    public void setKeyword(String keyword) {
        this.keyword = keyword;
    }


    public Agent getAgent() {
        return agent;
    }

    public void setAgent(Agent agent) {
        this.agent = agent;
    }

}

Since the response is enclosed in the root note _embedded, have to consider that and annotate with @JsonProperty, so that it can be recognizable

Get the reponse object like below -

Response reeponse = restOperations
                .exchange(new URI(url), HttpMethod.GET, null, new ParameterizedTypeReference<Response>() {
                }).getBody().getContent();
Derrick
  • 3,669
  • 5
  • 35
  • 50
  • Still I am having the same issues. – Achaius Oct 13 '16 at 13:39
  • Getting the same error as mentioned in the question – Achaius Oct 14 '16 at 04:05
  • 1
    Is this the only way. Because the response is in standard spring-hateoas format. Can I use some wrapper class from hateoas instead of writing this Response class. Because I need more Embedded class with different Objects like Order, Agent, ect., – Achaius Oct 14 '16 at 05:55
  • Not sure about other ways, but here you can adjust your response class to have all the objects you want and use @JsonInclude(JsonInclude.Include.NON_NULL) annotation to avoid object fields not present in the response. – Derrick Oct 14 '16 at 07:06
  • This is a hack, but it is still useful I think in helping people understand what the problem is resulting from. It would be better however to use the org.springframework.hateoas.Resources class with parameterized type references to convert the hateoas response to an object. – Kallaste Apr 08 '19 at 04:16
2

You should be able to make exactly the same restTemplate.exchange() call but using the org.springframework.hateoas.Resources wrapper class for a Collection of entities rather than the org.springframework.hateoas.Resource wrapper class for a single entity. I.e. new ParameterizedTypeReference<Resources<Order>>() {} as the 4th parameter.

Note that if you get an wrapped empty collection returned by this call but with no errors logged, then make sure you have the org.springframework.data:spring-data-rest-core dependency - myself and another developer have just spent much of today debugging this!

(This helped: http://www.java-allandsundry.com/2014/01/consuming-spring-hateoas-rest-service.html)

Matthew Wise
  • 2,639
  • 26
  • 23
0

I solved the problem by using spring-hateoas Traverson instead of RestTempalte. This works as I expected.

Achaius
  • 5,904
  • 21
  • 65
  • 122
0

Have Jackson desereliaze to Resources<Resource<Order>>. That will capture the collection's links as well as each order's links.

Derrick
  • 3,669
  • 5
  • 35
  • 50
gregturn
  • 2,625
  • 3
  • 25
  • 40
0

In current versions of Spring Data, the type of response you show is modeled by org.springframework.hateoas.CollectionModel.

So change the response type to CollectionModel<Order>, and use .getContent() to retrieve a Collection of items (rather than a list).

Collection<Order> orders = restOperations.exchange(new URI(url), HttpMethod.GET, null, new CollectionModel<Order>() {}).getBody().getContent();
GOTO 0
  • 42,323
  • 22
  • 125
  • 158