• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.fasterxml.jackson.databind.views;
2 
3 import java.io.*;
4 import java.util.*;
5 
6 import com.fasterxml.jackson.annotation.*;
7 
8 import com.fasterxml.jackson.databind.*;
9 
10 /**
11  * Unit tests for verifying JSON view functionality: ability to declaratively
12  * suppress subset of properties from being serialized.
13  */
14 public class TestViewSerialization
15     extends BaseMapTest
16 {
17     // Classes that represent views
18     static class ViewA { }
19     static class ViewAA extends ViewA { }
20     static class ViewB { }
21     static class ViewBB extends ViewB { }
22 
23     static class Bean
24     {
25         @JsonView(ViewA.class)
26         public String a = "1";
27 
28         @JsonView({ViewAA.class, ViewB.class})
29         public String aa = "2";
30 
31         @JsonView(ViewB.class)
getB()32         public String getB() { return "3"; }
33     }
34 
35     /**
36      * Bean with mix of explicitly annotated
37      * properties, and implicit ones that may or may
38      * not be included in views.
39      */
40     static class MixedBean
41     {
42         @JsonView(ViewA.class)
43         public String a = "1";
44 
getB()45         public String getB() { return "2"; }
46     }
47 
48     /**
49      * As indicated by [JACKSON-261], @JsonView should imply
50      * that associated element (method, field) is to be considered
51      * a property
52      */
53     static class ImplicitBean {
54         @JsonView(ViewA.class)
55         private int a = 1;
56     }
57 
58     static class VisibilityBean {
59         @JsonProperty protected String id = "id";
60 
61         @JsonView(ViewA.class)
62         public String value = "x";
63     }
64 
65     public static class WebView { }
66     public static class OtherView { }
67     public static class Foo {
68         @JsonView(WebView.class)
getFoo()69         public int getFoo() { return 3; }
70     }
71 
72     /*
73     /**********************************************************
74     /* Unit tests
75     /**********************************************************
76      */
77 
78     private final ObjectMapper MAPPER = objectMapper();
79 
80     @SuppressWarnings("unchecked")
testSimple()81     public void testSimple() throws IOException
82     {
83         StringWriter sw = new StringWriter();
84         // Ok, first, using no view whatsoever; all 3
85         Bean bean = new Bean();
86         Map<String,Object> map = writeAndMap(MAPPER, bean);
87         assertEquals(3, map.size());
88 
89         // Then with "ViewA", just one property
90         sw = new StringWriter();
91         MAPPER.writerWithView(ViewA.class).writeValue(sw, bean);
92         map = MAPPER.readValue(sw.toString(), Map.class);
93         assertEquals(1, map.size());
94         assertEquals("1", map.get("a"));
95 
96         // "ViewAA", 2 properties
97         sw = new StringWriter();
98         MAPPER.writerWithView(ViewAA.class).writeValue(sw, bean);
99         map = MAPPER.readValue(sw.toString(), Map.class);
100         assertEquals(2, map.size());
101         assertEquals("1", map.get("a"));
102         assertEquals("2", map.get("aa"));
103 
104         // "ViewB", 2 prop2
105         String json = MAPPER.writerWithView(ViewB.class).writeValueAsString(bean);
106         map = MAPPER.readValue(json, Map.class);
107         assertEquals(2, map.size());
108         assertEquals("2", map.get("aa"));
109         assertEquals("3", map.get("b"));
110 
111         // and "ViewBB", 2 as well
112         json = MAPPER.writerWithView(ViewBB.class).writeValueAsString(bean);
113         map = MAPPER.readValue(json, Map.class);
114         assertEquals(2, map.size());
115         assertEquals("2", map.get("aa"));
116         assertEquals("3", map.get("b"));
117 
118         // and finally, without view.
119         json = MAPPER.writerWithView(null).writeValueAsString(bean);
120         map = MAPPER.readValue(json, Map.class);
121         assertEquals(3, map.size());
122     }
123 
124     /**
125      * Unit test to verify implementation of [JACKSON-232], to
126      * allow "opt-in" handling for JSON Views: that is, that
127      * default for properties is to exclude unless included in
128      * a view.
129      */
130     @SuppressWarnings("unchecked")
testDefaultExclusion()131     public void testDefaultExclusion() throws IOException
132     {
133         MixedBean bean = new MixedBean();
134 
135         // default setting: both fields will get included
136         String json = MAPPER.writerWithView(ViewA.class).writeValueAsString(bean);
137         Map<String,Object> map = MAPPER.readValue(json, Map.class);
138         assertEquals(2, map.size());
139         assertEquals("1", map.get("a"));
140         assertEquals("2", map.get("b"));
141 
142         // but can also change (but not necessarily on the fly...)
143         ObjectMapper mapper = jsonMapperBuilder()
144                 .configure(MapperFeature.DEFAULT_VIEW_INCLUSION, false)
145                 .build();
146 
147         // with this setting, only explicit inclusions count:
148         json = mapper.writerWithView(ViewA.class).writeValueAsString(bean);
149         map = mapper.readValue(json, Map.class);
150         assertEquals(1, map.size());
151         assertEquals("1", map.get("a"));
152         assertNull(map.get("b"));
153 
154         // but without view, view processing disabled:
155         json = mapper.writer().withView(null).writeValueAsString(bean);
156         map = mapper.readValue(json, Map.class);
157         assertEquals(2, map.size());
158         assertEquals("1", map.get("a"));
159         assertEquals("2", map.get("b"));
160     }
161 
162     /**
163      * As per [JACKSON-261], @JsonView annotation should imply that associated
164      * method/field does indicate a property.
165      */
testImplicitAutoDetection()166     public void testImplicitAutoDetection() throws Exception
167     {
168         assertEquals("{\"a\":1}",
169                 MAPPER.writeValueAsString(new ImplicitBean()));
170     }
171 
testVisibility()172     public void testVisibility() throws Exception
173     {
174         VisibilityBean bean = new VisibilityBean();
175         // Without view setting, should only see "id"
176         String json = MAPPER.writerWithView(Object.class).writeValueAsString(bean);
177         //json = mapper.writeValueAsString(bean);
178         assertEquals("{\"id\":\"id\"}", json);
179     }
180 
181     // [JACKSON-868]
test868()182     public void test868() throws IOException
183     {
184         ObjectMapper mapper = new ObjectMapper();
185         mapper.setSerializationInclusion(JsonInclude.Include.NON_DEFAULT);
186         String json = mapper.writerWithView(OtherView.class).writeValueAsString(new Foo());
187         assertEquals(json, "{}");
188     }
189 }
190