Jersey/Jackson @JsonIgnore on setter

2019-03-25 16:37发布

i have an class with the following annotations:

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

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

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

What I try is to ignore the json on deserialization. But it doesn't work. Always when JSON String arrives the Jackson lib fill the references attribute. If I use only the @JsonIgnore annotation the getter doesn't work. Are there any solutions for this problem?

Thanks

5条回答
聊天终结者
2楼-- · 2019-03-25 16:47

I can only think of a non-jackson solution, to use a base class that does not have references for the mapping and then cast to the actual class:

// 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;
}

Why do you even send the References if you don't want them?

Or is the incoming data out of your hands and you just want to avoid the mapping exception telling you that jackson cannot find a property to set for incoming references? For that we use a base class which all of our Json model classes inherit:

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() + "\"");

    }

Then in the POJO you add @JsonIgnoreProperties so that incoming properties will get forwarded to handleUnknown()

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

edit

This SO Thread describes how to use Mixins. This might be the solution, if you want to keep your structure exactly as it is, but I have not tried it.

查看更多
姐就是有狂的资本
3楼-- · 2019-03-25 16:53

I think there are two key pieces that should enable you to have "read-only collections" as desired. First, in addition to ignoring the setter, ensure that your field is also marked with @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>>) { ... }

}

Second, in order to prevent the getters from being used as setters, disable the USE_GETTERS_AS_SETTERS feature:

ObjectMapper mapper = new ObjectMapper();
mapper.disable(MapperFeature.USE_GETTERS_AS_SETTERS);
查看更多
成全新的幸福
4楼-- · 2019-03-25 16:55

You have to make sure there is @JsonIgnore annotation on the field level as well as on the setter, and getter annotated with @JsonProperty.

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;
    }
}
  • If you submit a JSON request with a “doNotDeserialise” value set to something, when JSON is deserialised to an object it will be set to null (if not I put a validation constraint on the field so it will error out)
  • If you set the “doNotDeserialise” value to something on the server then it will be correctly serialised to JSON and pushed to the client
查看更多
We Are One
5楼-- · 2019-03-25 17:00

As of Jackson 2.6, there is a new and improved way to define read-only and write-only properties, using JsonProperty#access() annotation. This is recommended over use of separate JsonIgnore and JsonProperty annotations.

@JsonProperty(access = JsonProperty.Access.READ_ONLY)
public Map<String,List<String>> references;
查看更多
beautiful°
6楼-- · 2019-03-25 17:01

I used @JsonIgnore on my getter and it didn't work and I couldn't configure the mapper (I was using Jackson Jaxrs providers). This worked for me:

@JsonIgnoreProperties(ignoreUnknown = true, value = { "actorsAsString",
    "writersAsString", "directorsAsString", "genresAsString" }) 
查看更多
登录 后发表回答