【问题标题】:Can I ignore just a setter w/ Jackson & Spring?我可以忽略杰克逊和斯普林的二传手吗?
【发布时间】:2012-10-13 18:25:56
【问题描述】:

我有一种情况,我将一个对象从 Java 传递回 Javascript 客户端,并且它正在由 Spring 3 中内置的 Jackson 映射器序列化(使用 @RequestBody / @ResponseBody 和 application/json 内容类型)

我遇到的问题是一些类从具有 getter 但没有 setter 的接口实现。

我确实希望客户端可以使用 getter 值,因此我不能使用 @JsonIgnore 注释,因为它会完全忽略该属性,包括序列化和反序列化。序列化时我需要该属性。

还有其他方法吗?

【问题讨论】:

  • 如果类中没有设置器,您将如何反序列化属性值?
  • 我不会在乎它的反序列化。反序列化时可以忽略。
  • hmm...但是您说“我确实希望客户端可以使用 getter 值”-因此它在客户端 javascript 发送给您的 json 中可用,并且您需要该值,不这意味着在反序列化 (JSON -> java) 时确实需要它,但在序列化 (Java -> JSON) 时不需要它?
  • 我需要在 Javascript 中使用 Java>JSON,我不关心它是否返回 JSON>Java。

标签: java json spring jackson


【解决方案1】:

可能有一种更简单的方法,但我想提一下JSON views 的使用作为一种可能的解决方案。 this thread 上有一个例子。

您可能需要对反序列化而不只是序列化有不同的看法,这将是 Jackson 2.0 的功能 - supported by Spring 3.2 and backported into Spring 3.1。自 Jackson 1.4 以来,仅使用序列化视图是一项功能。

想到的另一个选项是使用custom deserializer

【讨论】:

  • 谢谢我会使用这些选项
【解决方案2】:

我也在寻找同样的东西。

根据Jackson docs,我们可以在属性、getter 或setter 上设置@JsonIgnore 注释,这将隐藏完整的属性,除非我们给setter 一个@JsonProperty 注释以确保该属性是设置时可见。不幸的是,反过来也行不通。我想在我的回复中显示该属性,但不将其包含在我的请求中。

例如,用例是一个自动生成的 id。我不希望用户设置,甚至不希望看到,但他可能会阅读。

您可以通过确实隐藏属性本身然后添加@JsonAnyGetter 方法来实现这一点。在这种方法中,您可以将数据按摩成您想要的任何形式。表示您只想显示单个名称或标识符或其他格式的复杂属性类也很有用。后者有更好的方法,但如果用例不太复杂,这就足够了。

举个例子(如果这太详细了,我很抱歉):

用户:

public class User {

    private String uid;
    private String customerId;
    private String taxSsnId;

    public String getUid() {
        return uid;
    }

    public void setUid(String uid) {
        this.uid = uid;
    }

    public String getCustomerId() {
        return extCustomerId;
    }

    public void setCustomerId(String extCustomerId) {
        this.extCustomerId = extCustomerId;
    }

    public String getTaxSsnId() {
        return taxSsnId;
    }

    public void setTaxSsnId(String taxSsnId) {
        this.taxSsnId = taxSsnId;
    }

    @JsonIgnore
    public void getId(){
        if (getUid() != null){
            return getUid();
        }
        if (getCustomerId() != null ){
            return getCustomerId();
        }
        return null;
    }
}

设置:

public class Setting {

    @JsonIgnore
    private int id;

    private String key;
    private String value;

    @JsonIgnore
    private User lastUpdatedBy;

    @JsonIgnore
    private Date lastUpdatedAt;

        public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public User getLastUpdatedBy() {
        return lastUpdatedBy;
    }

    public void setLastUpdatedBy(User lastUpdatedBy) {
        this.lastUpdatedBy = lastUpdatedBy;
    }

    public Date getLastUpdatedAt() {
        return lastUpdatedAt;
    }

    public void setLastUpdatedAt(Date lastUpdatedAt) {
        this.lastUpdatedAt = lastUpdatedAt;
    }

    @JsonAnyGetter
    private Map<String, String> other() {
        Map<String, String> map = new LinkedHashMap<String, String>();
        map.put( "id", this.getId());
        map.put( "lastUpdatedBy", this.getLastUpdatedBy().getId());
        SimpleDateFormat format = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss z");
        map.put( "lastUpdatedAt", format.format(this.getLastUpdatedAt()) );
        return map;
    }

}

产生这个Request 模式(反序列化视图):

{
  "key": "string",
  "value": "string"
}

还有这个Response 模式(序列化视图):

{
  "key": "string",
  "value": "string",
  "id": "12345",
  "lastUpdatedBy": "String",
  "lastUpdatedAt": "String" 
}

【讨论】:

  • 这样的缺点是模式没有正确表示。 @JsonAnyGetter 方法中设置的字段没有明显显示。如果有人有更好的方法?
猜你喜欢
  • 1970-01-01
  • 2016-04-19
  • 2016-01-16
  • 1970-01-01
  • 2015-04-19
  • 2016-09-11
  • 1970-01-01
  • 1970-01-01
  • 2022-06-22
相关资源
最近更新 更多