Spring HATEOAS 链接 return 单个对象的 HAL 格式,以及对象数组的规范格式

Spring HATEOAS links return in HAL format for single objects, and the spec format for an array of objects

我正在使用 Spring HATEOAS 0.20(也尝试过 0.23),当 return 使用单个对象与对象数组时,似乎有非常奇怪的行为。当 returning 单个对象时,生成的 JSON returns HATEOAS 链接通过 HAL 规范格式化(“_links”,我不想要):

{
  "_Id": 161,
  ...
  "_links": {
    "self": {
      "href": "http://localhost:8080/library/161"
    }
  }
}

当 returning 对象数组时,生成的 JSON returns HATEOAS 链接采用规范格式("links",我确实想要):

[
  {
    "_Id": 277,
    ...
    "links": [
      {
        "rel": "self",
        "href": "http://localhost:8080/library/277"
      }
    ]
  }
]

我没有指定@EnableHypermediaSupport,所以应该不支持HAL。但是,当 returning 单个对象时,我仍然得到 HAL 格式。

有谁知道为什么会这样? 需要通过 HATEOAS 规范对 return 具有 HATEOAS 链接的单个对象执行哪些操作?

===== 根据更多信息的请求更新到 POST =====

如果我 return JSON 使用以下代码加载,我将获得 HAL 链接:

//
//------------------- Get Single Membership As Single Object ----------------------------------------------
//
@PreAuthorize("hasRole('ROLE_ADMIN')")
@RequestMapping(value = REQUEST_GET_MEMBERSHIP, method = RequestMethod.GET,  produces = { MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<MembershipResource> getMembership(@PathVariable("membership-id") Integer membershipId) {
    Membership membership = membershipRepository.findOne(membershipId);

    if (membership == null) {
        HttpHeaders headers = new HttpHeaders();
        headers.add("error", "Membership with ID of " + membershipId + " does not exist.");
        return new ResponseEntity<MembershipResource>(headers, HttpStatus.NOT_FOUND);
    }

    MembershipResourceAssembler assm = new MembershipResourceAssembler();
    MembershipResource membershipResource = assm.toResource(membership);

    System.out.println("membership id: " + membership.getId());
    return new ResponseEntity<MembershipResource>(membershipResource, HttpStatus.OK);
}

以上将生成 HAL 规范样式链接:

{
  "_Id": 277,
  "member": {
    "_Id": 112,
    "title": "Mr.",
    "firstName": "ABC",
    "middleName": "",
    "lastName": "XYZ",
    "active": true,
    "_links": {
      "self": {
        "href": "http://localhost:8080/members/112"
      }
    }
  },
  "membershipTermType": "2016",
  "card": {
    "_Id": 27,
    "name": "27",
    "graphicUrl": "",
    "number": 27,
  },
  "active": false,
  "paid": true,
  "renewal": true,
  "termsAndConditionsAcknowledged": true,
  "_links": {
    "self": {
      "href": "http://localhost:8080/memberships/277"
    }
  }
}

如果我将方法修改为 return 单个成员的列表,returned JSON 加载是带有 HATEOAS 规范的链接:

//
//------------------- Get Single Membership As List --------------------------------------------------------
//
@PreAuthorize("hasRole('ROLE_ADMIN')")
@RequestMapping(value = REQUEST_GET_MEMBERSHIP, method = RequestMethod.GET,  produces = { MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<List<MembershipResource>> getMembership(@PathVariable("membership-id") Integer membershipId) {
    Membership membership = membershipRepository.findOne(membershipId);

    if (membership == null) {
        HttpHeaders headers = new HttpHeaders();
        headers.add("error", "Membership with ID of " + membershipId + " does not exist.");
        return new ResponseEntity<List<MembershipResource>>(headers, HttpStatus.NOT_FOUND);
    }

    MembershipResourceAssembler assm = new MembershipResourceAssembler();
        MembershipResource membershipResource = assm.toResource(membership);

    ArrayList<MembershipResource> list = new ArrayList<MembershipResource>();
    list.add(membershipResource);

    System.out.println("membership id: " + membership.getId());
    return new ResponseEntity<List<MembershipResource>>(list, HttpStatus.OK);
}

以上将生成 HATEOAS 规范样式链接:

[
  {
    "_Id": 277,
    "member": {
      "_Id": 112,
      "title": "Mr.",
      "firstName": "ABC",
      "middleName": "",
      "lastName": "XYZ",
      "active": true,
      "links": [
        {
          "rel": "self",
          "href": "http://localhost:8080/members/112"
        }
      ]
    },
    "membershipTermType": "2016",
    "card": {
      "_Id": 27,
      "name": "27",
      "graphicUrl": "",
      "number": 27,
      "links": []
    },
    "active": false,
    "renewal": true,
    "paid": true,
    "termsAndConditionsAcknowledged": true,
    "links": [
      {
        "rel": "self",
        "href": "http://localhost:8080/memberships/277"
      }
    ]
  }
]

有谁知道为什么会这样? 需要通过 HATEOAS 规范对 return 具有 HATEOAS 链接的单个对象执行哪些操作?

由于我使用 Spring Boot 作为我的应用程序服务器,@zeroflagL 建议我尝试在您的应用程序中添加 @EnableAutoConfiguration(exclude = HypermediaAutoConfiguration.class) 或在您的属性文件中添加 spring.hateoas.use-hal-as-default-json-media-type=false

@EnableAutoConfiguration(exclude = HypermediaAutoConfiguration.class) 的配置注释添加到我的应用程序 class 解决了这个问题。