Джерси/Джексон @JsonIgnore на сеттер

i имеет класс со следующими аннотациями:

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 заполняет атрибут ссылок. Если я использую только аннотацию @JsonIgnore, геттер не работает. Существуют ли какие-либо решения для этой проблемы?

Спасибо

Ответ 1

Я думаю, что есть две ключевые части, которые должны позволить вам иметь "коллекцию только для чтения" по желанию. Во-первых, в дополнение к игнорированию установщика убедитесь, что ваше поле также отмечено @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>>) { ... }

}

Во-вторых, чтобы предотвратить использование геттеров в настройках, отключите функцию USE_GETTERS_AS_SETTERS:

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

Ответ 2

Вы должны убедиться, что есть аннотация @JsonIgnore на уровне поля, а также на установщике, а getter - аннотируется с помощью @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;
    }
}
  • Если вы отправляете запрос JSON с значением "doNotDeserialise", установленным на что-то, когда JSON десериализуется на объект, он будет иметь значение null (если я не поставил ограничение проверки в поле, чтобы оно было ошибочным)
  • Если вы установите значение "doNotDeserialise" на что-то на сервере, тогда оно будет правильно сериализовано в JSON и нажато на клиентский

Ответ 3

Я использовал @JsonIgnore на моем получателе, и это не сработало, и я не смог настроить картограф (я использовал поставщиков Jackson Jaxrs). Это сработало для меня:

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

Ответ 4

Я могу только думать о решении без джексонов, использовать базовый класс, который не имеет ссылок для сопоставления, а затем отбрасывает в действительный класс:

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

Почему вы даже отправляете ссылки, если вы не хотите их?

Или входящие данные из ваших рук, и вы просто хотите избежать исключения отображения, сообщая вам, что Джексон не может найти свойство для установки входящих ссылок? Для этого мы используем базовый класс, который наследует все классы модели 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
}

изменить

Этот SO-поток описывает, как использовать Mixins. Это может быть решением, если вы хотите сохранить свою структуру в точности так, как есть, но я ее не пробовал.

Ответ 5

Как и в случае с Jackson 2.6, существует новый и улучшенный способ определения свойств read-only и write-only, используя JsonProperty # access() аннотация. Рекомендуется использовать отдельные аннотации JsonIgnore и JsonProperty.

@JsonProperty(access = JsonProperty.Access.READ_ONLY)
public Map<String,List<String>> references;