Java 未为@QueryParam调用Jackson JsonDeserialize

Java 未为@QueryParam调用Jackson JsonDeserialize,java,json,jackson,jax-rs,jersey-2.0,Java,Json,Jackson,Jax Rs,Jersey 2.0,我已经映射了一个自定义反序列化程序,将dd/MM/yyyy模式上的字符串转换为LocalDate,这样我就可以使用更可读的签名调用我的服务 这是我的dto类,用作Jersey@BeanParam在层之间传输数据: public class ProdutoFilterDto implements FilterDto { private static final long serialVersionUID = -4998167328470565406L; @QueryParam("dataIni

我已经映射了一个自定义反序列化程序,将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);
}

}
我是这样打电话的:

${host goes here}/produto/query?dataInicial=11/09/1992

问题是从未调用反序列化器方法,并且bean param变量仍然为null

MessageBodyReader
不用于
@QueryParam
。您似乎期望Jackson
MessageBodyReader
处理此反序列化,但它不是这样工作的

相反,您需要使用,这需要通过注册。例如:

@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;
    }
}
@Provider
公共类LocalDateParamConverterProvider实现ParamConverterProvider{
最终DateTimeFormatter formatter=模式的DateTimeFormatter.of(“dd/MM/yyyy”);
@凌驾
公共参数转换器getConverter(
类rawType、类型genericType、注释[]antns){
if(LocalDate.class==rawType){
返回新的参数转换器(){
@凌驾
公共T fromString(字符串){
试一试{
LocalDate LocalDate=LocalDate.parse(字符串,格式化程序);
返回rawType.cast(localDate);
}捕获(例外情况除外){
抛出新的BadRequestException(ex);
}
}
@凌驾
公共字符串到字符串(T){
LocalDate LocalDate=(LocalDate)t;
返回formatter.format(localDate);
}
};
}
返回null;
}
}
现在
LocalDate
将与
@QueryParam
和其他
@XxxParam
一起使用

需要注意的事项:

  • 如果您的目标是将
    @XxxParam
    s和JSON主体解析为一个bean,那么这是行不通的。我不确定这将如何工作,但我相信这将涉及大量的黑客攻击,我不建议这样做

  • 您对
    (LocalDate)
    的强制转换无效。这是对
    java.time.format.Parsed
    的非法强制转换。请参阅代码示例中的正确方法

  • 与上述观点有关。我花了整整一个小时的时间试图弄明白为什么我会用你的解析代码得到404。对于404,我最不想看的地方是
    ParamConverter
    。但是在
    ParamConverter
    中抛出的任何未捕获的异常都将导致404。没什么意义,对吧?头部撞击导致我,这导致我,这似乎是一个糟糕的规范

    “如果字段或属性带有注释 @MatrixParam、@QueryParam或@PathParam则实现必须生成 NotFoundException(404状态),它包装抛出的异常和无实体 "

    故事的寓意:确保捕获
    参数转换器中任何可能的异常

另请参见:


您是否配置了web.xml?您是否定义了servlet Jersey并对其进行了映射?对于如何使其适用于pathparam有何建议?我有一个带有多个查询和路径参数的BeanParm。getConverter方法仅为一个queryparam调用。有什么建议吗?应该还能用。如果你想用一个完整的例子来发布另一个问题,我可以在拿到问题的chancelink后再看一看
@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;
    }
}