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

gue*_*lla 11 java rest json 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>>) {
}
...
}
}
Run Code Online (Sandbox Code Playgroud)

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

谢谢

she*_*ley 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>>) { ... }

}
Run Code Online (Sandbox Code Playgroud)

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

ObjectMapper mapper = new ObjectMapper();
mapper.disable(MapperFeature.USE_GETTERS_AS_SETTERS);
Run Code Online (Sandbox Code Playgroud)


joa*_*mbl 6

从Jackson 2.6开始,使用JsonProperty#access()注释有了一种新的改进的定义read-onlywrite-only属性的方法。建议不要使用单独的和注释。JsonIgnoreJsonProperty

@JsonProperty(access = JsonProperty.Access.READ_ONLY)
public Map<String,List<String>> references;
Run Code Online (Sandbox Code Playgroud)


Ale*_*ych 5

您必须确保在字段级别和 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;
    }
}
Run Code Online (Sandbox Code Playgroud)
  • 如果您提交的 JSON 请求的“doNotDeserialise”值设置为某个值,则当 JSON 反序列化为对象时,它将被设置为 null(如果不是,我在该字段上设置了验证约束,因此它会出错)
  • 如果您将“doNotDeserialise”值设置为服务器上的某个值,那么它将被正确序列化为 JSON 并推送到客户端


Pet*_*ete 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;
}
Run Code Online (Sandbox Code Playgroud)

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

或者传入的数据是否超出了您的控制范围,而您只是想避免映射异常告诉您杰克逊无法找到为传入引用设置的属性?为此,我们使用所有 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() + "\"");

    }
Run Code Online (Sandbox Code Playgroud)

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

@JsonIgnoreProperties
class A extends JsonObject {
    // no references if you don't need them
}
Run Code Online (Sandbox Code Playgroud)

编辑

这个 SO Thread描述了如何使用 Mixins。如果您想保持结构原样,这可能是解决方案,但我还没有尝试过。