我正在尝试将 Json-B 与 Spring Boot 版本一起使用:2.3.1
json-b
<dependency>
<groupId>javax.json.bind</groupId>
<artifactId>javax.json.bind-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.eclipse</groupId>
<artifactId>yasson</artifactId>
<version>1.0.5</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.1.4</version>
</dependency>
休息控制器:
@RestController
public class MyController {
@PostMapping("/api/test")
public ResponseEntity init(@Valid @RequestBody MyRequest request) {
return ResponseEntity.ok("ok");
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentNotValidException.class)
public Map<String, String> handleValidationExceptions(
MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
ex.getBindingResult().getAllErrors().forEach((error) -> {
String fieldName = ((FieldError) error).getField();
String errorMessage = error.getDefaultMessage();
final Object rejectedValue = ((FieldError) error).getRejectedValue();
errors.put("Rejected Value: ", rejectedValue.toString());
errors.put(fieldName, errorMessage);
});
return errors;
}
}
请求:
public class MyRequest {
@DurationMin(minutes = 1")
@DurationMax(minutes = 10)
@JsonbTypeAdapter(DurationAdapter.class)
private Duration expiredTime;
....getter setter...
}
Json-B 适配器:
public class DurationAdapter implements JsonbAdapter<Duration, JsonValue> {
@Override
public JsonValue adaptToJson(Duration duration) throws Exception {
final JsonNumber value = Json.createValue(duration.toMillis());
return value;
}
@Override
public Duration adaptFromJson(JsonValue jsonValue) throws Exception {
final long timeInMillis = ((JsonNumber) jsonValue).longValue();
return Duration.ofMillis(timeInMillis);
}
}
我也试过这个适配器:
public class DurationAdapter implements JsonbAdapter<Duration, Long> {
@Override
public Long adaptToJson(Duration obj) throws Exception {
return obj.toMillis();
}
@Override
public Duration adaptFromJson(Long obj) throws Exception {
return Duration.ofMillis(obj);
}
}
我使用 Postman 发送了一个包含如下内容的发布请求:
{
"expiredTime": 6000
}
我在适配器中放置了断点,但应用程序从未通过断点。我在休息控制器的异常处理程序中的拒绝值处放置了一个断点,我看到持续时间始终以“秒”为单位,而不是毫秒。如果请求具有“expiredTime”:6000,那么 Java 对象将具有值为 Duration=6000 秒的 expriredTime 字段(使用调试器查看值)并且将引发异常(这就是我可以在异常处理程序中使用调试器的原因)。
如何让 Spring Boot 使用我的 Json-B 适配器? 谢谢!
更新:我也在 application.properties 中指定了这个:
spring.http.converters.preferred-json-mapper=jsonb