#spring #jackson #spring-data-rest #spring-hateoas
#весна #джексон #spring-data-rest #spring-ненависть
Вопрос:
Я использую spring-data-rest для предоставления REST API. Один из моих методов поиска возвращает список сущностей. Репозиторий и ответ rest следующим образом
List<Order> findByKeywordContaining(String keyword);
Поиск ответа:
{
"_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"
}
}
}
Теперь я использую RestTemplate для использования этого ответа для обработки на стороне клиента следующим образом
List<Order> orders = restOperations.exchange(new URI(url), HttpMethod.GET, null, new ParameterizedTypeReference<Resource<List<Order>>>() {}).getBody().getContent();
Приведенный выше код отлично работает для одного объекта в ответе, но если ответ содержит несколько объектов. Код выдает следующую ошибку
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"])
Чего мне здесь не хватает? Как использовать приведенный выше ответ в виде списка?
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;
}
Полный стек ошибок
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
Комментарии:
1. можете ли вы показать свой класс Order?
2. обновленная информация о классе порядка, о которой идет речь
3. @DerickDaniel Есть идеи???
4. Не знаю, решит ли это вашу проблему, но, похоже, невозможно вернуть список из шаблона rest, только массивы: javaspringframeworkcourse.wordpress.com/2015/08/06 /. … Может быть, вы могли бы попробовать.
5. @Achaius смотрите мой ответ
Ответ №1:
Проблема в том, что в вашем классе Order не все поля отображаются в соответствии с ответом, поэтому, если вам не нужны все поля, игнорируйте их, используя аннотацию Джексона в вашем классе Order —
@JsonIgnoreProperties(ignoreUnknown = true)
public class Order {
...
}
РЕДАКТИРОВАТЬ: создайте свой класс ответов, как показано ниже (вы можете отредактировать его в соответствии с вашим ответом json)-
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;
}
}
Поскольку ответ вложен в корневую заметку _embedded
, необходимо учитывать это и комментировать @JsonProperty
, чтобы его можно было распознать
Получите объект ответа, как показано ниже —
Response reeponse = restOperations
.exchange(new URI(url), HttpMethod.GET, null, new ParameterizedTypeReference<Response>() {
}).getBody().getContent();
Комментарии:
1. Тем не менее, у меня возникают те же проблемы.
2. Получение той же ошибки, что и в вопросе
3. Это единственный способ. Потому что ответ находится в стандартном формате spring-hateoas. Могу ли я использовать какой-либо класс-оболочку из hateoas вместо написания этого класса ответов. Потому что мне нужно больше встроенного класса с различными объектами, такими как Order, Agent и т. Д.,
4. Не уверен насчет других способов, но здесь вы можете настроить свой класс ответов так, чтобы в нем были все нужные вам объекты, и использовать @JsonInclude(JsonInclude. Включить аннотацию .NON_NULL), чтобы избежать полей объектов, отсутствующих в ответе.
5. Это взлом, но, я думаю, он по-прежнему полезен, помогая людям понять, в чем причина проблемы. Однако было бы лучше использовать org.springframework.hateoas. Класс ресурсов с параметризованными ссылками на типы для преобразования ответа hateoas в объект.
Ответ №2:
Вы должны иметь возможность выполнить точно такой же restTemplate.exchange()
вызов, но используя org.springframework.hateoas.Resources
класс-оболочку для набора объектов, а не org.springframework.hateoas.Resource
класс-оболочку для одного объекта. Т.е. new ParameterizedTypeReference<Resources<Order>>() {}
в качестве 4-го параметра.
Обратите внимание, что если вы получаете завернутую пустую коллекцию, возвращенную этим вызовом, но без зарегистрированных ошибок, то убедитесь, что у вас есть org.springframework.data:spring-data-rest-core dependency — я и другой разработчик только что потратили большую часть сегодняшнего дня на отладку этого!
(Это помогло: http://www.java-allandsundry.com/2014/01/consuming-spring-hateoas-rest-service.html )
Ответ №3:
Я решил проблему, используя spring-hateoas Traverson вместо RestTempalte. Это работает так, как я ожидал.
Комментарии:
1. не могли бы вы привести пример, пожалуйста? Спасибо
Ответ №4:
Попросите Джексона отказаться Resources<Resource<Order>>
от использования. Это будет захватывать ссылки коллекции, а также ссылки каждого заказа.
Ответ №5:
В текущих версиях Spring Data тип отображаемого вами ответа моделируется org.springframework.hateoas.CollectionModel
.
Поэтому измените тип ответа на CollectionModel<Order>
, и используйте .getContent()
для извлечения Collection
элементов (а не списка).
Collection<Order> orders = restOperations.exchange(new URI(url), HttpMethod.GET, null, new CollectionModel<Order>() {}).getBody().getContent();