我已经映射了一个自定义反序列化程序,用于将dd / MM / yyyy模式上的字符串转换为LocalDate,这样我就可以使用更易读的签名来调用我的服务..
这是我的dto类,用作Jersey @BeanParam在层之间传输数据:
public class ProdutoFilterDto implements FilterDto {
private static final long serialVersionUID = -4998167328470565406L;
@QueryParam("dataInicial")
@JsonDeserialize(using = CustomLocalDateDeserializer.class)
private LocalDate dataInicial;
@QueryParam("dataInicial")
@JsonDeserialize(using = CustomLocalDateDeserializer.class)
private LocalDate dataFinal;
public LocalDate getDataInicial() {
return dataInicial;
}
public void setDataInicial(LocalDate dataInicial) {
this.dataInicial = dataInicial;
}
public LocalDate getDataFinal() {
return dataFinal;
}
public void setDataFinal(LocalDate dataFinal) {
this.dataFinal = dataFinal;
}
}
这是我的自定义反序列化器:
public class CustomLocalDateDeserializer extends JsonDeserializer<LocalDate> {
@Override
public LocalDate deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
final String data = p.getValueAsString();
return (LocalDate) formatter.parse(data);
}
}
它被用于这项球衣服务:
@Path("produto")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class ProdutoService {
...
@GET
@Path("query")
@Override
public Response query(
@QueryParam("offset") @DefaultValue(value = "0") Integer offSet,
@QueryParam("limit") @DefaultValue(value = "10") Integer limit,
@BeanParam ProdutoFilterDto filter) { ... }
...
}
我这样打电话:
${host goes here}/produto/query?dataInicial=11/09/1992
问题是从不调用反序列化器方法,并且bean参数变量保持为空。
答案 0 :(得分:5)
MessageBodyReader
并未用于@QueryParam
。你似乎期待着杰克逊MessageBodyReader
来处理这种反序列化,但它并没有像那样工作。
相反,您需要使用ParamConverter
,这需要通过ParamConverterProvider
进行注册。例如:
@Provider
public class LocalDateParamConverterProvider implements ParamConverterProvider {
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
@Override
public <T> ParamConverter<T> getConverter(
Class<T> rawType, Type genericType, Annotation[] antns) {
if (LocalDate.class == rawType) {
return new ParamConverter<T>() {
@Override
public T fromString(String string) {
try {
LocalDate localDate = LocalDate.parse(string, formatter);
return rawType.cast(localDate);
} catch (Exception ex) {
throw new BadRequestException(ex);
}
}
@Override
public String toString(T t) {
LocalDate localDate = (LocalDate) t;
return formatter.format(localDate);
}
};
}
return null;
}
}
现在LocalDate
也适用于@QueryParam
和其他@XxxParam
。
有些注意事项:
如果你的目标是将你的@XxxParam
和你的JSON主体解析成bean,那么这将无效。我不确定它是如何工作的,但我确定它会涉及很多黑客行为,我不会推荐它。
您的演员(LocalDate)
无法奏效。这是java.time.format.Parsed
的非法演员。在代码示例中查看正确的方法。
与上述相关。我正在拔出我的头发好一个小时试图找出我为什么得到404,使用你的解析代码。有了404,我认为最后一个地方是ParamConverter
。但似乎ParamConverter
中引发的任何未被捕获的异常都会导致404.没有多大意义吗?头部冲击让我this,这导致我this,这似乎是一个糟糕的规范
&#34;如果字段或属性使用注释 @MatrixParam,@ QueryParam或@PathParam然后一个实现必须生成一个实例 NotFoundException(404 status)包装抛出的异常而没有实体 &#34;
故事的道德:确保在ParamConverter
中抓住任何可能的例外情况!
另见: