# Feature: JSON Views

### Idea

"Views" in this context mean ability to define subsets of logical properties (things accessed via getters or fields) to serialize. Views are defined statically (using annotations), but view to use for serialization is chosen dynamically (per serialization).

“Views”，在这个语境中，意思是为将要序列化的逻辑属性（通过get方法或者字段获取到的）定义一个子集。views是通过注解（annotations）来静态定义的，但是使用的时候是动态选择的（每个需要序列化的地方自己选择使用哪些views）

### Design

• Views themselves are identified by using Classes, instead of Strings (or dedicated objects). Reasons:

• views是使用类来定义的，而不是使用字符串，或者其它某些特定的实例。原因是：

• With classes, can use inheritance to naturally (?) represent View hierarchies (if a field is part of a View, it'll be also part of parent view)

• 使用类，就可以使用继承来更加自然的展示views的结构（如果一个字段是某个view的一部分，那么它也是父级view的一部分）

• Classes can be used as annotation values: Enums not (Enums would have been one other obvious possibility)

• 类可以用作注解中的值，而枚举不可以（枚举也是另一个可能用作view的设计）

• For future extensibility, classes can also be annotated if need be (no plans for such annotations yet)

• 考虑未来的扩展性，如果有必要的话，（用作vies定义的）类本身也可以被打上注解（不过不在现有标签的计划中）

• View membership defined using annotations: specify which view(s)property will be included in. If no view annotation, assumed to mean View identified by Object.class: that is, included in all views

• 我们是这样定义视图注解的使用方式的：为某个属性标记上某个注解，标示这个属性将被包含在（最终的json字符串之）内。如果某个属性上没有任何注解，则认为它被标记为“Object.class"的视图，并会被包含在所有视图中。

• View to use for serialization (and with 2.0, deserialization) is specified dynamically; active view is a property of SerializationConfig (and DeserializationConfig). Conceptually defaults to Object.class; as if no View functionality was used at all.

• 在序列化为json的过程中（以及，在2.0中，还包括反序列化的过程），view是动态指定的。一个view是一个SerializationConfig (对反序列化来说则是DeserializationConfig)的一个属性。这个属性的默认值是Object.class，其功能和不使用view是一样的。

• Only single active view per serialization; but due to inheritance of Views, can combine Views via aggregation.

• 每次序列化都只能使用一个视图；但是，考虑到视图的继承层次，可以把多个视图组合成一个。

• All view membership inclusive, no need for exclusions? (however: could add an option to change default handling of 'unmarked' properties to mean "don't include unless specifically identified)

• view的用法都是“包含在序列化结果”中的，没有“排除在序列化结果之外”的语义。（不过，可以增加一个选项来改变对“unmarked”属性的默认处理方式——把它改成“除非特别声明，否则不把被标记属性包含在序列化结果中”）

### Implementation

1.4 implementation is used as follows.

1.4版的实现是这样使用的。

First, defining views means declaring classes; you can reuse existing ones, or just create bogus classes -- they are just view identifiers with relationship information (child inherits view membership from parents):

  // View definitions:
class Views {
static class Public { }
static class ExtendedPublic extends PublicView { }
static class Internal extends ExtendedPublicView { }
}

public class Bean {
// Name is public
@JsonView(Views.Public.class) String name;
// Address semi-public
@JsonView(Views.ExtendPublic.class) Address address;
// SSN only for internal usage
@JsonView(Views.Internal.class) SocialSecNumber ssn;
}

With such view definitions, serialization would be done like so:

  // short-cut:
objectMapper.writeValueUsingView(out, beanInstance, ViewsPublic.class);

// or fully exploded:
objectMapper.getSerializationConfig().setSerializationView(Views.Public.class);
// (note: can also pre-construct config object with 'mapper.copySerializationConfig'; reuse)
objectMapper.writeValue(out, beanInstance); // will use active view set via Config

// or, starting with 1.5, more convenient (ObjectWriter is reusable too)
objectMapper.viewWriter(ViewsPublic.class).writeValue(out, beanInstance);

and result would only contain 'name', not 'address' or 'ssn'.

NOTE: even if you only want to use "default" view -- that is, just exclude things that are only to be included in specific "full" view -- you DO need to enable View processing by specifying a view. If you do not have explicit "basic" view setting, just use Object.class.

### Handling of "view-less" properties

By default all properties without explicit view definition are included in serialization. But starting with Jackson 1.5 you can change this default by:

  objectMapper.configure(SerializationConfig.Feature.DEFAULT_VIEW_INCLUSION, false);

where false means that such properties are NOT included when enabling with a view. Default for this property is 'true'.

### Customization

Although default implementation is not very customizable, underlying design does allow for implementing elaborate custom filtering, using alternative means of defining custom views. Here is how.

#### Enabling "view" processing

Depending on exactly how custom serialization is implemented, you may (or may not) need to enable view processing. If it is needed, you will just do something like:

  ObjectWriter w = objectMapper.viewWriter(SomeClass.class); // 1.8 and prior
ObjectWriter w = objectMapper.writerWithView(SomeClass.class); // 1.9 and above

which offers same set of writeValue (and writeValueAsString, writeValueAsBytes, ...) write methods and can be reused easily (or passed).

As of 2.0 this is also available for deserialization, like so:

  ObjectReader r = objectMapper.readerWithView(SomeClass.class); // 2.0 and above

#### Views with JAX-RS

With 2.3 (of JAX-RS module) it is also possible to annotate JAX-RS resources like so:

    public class Resource {

@JsonView(Views.Public.class)
@GET
@Produces(MediaType.APPLICATION_JSON )
public List<Object> getElements() {
...
return someResultList;
}
}

so that you need not try to configure active view via ObjectReader / ObjectWriter.

+ 订阅