要解决此问题,目前,以下工作。
战争依赖:
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>8.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jberet</groupId>
<artifactId>jberet-rest-commons</artifactId>
<version>1.4.0.Final</version>
</dependency>
<dependency>
<groupId>org.jberet</groupId>
<artifactId>jberet-schedule-executor</artifactId>
<version>1.4.0.Final</version>
</dependency>
<dependency>
<groupId>org.jberet</groupId>
<artifactId>jberet-schedule-timer</artifactId>
<version>1.4.0.Final</version>
</dependency>
<dependency>
<groupId>org.jberet</groupId>
<artifactId>jberet-rest-api</artifactId>
<version>1.4.0.Final</version>
</dependency>
然后创建一个 json 反序列化器:
public class ScheduleExpressionDeserializer extends JsonDeserializer<ScheduleExpression> {
private final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ISO_OFFSET_DATE;
@Override
public ScheduleExpression deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
ScheduleExpression scheduleExpression = new ScheduleExpression();
// Payload example:
// {"year":"1","month":"2","dayOfMonth":"3","dayOfWeek":"4",
// "hour":"5","minute":"6","start":"2020-05-04T08:10:00.000Z",
// "end":"2020-06-05T08:12:00.000Z","timezone":"Africa/Blantyre"}
TreeNode treeNode = jsonParser.getCodec().readTree(jsonParser);
Optional.ofNullable(treeNode.get("year"))
.flatMap(this::parseIntegerNode)
.ifPresent(scheduleExpression::year);
Optional.ofNullable(treeNode.get("month"))
.flatMap(this::parseIntegerNode)
.ifPresent(scheduleExpression::month);
Optional.ofNullable(treeNode.get("dayOfMonth"))
.flatMap(this::parseIntegerNode)
.ifPresent(scheduleExpression::dayOfMonth);
Optional.ofNullable(treeNode.get("dayOfWeek"))
.flatMap(this::parseIntegerNode)
.ifPresent(scheduleExpression::dayOfWeek);
Optional.ofNullable(treeNode.get("hour"))
.flatMap(this::parseIntegerNode)
.ifPresent(scheduleExpression::hour);
Optional.ofNullable(treeNode.get("minute"))
.flatMap(this::parseIntegerNode)
.ifPresent(scheduleExpression::minute);
Optional.ofNullable(treeNode.get("start"))
.flatMap(this::parseDateTimeNode)
.ifPresent(scheduleExpression::start);
Optional.ofNullable(treeNode.get("end"))
.flatMap(this::parseDateTimeNode)
.ifPresent(scheduleExpression::end);
Optional.ofNullable(treeNode.get("timezone"))
.map(TreeNode::asToken)
.map(JsonToken::asString)
.ifPresent(scheduleExpression::timezone);
return scheduleExpression;
}
private Optional<Integer> parseIntegerNode(TreeNode node) {
if (node instanceof TextNode) {
TextNode textNode = (TextNode) node;
return Optional.of(textNode)
.map(TextNode::asInt);
} else {
return Optional.empty();
}
}
private Optional<Date> parseDateTimeNode(TreeNode node) {
if (node instanceof TextNode) {
TextNode textNode = (TextNode) node;
return Optional.of(textNode)
.map(TextNode::asText)
.map(s -> OffsetDateTime.parse(s, dateTimeFormatter))
.map(OffsetDateTime::toInstant)
.map(Date::from);
} else {
return Optional.empty();
}
}
}
并在 jax-rs 提供的 ObjectMapper 中使用它:
@Provider
public class JacksonMapperResolver implements ContextResolver<ObjectMapper> {
@Override
public ObjectMapper getContext(Class<?> type) {
ObjectMapper mapper = new ObjectMapper();
SimpleModule simpleModule = new SimpleModule("Custom deserializers");
simpleModule.addDeserializer(ScheduleExpression.class, new ScheduleExpressionDeserializer());
mapper.registerModule(simpleModule);
return mapper;
}
}