泽西/杰克逊@JsonIgnore在二传手

时间:2012-09-26 05:56:39

标签: java json rest jersey jackson

我有一个带有以下注释的课程:

class A {
public Map<String,List<String>> references;

@JsonProperty
public Map<String,List<String>> getReferences() {
...
}

@JsonIgnore
public void setReferences(Map<String,List<String>>) {
}
...
}
}

我尝试忽略反序列化的json。但它不起作用。始终当JSON String到达时,Jackson lib会填充references属性。如果我只使用@JsonIgnore注释,则getter不起作用。有没有解决这个问题的方法?

由于

5 个答案:

答案 0 :(得分:16)

我认为有两个关键部分可以让你根据需要拥有“只读集合”。首先,除了忽略setter之外,请确保字段也标有@JsonIgnore

class A {

  @JsonIgnore
  public Map<String,List<String>> references;

  @JsonProperty
  public Map<String,List<String>> getReferences() { ... }

  @JsonIgnore
  public void setReferences(Map<String,List<String>>) { ... }

}

其次,为了防止将getter用作setter,请禁用USE_GETTERS_AS_SETTERS功能:

ObjectMapper mapper = new ObjectMapper();
mapper.disable(MapperFeature.USE_GETTERS_AS_SETTERS);

答案 1 :(得分:4)

你必须确保在字段级别和setter上都有@JsonIgnore注释,并使用@JsonProperty注释getter。

public class Echo {

    @Null
    @JsonIgnore
    private String doNotDeserialise;

    private String echo;

    @JsonProperty
    public String getDoNotDeserialise() {
        return doNotDeserialise;
    }

    @JsonIgnore
    public void setDoNotDeserialise(String doNotDeserialise) {
        this.doNotDeserialise = doNotDeserialise;
    }

    public String getEcho() {
        return echo;
    }

    public void setEcho(String echo) {
        this.echo = echo;
    }
}

@Controller
public class EchoController {

@ResponseBody
@RequestMapping(value = "/echo", consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE)
    public Echo echo(@RequestBody @Valid Echo echo) {
        if (StringUtils.isEmpty(echo.getDoNotDeserialise())) {
            echo.setDoNotDeserialise("Value is set by the server, not by the client!");
        }

        return echo;
    }
}
  • 如果你提交一个设置为“doNotDeserialise”值的JSON请求,当JSON被反序列化为一个对象时,它将被设置为null(如果不是我在该字段上放置一个验证约束,那么它将会出错)< / LI>
  • 如果您将“doNotDeserialise”值设置为服务器上的某个值,那么它将被正确序列化为JSON并推送到客户端

答案 2 :(得分:3)

我在我的getter上使用@JsonIgnore并且它无效并且我无法配置映射器(我使用的是Jackson Jaxrs提供程序)。这对我有用:

@JsonIgnoreProperties(ignoreUnknown = true, value = { "actorsAsString",
    "writersAsString", "directorsAsString", "genresAsString" }) 

答案 3 :(得分:2)

从Jackson 2.6开始,使用JsonProperty#access()注释定义val text = "1 فِي الْبَدْءِ خَلَقَ اللهُ السَّمَاوَاتِ وَالأَرْضَ. 2 وَكَانَتِ الأَرْضُ خَرِبَةً وَخَالِيَةً، وَعَلَى وَجْهِ الْغَمْرِ ظُلْمَةٌ، وَرُوحُ اللهِ يَرِفُّ عَلَى وَجْهِ الْمِيَاهِ. 3 وَقَالَ اللهُ: «لِيَكُنْ نُورٌ»، فَكَانَ نُورٌ. 4 وَرَأَى اللهُ النُّورَ أَنَّهُ حَسَنٌ. وَفَصَلَ اللهُ بَيْنَ النُّورِ وَالظُّلْمَةِ. 5 وَدَعَا اللهُ النُّورَ نَهَارًا، وَالظُّلْمَةُ دَعَاهَا لَيْلاً. وَكَانَ مَسَاءٌ وَكَانَ صَبَاحٌ يَوْمًا وَاحِدًا.6 وَقَالَ اللهُ: «لِيَكُنْ جَلَدٌ فِي وَسَطِ الْمِيَاهِ. وَلْيَكُنْ فَاصِلاً بَيْنَ مِيَاهٍ وَمِيَاهٍ». 7 فَعَمِلَ اللهُ الْجَلَدَ، وَفَصَلَ بَيْنَ الْمِيَاهِ الَّتِي تَحْتَ الْجَلَدِ وَالْمِيَاهِ الَّتِي فَوْقَ الْجَلَدِ. وَكَانَ كَذلِكَ. 8 وَدَعَا اللهُ الْجَلَدَ سَمَاءً. وَكَانَ مَسَاءٌ وَكَانَ صَبَاحٌ يَوْمًا ثَانِيًا.9 وَقَالَ اللهُ: «لِتَجْتَمِعِ الْمِيَاهُ تَحْتَ السَّمَاءِ إِلَى مَكَانٍ وَاحِدٍ، وَلْتَظْهَرِ الْيَابِسَةُ». وَكَانَ كَذلِكَ. 10 وَدَعَا اللهُ الْيَابِسَةَ أَرْضًا، وَمُجْتَمَعَ الْمِيَاهِ دَعَاهُ بِحَارًا. وَرَأَى اللهُ ذلِكَ أَنَّهُ حَسَنٌ. " val res = text.replace(Regex("""(\d+)\s""")) { match -> val (num) = match.destructured "\n$num " } println(res) read-only属性有一种新的改进方法。建议使用单独的write-onlyJsonIgnore注释。

JsonProperty

答案 4 :(得分:0)

我只能想到一个非杰克逊解决方案,使用没有映射引用然后转换为实际类的基类:

// expect a B on an incoming request
class B {
// ...
}

// after the data is read, cast to A which will have empty references
class A extends B {
public Map<String,List<String>> references;
}

如果您不想要它们,为什么还要发送参考文献?

或者传出的数据是否在您手中,您只是想避免映射异常,告诉您jackson无法找到为传入引用设置的属性?为此我们使用了一个基类,我们所有的Json模型类都继承了这个基类:

public abstract class JsonObject {

    @JsonAnySetter
    public void handleUnknown(String key, Object value) {

        // for us we log an error if we can't map but you can skip that
        Log log = LogFactory.getLog(String.class);    
        log.error("Error mapping object of type: " + this.getClass().getName());    
        log.error("Could not map key: \"" + key + "\" and value: \"" + "\"" + value.toString() + "\"");

    }

然后在POJO中添加@JsonIgnoreProperties,以便传入的属性转发到handleUnknown()

@JsonIgnoreProperties
class A extends JsonObject {
    // no references if you don't need them
}

修改

This SO Thread介绍了如何使用Mixins。这可能是解决方案,如果你想保持你的结构完全一样,但我还没有尝试过。