当前位置: 首页 > 知识库问答 >
问题:

用户定义类中基元字段的Jersey-Jackson映射问题

经慈
2023-03-14

我在客户端使用AngularJS,在服务器端使用jersey jackson的Java实现RESTful webservice。

我正在使用HTTP PUT方法更新记录。我正在从角客户端应用程序向java webservice应用程序发送一个参数(JSON对象)。

我们的POJO类有一些默认值为0的基本数字字段(long/int)。但在接收到包含这些字段的空白字符串的JSON时,jersey jackson会将这些数字字段的值映射为null,这不是我们想要的行为。

当从客户端应用程序发送空值时,如何配置webservice应用程序来映射默认值(数字字段为0)?

java webservice项目中的示例POJO类:

@XmlRootElement
public class modelclass {
    private Long telephoneNumber = 0;
    private Long faxNumber = 0;
    private String name = "";
public modelclass (String jsonData) {
        ObjectMapper mapper = new ObjectMapper();
        try {
            modelclass pdo = mapper.readValue(jsonData, modelclass.class);
            this.telephoneNumber = pdo.telephoneNumber;
            this.faxNumber = pdo.faxNumber;
            this.name = pdo.name;
        }
}
}

共有2个答案

方航
2023-03-14

作为一个选项,您可以在构造函数中添加对输入值的验证,或注册一个自定义Long反序列化器,该反序列化器设置空字段的默认值。

以下是一个示例:

public class JacksonDefaultValues {
    public static class Model {
        private final long  telephoneNumber;
        private final long faxNumber;
        private final String name;

        @JsonCreator
        public Model(@JsonProperty("telephoneNumber") Long telephoneNumber,
                     @JsonProperty("faxNumber") Long faxNumber,
                     @JsonProperty("name") String name) {
            // add validation as follows:
            // this.telephoneNumber = telephoneNumber == null ? 1234567l : telephoneNumber;
            this.telephoneNumber = telephoneNumber;
            this.faxNumber = faxNumber;
            this.name = name;
        }

        @Override
        public String toString() {
            return "Model{" +
                    "telephoneNumber=" + telephoneNumber +
                    ", faxNumber=" + faxNumber +
                    ", name='" + name + '\'' +
                    '}';
        }
    }

    private static class LongDeserializerDefaultValue extends StdDeserializer<Long> {
        private final long defaultValue;

        protected LongDeserializerDefaultValue(long defaultValue) {
            super(Long.TYPE);
            this.defaultValue = defaultValue;
        }

        @Override
        public Long getNullValue() {
            return defaultValue;
        }

        @Override
        public Long deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
            return _parseLong(jp, ctxt);
        }
    }

    public static void main(String[] args) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        SimpleModule testModule = new SimpleModule()
                .addDeserializer(Long.class, new LongDeserializerDefaultValue(678));
        mapper.registerModule(testModule);
        String json = "{\"telephoneNumber\":0,\"name\":\"John\"}";
        System.out.println(mapper.readValue(json, Model.class));
    }

}

输出:

Model{telephoneNumber=0, faxNumber=678, name='John'}
郝昊天
2023-03-14

你有几个选择。你没有提到你使用的是什么版本的球衣/杰克逊,所以我假设是2。x表示两者。

在将值分配给字段之前,可以使用现有代码检查值是否为null。

您还可以使用Jackson注释重写POJO:

@JsonAutoDetect(fieldVisibility = Visibility.ANY)
@JsonIgnoreProperties(ignoreUnknown = true)
public class ModelClass {
    private Long telephoneNumber = 0;
    private Long faxNumber = 0;
    private String name = "";
}

@JsonAutoDetect告诉Jackson甚至可以使用私有字段,而@JsonIgnoreProperties使其忽略json输入字符串中的无关内容。我还没有测试过这个,但它应该可以满足您的要求。

顺便说一句,您使用Long存储电话号码的任何特殊原因?我总是将它们存储为String或某种URI。我发现它使显示/格式化变得更加容易。

 类似资料:
  • 另外,如果一个键的值为null,那么它就是被接受的默认值,所以我也不能使用@NotNull。对于eg:[{firstKey:null,secondKey:“value2”,thirKey:“value3”}]是有效的JSON,在反序列化过程中应该毫无异常地进行解析。

  • 我想为无法识别的字段和其他带有请求正文的错误设置自定义错误消息。我试过ExceptionMapper,但它不起作用:/使用Quarkus和杰克逊 发送请求时: 看起来不错。但发送时: 找到类似DeserializationProblemHandler的内容,但不知道如何更改handleUnknownProperty:/的消息

  • 我使用DTO和modelMapper是为了不让某些字段可见。我有一个类别实体,可以有子类别 创建类别时,我使用模型: 在此模型中,我希望parentCategoryKeyId与父对象的categoryKeyId匹配。 例如,如果我创建了一个“顶级”类别: 它返回给我: 当我这样做时: 在我的控制器中,我将其余对象传递给DTO层,该层调用服务: 我的类别是基本的POJO: 为我服务: 我的问题是,我

  • 问题内容: 我不清楚杰克逊如何处理映射字段中的大写字母。如果有人可以帮忙,我将不胜感激。 上面是我的json,下面是我的例外… 上面是我的例外,下面是我的课… …等等 问题答案: 由于您的设置方法命名为Jackson,因此假设变量的命名是基于Java的 命名约定 (变量应以小写字母开头)。 如果您真的想要一个大写字母,请使用 setter 上的 @JsonProperty 注释(或-进行序列化-在

  • 我不清楚jackson是如何处理映射字段中的大写字母的。如果有人能帮忙,我将不胜感激。 上面是我的json,下面是我的例外。。。 上面是我的例外,下面是我的班级。。。 ... 等等

  • 我创建了一个如下表 然后,我将另一列添加到表中: 将其添加到表中: 用户添加user_traits冻结 我想运行一个查询,返回所有单身用户的姓名,但是我不确定如何实现这一点,因为我正在过滤用户定义类型中的字段。 这就是我所拥有的: <代码>选择user\u fname,user\u lname FROM users WHERE user\u traits。婚姻状况='单身'允许筛选 但是,此代码在