我有一个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
);
}
控制器端点太具有表现力和方便性(确保内容类型,解析并验证输入有效载荷),以至于无法丢弃原始字符串输入,并且需要手工完成所有这些操作。输入的有效负载必须保留用于审核。
有可能获得原始的JSON值而不是反序列化的对象。
我可以想到两种方法。
1st,其中我不推荐:
这样,您无法使用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);
}
}
第二,其中我更喜欢。
将对象作为对象接收(就像您所做的那样,然后使用ObjectMapper从对象获取JSON原始值
这样您可以使用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。
UPDATE
您可以将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);
}
}