Spring-boot Hateoas将Hateoas链接转换为对象而不是集合

时间:2019-01-29 17:54:14

标签: java spring spring-boot spring-hateoas hateoas

我与Hateoas一起使用spring-boot。我的API之一将仇恨链接公开为集合“ _ links”:[),而不是对象“ _ links”:{。我不确定为什么它使用数组表示法而不是对象。请在下面找到代码。任何帮助将不胜感激。

public class Book {
    private String id;
    private BookInfo bookInfo;
}

public class BookInfo extends ResourceSupport{
    private String bookUid;
    private String bookName;
    private String authhorName;
    private String bookGenre;

    @Override
    @JsonProperty("_links")
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public List<Link> getLinks() {
        return super.getLinks();
    }
}

@RestController
@RequestMapping(value = "/api/v1/", produces = APP_JSON)
public class BookController {

    @GetMapping("getBooks")
    public ResponseEntity<Book> getTransactionStatus() {
        Book book = bookRepo.getAllBooks();
        book.getBookInfo().add(addLinks(book.getId()));
        return ResponseEntity.ok().contentType(MediaType.valueOf(APP_JSON)).body(book);
    }

      public SuperLink getBookInfoLinks(String bookUid) {
        return new SuperLink(
                linkTo(methodOn(BookController.class).getBook(bookUid))
                        .withRel("retrieve-book").expand(),APP_JSON);
    }
}

public class SuperLink extends Link {


    @XmlAttribute
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private String accepts;

    public SuperLink(Link link) {
        super(link.getHref(), link.getRel());
    }

    public SuperLink(Link link, String accepts) {
        super(link.getHref(), link.getRel());
        this.accepts = accepts;
    }

    public String getAccepts() {
        return accepts;
    }

    public void setAccepts(String accepts) {
        this.accepts = accepts;
    }
}

实际输出

{
   "id":"bookId",
   "BookInfo":{
      "bookUid":"bookUid",
      "_links":[
         {
            "rel":"retrieve-book",
            "href":"http://localhost/api/v1/book/bookId",
            "accepts":"application/json"
         }
      ]
   }
}

预期产量

{
   "id":"bookId",
   "BookInfo":{
      "bookUid":"bookUid",
      "_links":
         {
            "retrieve-book": {
            "href":"http://localhost/api/v1/book/bookId",
            "accepts":"application/json"
            }
         }

   }
}

3 个答案:

答案 0 :(得分:0)

我无法添加评论以包含我的建议。因此,在这里提及: 请参考此内容:Embed object instead of collection in Spring HATEOAS

答案 1 :(得分:0)

之所以发生这种情况,是因为您在代码中使用了列表。

 @Override
 @JsonProperty("_links")
 @JsonInclude(JsonInclude.Include.NON_NULL)
 public List<Link> getLinks() {
    return super.getLinks();
 }

您应该使用Link对象而不是Link List。

答案 2 :(得分:0)

链接应序列化为地图,而不是列表。您既可以自己将其转换为地图,也可以使用自定义序列化器/反序列化器。幸运的是,Spring已经有了它们:

@Override
@JsonProperty("_links")
@JsonInclude(Include.NON_EMPTY)
@JsonSerialize(using = Jackson2HalModule.HalLinkListSerializer.class)
@JsonDeserialize(using = Jackson2HalModule.HalLinkListDeserializer.class)
public List<Link> getLinks() {
  return super.getLinks();
}

---编辑

为了使其正常工作,您将需要消息转换器列表中的halJacksonHttpMessageConverter bean。创建一个WebMvcConfigurer并将halJacksonHttpMessageConverter添加到extendMessageConverters方法的转换器中。

@Autowired
private HttpMessageConverter halJacksonHttpMessageConverter;

public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
  converters.add(halJacksonHttpMessageConverter);
}

您应将其添加到列表的开头,或从列表中删除原始的jacksonHttpMessageConverter