简体   繁体   English

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

[英]Spring-boot hateoas convert hateoas links to object instead of collection

I am using spring-boot along with Hateoas. 我正在与Hateoas一起使用spring-boot。 One of my API exposes hateoas links as a collection "_links":[ instead if an object "_links":{ . 我的API之一将Hateoas链接公开为集合“ _links”:[[如果对象为“ _links”:{则相反 I am not sure why it is using array notation instead of an object. 我不确定为什么它使用数组表示法而不是对象。 Please find the code below. 请在下面找到代码。 Any help would be appreciated. 任何帮助,将不胜感激。

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;
    }
}

Actual output 实际产量

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

Expected output 预期产量

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

   }
}

I can not add comment to include my suggestion. 我无法添加评论以包含我的建议。 So, mentioning it here: Refer to this one : Embed object instead of collection in Spring HATEOAS 因此,在这里提到它:参考这一内容: 在Spring HATEOAS中嵌入对象而不是集合

This is happening because you are using List in you code. 发生这种情况是因为您在代码中使用列表。

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

You should use Link object instead of List of Link. 您应该使用链接对象而不是链接列表。

The links should be serialized as a map, not as a list. 链接应序列化为映射,而不是列表。 You either convert it into a map yourself or you can use custom serializer/deseralizer for that. 您既可以自己将其转换为地图,也可以使用自定义序列化器/反序列化器。 Fortunately Spring already has them: 幸运的是,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();
}

--- edit -编辑

In order to make it work you will need the halJacksonHttpMessageConverter bean in the list of message-converters. 为了使其工作,您将需要消息转换器列表中的halJacksonHttpMessageConverter bean。 Create a WebMvcConfigurer and add the halJacksonHttpMessageConverter to the converters in the extendMessageConverters method. 创建WebMvcConfigurer和添加halJacksonHttpMessageConverter在转换器extendMessageConverters方法。

@Autowired
private HttpMessageConverter halJacksonHttpMessageConverter;

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

You should add it to the front of the list, or remove the original jacksonHttpMessageConverter from the list. 您应该将其添加到列表的jacksonHttpMessageConverter ,或者从列表中删除原始的jacksonHttpMessageConverter

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM