Подтвердить что ты не робот

Как исключить поля с помощью Джексона, не используя аннотации?

Мне нужно исключить некоторые поля по именам перед рендерингом. Список полей является динамическим, поэтому я не могу использовать аннотации.

Я пытался создать собственный сериализатор, но не могу получить имя поля там.

В GSON я использовал ExclusionStrategy, но у Джексона такой функциональности нет. Есть ли эквивалент?

4b9b3361

Ответ 1

Ниже приведен пример исключения полей по имени из моего сообщения в блоге, Gson v Jackson - Part 4. (Найдите PropertyFilterMixIn.) В этом примере показано использование FilterProvider с SimpleBeanPropertyFilter до serializeAllExcept указанным пользователем списком имен полей.

@JsonFilter("filter properties by name")  
class PropertyFilterMixIn {}  

class Bar  
{  
  public String id = "42";  
  public String name = "Fred";  
  public String color = "blue";  
  public Foo foo = new Foo();  
}  

class Foo  
{  
  public String id = "99";  
  public String size = "big";  
  public String height = "tall";  
}  

public class JacksonFoo  
{  
  public static void main(String[] args) throws Exception  
  {  
    ObjectMapper mapper = new ObjectMapper();  
    mapper.getSerializationConfig().addMixInAnnotations(  
        Object.class, PropertyFilterMixIn.class);  

    String[] ignorableFieldNames = { "id", "color" };  
    FilterProvider filters = new SimpleFilterProvider()  
      .addFilter("filter properties by name",   
          SimpleBeanPropertyFilter.serializeAllExcept(  
              ignorableFieldNames));  
    ObjectWriter writer = mapper.writer(filters);  

    System.out.println(writer.writeValueAsString(new Bar()));  
    // output:  
    // {"name":"James","foo":{"size":"big","height":"tall"}}  
  }  
} 

(Примечание. Соответствующий API может немного измениться с недавним выпуском Jackson.)

В то время как в примере используется кажущаяся ненужная аннотация, аннотация не применяется к полям, которые должны быть исключены. (Чтобы помочь изменить API, чтобы немного упростить необходимую конфигурацию, пожалуйста, не стесняйтесь голосовать за реализацию проблемы JACKSON-274.

Ответ 2

Я написал библиотеку для работы с аналогичным вариантом использования. Мне нужно было программно игнорировать поля на основе пользовательских данных. Обычные варианты Джексона были слишком тяжелыми, и я ненавидел то, как это выглядело в моем коде.

Библиотека делает это намного легче понять. Это позволяет вам просто сделать это:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.monitorjbl.json.JsonView;
import com.monitorjbl.json.JsonViewSerializer;
import static com.monitorjbl.json.Match.match;

//initialize jackson
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addSerializer(JsonView.class, new JsonViewSerializer());
mapper.registerModule(module);

 //get a list of the objects
List<MyObject> list = myObjectService.list();

String json;
if(user.getRole().equals('ADMIN')){
    json = mapper.writeValueAsString(list);
} else {
    json = mapper.writeValueAsString(JsonView.with(list)
        .onClass(MyObject.class, match()
           .exclude("*")
           .include("name")));
}

System.out.println(json);

Код доступен на GitHub, надеюсь, что это поможет!

Ответ 3

Джексон полагается на аннотации для большинства вещей, подобных этому; но вам не нужно напрямую комментировать классы значений. Вы также можете использовать "аннотации микширования" (см. http://www.cowtowncoder.com/blog/archives/2009/08/entry_305.html).

И затем есть несколько вариантов, которые вы можете использовать за пределами базового @JsonIgnore (для каждого свойства) или @JsonIgnoreProperties (для каждого класса), см. http://www.cowtowncoder.com/blog/archives/2011/02/entry_443.html

Ответ 4

Если у вас есть фильтры, определенные на двух или более pojo, вы можете попробовать следующее:

@JsonFilter("filterAClass") 
class AClass  
{       
  public String id = "42";  
  public String name = "Fred";  
  public String color = "blue";
  public int sal = 56;
  public BClass bclass = new BClass();  
}  

//@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
@JsonFilter("filterBClass") 
class BClass  
{  

  public String id = "99";  
  public String size = "90";  
  public String height = "tall";  
  public String nulcheck =null;  
}  
public class MultipleFilterConcept {
    public static void main(String[] args) throws Exception  
      {   
        ObjectMapper mapper = new ObjectMapper();
     // Exclude Null Fields
        mapper.setSerializationInclusion(Inclusion.NON_NULL);
        String[] ignorableFieldNames = { "id", "color" };  
        String[] ignorableFieldNames1 = { "height","size" };  
        FilterProvider filters = new SimpleFilterProvider()  
          .addFilter("filterAClass",SimpleBeanPropertyFilter.serializeAllExcept(ignorableFieldNames))
          .addFilter("filterBClass", SimpleBeanPropertyFilter.serializeAllExcept(ignorableFieldNames1));  
        ObjectWriter writer = mapper.writer(filters);
       System.out.println(writer.writeValueAsString(new AClass())); 

      }
}

Ответ 5

Я написал библиотеку под названием Squiggly Filter, которая выбирает поля на основе подмножества синтаксиса API Graph Graph. Например, чтобы выбрать zipCode поля адреса пользовательского объекта, вы должны использовать строку запроса ?fields=address{zipCode}. Одним из преимуществ Squiggly Filter является то, что до тех пор, пока у вас есть доступ к ObjectMapper, который отображает json, вам не нужно изменять код любого из ваших методов контроллера.

Предполагая, что вы используете API сервлета, вы можете сделать следующее:

1) Зарегистрируйте фильтр

<filter> 
    <filter-name>squigglyFilter</filter-name>
    <filter-class>com.github.bohnman.squiggly.web.SquigglyRequestFilter</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>squigglyFilter</filter-name>
    <url-pattern>/**</url-pattern> 
</filter-mapping>

2) Инициализировать ObjectMapper

Squiggly.init(objectMapper, new RequestSquigglyContextProvider());

3) Теперь вы можете фильтровать json

curl https://yourhost/path/to/endpoint?fields=field1,field2{nested1,nested2}

Дополнительная информация о Squiggly Filter доступна на github.