Spring Boot MVC — Как программно сгенерировать значение etag объекта?

#spring-boot #etag

Вопрос:

Я использую Spring Boot 1.5.18 с ReactJS и пытаюсь условно обновить объект с помощью ETag.

Я добавил следующую конфигурацию, и Spring Boot генерирует теги etag в заголовках ответов.

 @Bean
public Filter shallowEtagHeaderFilter() {
    return new ShallowEtagHeaderFilter();
}
 

Теперь я хочу проверить в своем методе контроллера, совпадают ли метки etag, прежде чем обновлять сущность. Мой метод контроллера заключается в следующем:

 @RequestMapping(method = POST, value = "/assignments/{id}/edit")
public @ResponseBody
ResponseEntity<?> editStaffAssignment(@RequestBody Resource<AssignmentDTO> dtoResource,
                                      @PathVariable Long id,
                                      PersistentEntityResourceAssembler resourceAssembler, Pageable pageable) {

    Assignment assignment = assignHandler.updateAssignment(dtoResource.getContent(), id);

    return new ResponseEntity<>(resourceAssembler.toResource(assignment), HttpStatus.OK);

}
 

Я включил заголовок etag в запрос Axios от клиента reactjs и могу извлечь его в методе контроллера, но как программно сгенерировать текущее значение etag на стороне сервера?

Ответ №1:

Значение ShallowEtagHeaderFilter ETag вычисляется на основе сериализованного тела ответа, поэтому его нелегко вычислить заранее (т. Е. До того, как тело ответа будет фактически отправлено).

Если я правильно вас понял, вы хотите использовать оптимистичный механизм блокировки. Если это так, я бы предложил сначала удалить ShallowEtagHeaderFilter и вместо этого вычислить ETag вручную, вот так:

 String etag = calculateETag(); // TODO
return ResponseEntity.ok()
      .eTag(etag)
      .body(resourceAssembler.toResource(assignment));
 

Если вы используете JPA, вы можете повторно использовать это @Version поле в качестве значения ETag здесь.