Доступна ли необработанная полезная нагрузка POST в контроллере покоя, если она была сопоставлена ​​с объектом, в противном случае? - PullRequest
0 голосов
/ 04 ноября 2019

У меня есть конечная точка POST, и некоторая полезная нагрузка JSON, которая содержит важные данные, должна быть заархивирована с дайджестом.

@RestController
public class SomeController {

  @PostMapping(value = "/api/some")
  public ResponseEntity<ResponseStatus> postSome(@Valid @RequestBody Some some) {
    archiveAndDigest(rawJsonPostPayloadSomeHowFromCurrentContext());
    someService(some);
    return new ResponseEntity<ResponseStatus>(
      ResponseStatus.builder()
...
        .build(),
        HttpStatus.CREATED
      );
  }

Конечная точка контроллера слишком выразительна и удобна (обеспечивает тип содержимого, анализирует и проверяет вводПолезная нагрузка) для ввода необработанных строк и выполнения всего этого вручную. Входные данные должны быть сохранены для целей аудита.

1 Ответ

0 голосов
/ 04 ноября 2019

Можно получить необработанное значение JSON вместо десериализованного объекта.

Я могу придумать два способа сделать это.

1-й , что Я не рекомендую :

Таким образом, вы не сможете использовать Spring Validator.

Получите JSON какСтрока, а затем превратить необработанное значение в объект, используя ObjectMapper.

@RestController
public class SomeController {

    private final Logger log = LoggerFactory.getLogger(this.getClass());

    @PostMapping(value = "/api/some")
    public ResponseEntity<ResponseStatus> postSome(String rawRequest) {
        log.info("Raw value: {}", rawRequest);

        ObjectMapper mapper = new ObjectMapper();
        Some some = mapper.readValue(rawRequest, Some.class);
        someService(some);

        return new ResponseEntity<ResponseStatus> (ResponseStatus.builder()
        ...
        .build(), HttpStatus.CREATED);
    }
}

2nd , который я предпочитаю .

Получите объект как объект (именно так, как вы это делаете), а затем получите необработанное значение JSON из объекта с помощью ObjectMapper

Таким образом, вы сможете используйте Spring Validator.

@RestController
public class SomeController {

    private final Logger log = LoggerFactory.getLogger(this.getClass());

    @PostMapping(value = "/api/some")
    public ResponseEntity<ResponseStatus> postSome(@Valid @RequestBody Some some) {
        ObjectMapper mapper = new ObjectMapper();

        String rawJsonValue mapper.writeValueAsString(some);
        log.info("Raw value: {}", rawJsonValue);

        someService(some);

        return new ResponseEntity<ResponseStatus> (ResponseStatus.builder()
        ...
        .build(), HttpStatus.CREATED);
    }
}

Я предпочитаю лестницу, но имейте в виду, что любой атрибут, отправленный в запросе JSON, который не существует в вашем объекте, не будет напечатан. Это происходит потому, что mapper.writeValueAsString(some) будет генерировать JSON на основе свойств вашего объекта.

ОБНОВЛЕНИЕ

Вы можете определить HttpServletRequest в качестве аргумента для вашегометод. Таким образом Spring предоставит текущий запрос и передаст его в аргументе.

@RestController
public class SomeController {

    @PostMapping(value = "/api/some")
    public ResponseEntity<ResponseStatus> postSome(@Valid @RequestBody Some some, HttpServletRequest request) {
        String rawValue = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));

        System.out.println(rawValue);

        someService(some);

        return new ResponseEntity<ResponseStatus> (ResponseStatus.builder()
        ...
        .build(), HttpStatus.CREATED);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...