Mar*_*hel 3 java json jax-rs jackson jersey-2.0
我已经映射了一个自定义解串器,以将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;
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的自定义反序列化器:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
该球衣服务中使用了它:
@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) { ... }
...
}
Run Code Online (Sandbox Code Playgroud)
我这样打电话:
${host goes here}/produto/query?dataInicial=11/09/1992
Run Code Online (Sandbox Code Playgroud)
问题是从不调用解串器方法,并且bean param变量保持为空。
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;
}
}
Run Code Online (Sandbox Code Playgroud)
现在LocalDate将与@QueryParam和其他一起使用@XxxParam。
注意事项:
如果您的目标是将@XxxParams和JSON正文都解析为一个bean,那么它将不起作用。我不确定这将如何工作,但是我确定它会涉及很多黑客行为,因此我不建议这样做。
您的投向(LocalDate)将无法正常工作。这是非法的java.time.format.Parsed。在代码示例中查看正确的方法。
与以上几点有关。我花了好一个小时拉着头发,试图用您的解析代码弄清楚为什么我得到404。使用404,我想看的最后一个地方是ParamConverter。但似乎所有未捕获的异常都ParamConverter将引发404。这不是很有意义吗?头撞着我导致了这个,这导致我导致了这个,这似乎是一个糟糕的规范
“如果字段或属性使用@ MatrixParam,@ QueryParam或@PathParam进行注释,则实现必须生成一个NotFoundException实例(404状态),该实例包装抛出的异常,并且不包含任何实体”
故事的寓意:请确保在中捕获任何可能的例外ParamConverter!
也可以看看:
| 归档时间: |
|
| 查看次数: |
3277 次 |
| 最近记录: |