Skip to content

FEATURE: Allow to specify a Json View to serialize a property of an object #132

Open

Description

@ccasallas

Currently it's not possible to serialize the property of an object specifying a Json view. Please create a new @JsonUseView annotation to be able to specify a view used to serialize the property.

public class Company {
  @JsonView(View.Basic.class)
  private Long id;

  @JsonView(View.Basic.class)
  private String name;

  private String extraData;
  private String sensitiveData;
  private String privateData;
  ...
}

public class User{
  private Long id;
  private String name;

  @UseJsonView(View.Basic.class)
  private Company company;
  ...
}

Or create a new set of annotations that allow this feature. For example:

@JsonViews(views={
  @View(name="basic", fields=["id", "name"]),
  @View(name="otherView", fields=["id", "name", "extraData"]),
})
public class Company {
  private Long id;
  private String name;
  private String extraData;
  private String sensitiveData;
  private String privateData;
  ...
}

public class User{
  private Long id;
  private String name;

  @UseJsonView("basic")
  private Company company;
  ...
}

Activity

  1. changed the title [-]FEATURE: Enable to serialize a property using Json views feature[/-] [+]FEATURE: Allow to specify a Json View to serialize a property[/+] on Mar 27, 2018
  2. changed the title [-]FEATURE: Allow to specify a Json View to serialize a property[/-] [+]FEATURE: Allow to specify a Json View to serialize a property of a object[/+] on Mar 27, 2018
  3. changed the title [-]FEATURE: Allow to specify a Json View to serialize a property of a object[/-] [+]FEATURE: Allow to specify a Json View to serialize a property of an object[/+] on Mar 27, 2018
  4. lenxeon commented on Feb 4, 2020

    @lenxeon

    what the content about UseJsonView ?

  5. jwang0512 commented on Apr 8, 2025

    @jwang0512

    Really need this one, an update or any other alternative ways please?

  6. cowtowncoder commented on Apr 8, 2025

    @cowtowncoder
    Member

    @jwang0512 If there was an update, it'd be here. I don't think anyone is implementing such support -- support would be added via jackson-databind repository, beyond addition of a new annotation here.

    I am not sure implementing this is practical, either, since it would clash with per-call View setting. But whoever wanted to implement that would need to figure it out.

  7. jwang0512 commented on Apr 9, 2025

    @jwang0512

    Thanks for your reply @cowtowncoder

    I want this because I need to serialize different fields in different situations. Here is my example

    class Item {
      public interface BasicView {}
      public interface AdvanceView extends BasicView {}
      @JsonView(BasicView.class)
      Integer id;
      @JsonView(BasicView.class)
      String name;
      @JsonView(AdvancedView.class)
      Integer code;
      String comment;
    }
    
    class Data {
      Item itemA; //  BasicView
      Item itemB; //  AdvancedView
      String address;
    }

    and here is my implementation. for anyone who need this:

    @Target({ElementType.FIELD})
    @Retention(RetentionPolicy.RUNTIME)
    @JacksonAnnotationsInside
    @JsonSerialize(using = UseJsonViewSerializer.class)
    public @interface UseJsonView {
        Class<?> value();
    }
    public class UseJsonViewSerializer extends JsonSerializer<Object> implements ContextualSerializer {
        private final Class<?> viewClass;
    
        public UseJsonViewSerializer() {
            this.viewClass = null; // default for Jackson to construct first
        }
    
        public UseJsonViewSerializer(Class<?> viewClass) {
            this.viewClass = viewClass;
        }
    
        @Override
        public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
            if (property != null) {
                UseJsonView ann = property.getAnnotation(UseJsonView.class);
                if (ann == null) ann = property.getContextAnnotation(UseJsonView.class);
                if (ann != null) {
                    return new UseJsonViewSerializer(ann.value());
                }
            }
            return this;
        }
    
        @Override
        public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
            if (viewClass == null || value == null) {
                gen.writeObject(value);
                return;
            }
    
            ObjectMapper mapper = (ObjectMapper) gen.getCodec();
            ObjectWriter writer = mapper.writerWithView(viewClass);
    
            if (value instanceof Collection<?> collection) {
                gen.writeStartArray();
                for (Object item : collection) {
                    if (item == null) gen.writeNull();
                    else writer.writeValue(gen, item);
                }
                gen.writeEndArray();
    
            } else if (value.getClass().isArray()) {
                gen.writeStartArray();
                int len = Array.getLength(value);
                for (int i = 0; i < len; i++) {
                    Object item = Array.get(value, i);
                    if (item == null) gen.writeNull();
                    else writer.writeValue(gen, item);
                }
                gen.writeEndArray();
            } else if (value instanceof Map<?, ?> map) {
                gen.writeStartObject();
                for (Map.Entry<?, ?> entry : map.entrySet()) {
                    Object key = entry.getKey();
                    if (key != null) {
                        gen.writeFieldName(key.toString());
                        Object item = entry.getValue();
                        if (item == null) gen.writeNull();
                        else writer.writeValue(gen, item);
                    }
                }
                gen.writeEndObject();
            } else {
                writer.writeValue(gen, value);
            }
        }
    }
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions