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