首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >伪装和HAL/资源

伪装和HAL/资源
EN

Stack Overflow用户
提问于 2015-05-29 03:27:20
回答 5查看 6.5K关注 0票数 5

我有一个通过spring-data-rest公开资源的服务器,据我所知,它使用的是HAL或HATEOAS。但当我尝试将它与Feign结合使用时,我似乎无法注册被拾取的Jackson2HalModule。

有没有什么我必须做的连接假“客户端”到新的转换器?它是否使用了与我在这里得到的不同的ObjectMapper?

代码:

代码语言:javascript
复制
@Inject
public void configureObjectMapper(ObjectMapper mapper, RestTemplate template) {
    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    mapper.registerModule(new Jackson2HalModule());

    MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
    converter.setSupportedMediaTypes(MediaType.parseMediaTypes("application/hal+json"));
    converter.setObjectMapper(mapper);

    template.getMessageConverters().add(converter);
}

来自服务器的响应:

代码语言:javascript
复制
{
  "_links" : {
    "self" : {
      "href" : "http://localhost:13372/user{?page,size,sort}",
      "templated" : true
    },
    "search" : {
      "href" : "http://localhost:13372/user/search"
    }
  },
  "_embedded" : {
    "user" : [ {
      "id" : "5567613e5da543dba4201950",
      "version" : 0,
      "created" : "2015-05-28T18:41:02.685Z",
      "createdBy" : "system test",
      "edited" : "2015-05-28T18:41:02.713Z",
      "editedBy" : "system test",
      "username" : "devuser",
      "email" : "dev@test.com",
      "roles" : [ "USER" ],
      "_links" : {
        "self" : {
          "href" : "http://localhost:13372/user/5567613e5da543dba4201950"
        }
      }
    } ]
  },
  "page" : {
    "size" : 20,
    "totalElements" : 1,
    "totalPages" : 1,
    "number" : 0
  }
}

例外:

代码语言:javascript
复制
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token
 at [Source: java.io.PushbackInputStream@7b6c6e70; line: 1, column: 1]
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148)
    at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:762)
    at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:758)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.handleNonArray(CollectionDeserializer.java:275)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:216)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:206)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:25)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3066)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2221)
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:205)
EN

回答 5

Stack Overflow用户

发布于 2015-05-29 12:23:04

我找到问题了。发生异常的原因是来自REST API的响应是单个响应。所以它没有把它看作是一个实体列表。

当我添加(基于上面的代码)时:

代码语言:javascript
复制
mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);

它起作用了

编辑:顺便说一句,我像这样实现了FeignClient:

代码语言:javascript
复制
@Service
@FeignClient(UsersConstants.USER_SERVICE_NAME)
public interface UsersServices {

    @RequestMapping(method = RequestMethod.GET, value = "/user")
    List<User> getUsers();
}

但它应该是什么样子,因为它是一个可分页的资源:

代码语言:javascript
复制
@Service
@FeignClient(UsersConstants.USER_SERVICE_NAME)
public interface UsersServices {

    @RequestMapping(method = RequestMethod.GET, value = "/user")
    List<PagedResources<User>> getUsers();
}

可以在HATEOAS依赖中找到PagedResource:

代码语言:javascript
复制
<dependency>
    <groupId>org.springframework.hateoas</groupId>
    <artifactId>spring-hateoas</artifactId>
</dependency>

它还有很多其他的类可以提供帮助,比如Resource、Resources等等。

票数 5
EN

Stack Overflow用户

发布于 2015-11-28 22:28:05

这对我很有效:

代码语言:javascript
复制
@EnableHypermediaSupport(type = EnableHypermediaSupport.HypermediaType.HAL)
@SpringBootApplication
@EnableFeignClients
public class Application {
....
}

请注意@EnableHypermediaSupport

代码语言:javascript
复制
@FeignClient(url = "http://localhost:8080")
public interface PersonClient {
    @RequestMapping(method = RequestMethod.GET, value = "/persons")
    Resources<Person> getPersons();

    @RequestMapping(method = RequestMethod.GET, value = "/persons/{id}")
    Resource<Person> getPerson(@PathVariable("id") long id);
}

我在这里创建了一个完整的工作示例:https://github.com/jtdev/spring-feign-data-rest-example

请注意,简单地将maven pom从spring-boot切换到spring-cloud (不更改代码)很容易导致json错误。

票数 5
EN

Stack Overflow用户

发布于 2015-07-15 02:33:34

您应该在应用程序中定义一个feignDecoder bean。如果您的环境中有spring-hateoas,请尝试如下所示:

代码语言:javascript
复制
@Bean
public Decoder feignDecoder() {
    ObjectMapper mapper = new ObjectMapper()
            .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
            .registerModule(new Jackson2HalModule());

    return new ResponseEntityDecoder(new JacksonDecoder(mapper));
}

然后,您可以将您的HAL作为PagedResource使用。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30515483

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档