Переопределить связанные ссылки в Spring Data REST - PullRequest
1 голос
/ 17 июня 2019

Я использую Spring Boot 2, Spring Data REST, Spring HATEOAS.

Допустим, у меня есть модель:

@EntityListeners({ContactListener.class})
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Contact extends AbstractEntity {

    @NotNull
    @Enumerated(EnumType.STRING)
    @Column(nullable = false, columnDefinition = "VARCHAR(30) DEFAULT 'CUSTOMER'")
    private ContactType type = ContactType.CUSTOMER;

    @NotNull
    @Enumerated(EnumType.STRING)
    @Column(nullable = false, columnDefinition = "VARCHAR(30) DEFAULT 'NATURAL_PERSON'")
    private PersonType personType = PersonType.NATURAL_PERSON;

    private String firstName;

    private String lastName;

    private String companyName;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "store_id", updatable = false)
    private Store store;

и магазин:

@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Store extends AbstractEntity {

    @NotBlank
    @Column(nullable = false)
    private String name;

    @Username
    @NotBlank
    @Length(max = 16)
    @Column(nullable = false/*, unique = true*/)
    @ColumnTransformer(write = "UPPER(?)")
    private String code;

    private String address;

    private String zipCode;

    private String city;

    private String district;

Когда я получаю контакт, ответ выглядит так:

{
    "sid": "962732c2-68a8-413b-9762-f676d42046b4",
    "createdBy": "1ccf2329-4aa3-4d55-8878-25517edf1522",
    "createdDate": "2019-05-28T14:06:07.011Z",
    "lastModifiedDate": "2019-06-04T08:46:02.591Z",
    "lastModifiedBy": "system",
    "createdByName": "Rossi Mario",
    "lastModifiedByName": null,
    "type": "CUSTOMER",
    "personType": "NATURAL_PERSON",
    "firstName": "Mario",
    "lastName": "Rossi",
    "companyName": null,
    "fullName": "Rossi Mario",
    "gender": "MALE",
    "birthDate": "2019-05-21T00:00:00Z",
    "birthCity": null,
    "job": null,
    "billingAddress": "Via 123",
    "billingZipCode": "14018",
    "billingCity": "Roatto",
    "billingDistrict": "AT",
    "billingCountry": "IT",
    "shippingAddress": "Via 123",
    "shippingZipCode": "14018",
    "shippingCity": "Roatto",
    "shippingDistrict": "AT",
    "shippingCountry": "IT",
    "taxCode": "XXXX",
    "vatNumber": null,
    "landlinePhone": null,
    "mobilePhone": null,
    "fax": null,
    "email": "aaa@sdfg.it",
    "certifiedEmail": null,
    "survey": null,
    "iban": null,
    "swift": null,
    "publicAdministration": false,
    "sdiAccountId": "0000000",
    "preset": false,
    "_links": {
        "self": {
            "href": "http://localhost:8082/api/v1/contacts/1"
        },
        "contact": {
            "href": "http://localhost:8082/api/v1/contacts/1{?projection}",
            "templated": true
        },
        "store": {
            "href": "http://localhost:8082/api/v1/contacts/1/store{?projection}",
            "templated": true
        }
    }
}

как вы можете видеть ссылку магазина, это не ссылка self ресурса магазина. Я хотел бы переопределить эту ссылку, установив собственный ресурс. Итак, я создал этот процессор:

@Component
public class DocumentRowProcessor implements ResourceProcessor<Resource<Contact>> {

    @Autowired
    private BasePathAwareLinks service;

    @Autowired
    private EntityLinks entityLinks;

    @Override
    public Resource<Contact> process(Resource<Contact> resource) {

        Store store = resource.getContent().getStore();
        if(store != null){
           resource.add(entityLinks.linkToSingleResource(store.getClass(), store.getId()).withRel("store"));
        }

        return resource;
    }
}

К сожалению, ссылка теперь переопределена, но я нахожу 2 ссылки внутри "магазина". Отладка Я видел, что внутри ресурса присутствует только ссылка на себя. Я предполагаю, что связанные ссылки добавляются в следующих шагах.

Как мне достичь своей цели чистым способом?

1 Ответ

1 голос
/ 01 июля 2019
  1. Ссылки hateoas добавляются в результат во время сериализации (с использованием определенного сериализатора JSON), поэтому вы не можете удалить его с помощью ResourceProcessor.
  2. Ссылка hateoas в результате - это правильная ссылка для этого ресурса. http://localhost:8082/api/v1/contacts/1/store является конечной точкой, где вы можете проверить, какое хранилище связано с этим контентом, или вы можете удалить / изменить связь между этими двумя объектами.

Однако в некоторых случаях вам нужна собственная ссылка для дальнейших действий, и вы не хотите отправлять дополнительный запрос от клиента. Сделайте следующее: 1. Создайте прогноз для константы. 2. Включите все необходимые вам свойства, а также магазин. 3. Если вам не нужны здесь какие-либо свойства магазина - только ссылка на себя - создайте «пустую проекцию» для entoty магазина и включите эту проекцию в качестве свойства магазина в свойство контакта.

Когда вы получите эту проекцию контакта, результат будет содержать собственную ссылку на хранилище внутри свойства хранилища. Таким образом, основная коллекция _links будет по-прежнему регулярной коллекцией ссылок hateos, но будет свойство store._links.self.href, которое будет содержать собственную ссылку связанного хранилища.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...