How to consume list of entities response from spring-data-rest
Asked Answered
P

5

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
Petulant answered 13/10, 2016 at 12:26 Comment(8)
can you show your Order class ?Synovia
updated Order class info in questionPetulant
@DerickDaniel Any idea???Petulant
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: javaspringframeworkcourse.wordpress.com/2015/08/06/…. Maybe you could try.Parahydrogen
@Petulant see my answerSynovia
Do you have an object which contains the List<Orders>? If yes please Show itGeraldina
No I dind't have any Object with List<Order>. I wrote a search method in spring-data-rest which returns List<Order> as a response Json. I am trying to consume this Json in my action class to render my jsp page using restTemplate.Petulant
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<Map<String, List<Order>>>>. Or you create your own class.Swale
S
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();
Synovia answered 13/10, 2016 at 13:21 Comment(5)
Still I am having the same issues.Petulant
Getting the same error as mentioned in the questionPetulant
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.,Petulant
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.Synovia
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.Wycoff
C
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)

Cookstove answered 16/2, 2017 at 17:12 Comment(0)
P
0

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

Petulant answered 14/10, 2016 at 11:25 Comment(1)
could you provide an example please? ThanksDusen
P
0

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

Panocha answered 11/3, 2017 at 13:38 Comment(0)
B
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();
Battement answered 29/7, 2021 at 14:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.