• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.fasterxml.jackson.databind.convert;
2 
3 import com.fasterxml.jackson.core.JsonProcessingException;
4 import com.fasterxml.jackson.databind.*;
5 import com.fasterxml.jackson.databind.cfg.CoercionAction;
6 import com.fasterxml.jackson.databind.cfg.CoercionInputShape;
7 import com.fasterxml.jackson.databind.exc.MismatchedInputException;
8 import com.fasterxml.jackson.databind.type.LogicalType;
9 
10 public class CoercePojosTest extends BaseMapTest
11 {
12     static class Bean {
13         public String a;
14     }
15 
16     private final ObjectMapper MAPPER = newJsonMapper();
17 
18     private final String JSON_EMPTY = quote("");
19     private final String JSON_BLANK = quote("    ");
20 
21     /*
22     /********************************************************
23     /* Test methods, from empty String
24     /********************************************************
25      */
26 
testPOJOFromEmptyStringLegacy()27     public void testPOJOFromEmptyStringLegacy() throws Exception
28     {
29         // first, verify default settings which do not accept empty String:
30         assertFalse(MAPPER.isEnabled(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT));
31 
32         // should be ok to enable dynamically
33         _verifyFromEmptyPass(MAPPER.reader()
34                 .with(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT),
35                 JSON_EMPTY);
36 
37     }
38 
testPOJOFromEmptyGlobalConfig()39     public void testPOJOFromEmptyGlobalConfig() throws Exception
40     {
41         _testPOJOFromEmptyGlobalConfig(CoercionInputShape.EmptyString, JSON_EMPTY, null);
42     }
43 
testPOJOFromEmptyLogicalTypeConfig()44     public void testPOJOFromEmptyLogicalTypeConfig() throws Exception
45     {
46         _testPOJOFromEmptyLogicalTypeConfig(CoercionInputShape.EmptyString, JSON_EMPTY, null);
47     }
48 
testPOJOFromEmptyPhysicalTypeConfig()49     public void testPOJOFromEmptyPhysicalTypeConfig() throws Exception
50     {
51         _testPOJOFromEmptyPhysicalTypeConfig(CoercionInputShape.EmptyString, JSON_EMPTY, null);
52     }
53 
54     /*
55     /********************************************************
56     /* Test methods, from blank String
57     /********************************************************
58      */
59 
testPOJOFromBlankGlobalConfig()60     public void testPOJOFromBlankGlobalConfig() throws Exception
61     {
62         _testPOJOFromEmptyGlobalConfig(CoercionInputShape.EmptyString, JSON_BLANK, Boolean.TRUE);
63     }
64 
testPOJOFromBlankLogicalTypeConfig()65     public void testPOJOFromBlankLogicalTypeConfig() throws Exception
66     {
67         _testPOJOFromEmptyLogicalTypeConfig(CoercionInputShape.EmptyString, JSON_BLANK, Boolean.TRUE);
68     }
69 
testPOJOFromBlankPhysicalTypeConfig()70     public void testPOJOFromBlankPhysicalTypeConfig() throws Exception
71     {
72         _testPOJOFromEmptyPhysicalTypeConfig(CoercionInputShape.EmptyString, JSON_BLANK, Boolean.TRUE);
73     }
74 
75     /*
76     /********************************************************
77     /* Second-level helper methods
78     /********************************************************
79      */
80 
_testPOJOFromEmptyGlobalConfig(final CoercionInputShape shape, final String json, Boolean allowEmpty)81     private void _testPOJOFromEmptyGlobalConfig(final CoercionInputShape shape, final String json,
82             Boolean allowEmpty)
83         throws Exception
84     {
85         ObjectMapper mapper;
86 
87         // First, coerce to null
88         mapper = newJsonMapper();
89         mapper.coercionConfigDefaults().setCoercion(shape, CoercionAction.AsNull)
90             .setAcceptBlankAsEmpty(allowEmpty);
91         assertNull(_verifyFromEmptyPass(mapper, json));
92 
93         // Then coerce as empty
94         mapper = newJsonMapper();
95         mapper.coercionConfigDefaults().setCoercion(shape, CoercionAction.AsEmpty)
96             .setAcceptBlankAsEmpty(allowEmpty);
97         Bean b = _verifyFromEmptyPass(mapper, json);
98         assertNotNull(b);
99 
100         // and finally, "try convert", which aliases to 'null'
101         mapper = newJsonMapper();
102         mapper.coercionConfigDefaults().setCoercion(shape, CoercionAction.TryConvert)
103             .setAcceptBlankAsEmpty(allowEmpty);
104         assertNull(_verifyFromEmptyPass(mapper, json));
105     }
106 
_testPOJOFromEmptyLogicalTypeConfig(final CoercionInputShape shape, final String json, Boolean allowEmpty)107     private void _testPOJOFromEmptyLogicalTypeConfig(final CoercionInputShape shape, final String json,
108             Boolean allowEmpty)
109         throws Exception
110     {
111         ObjectMapper mapper;
112 
113         // First, coerce to null
114         mapper = newJsonMapper();
115         mapper.coercionConfigFor(LogicalType.POJO).setCoercion(shape, CoercionAction.AsNull)
116             .setAcceptBlankAsEmpty(allowEmpty);
117         assertNull(_verifyFromEmptyPass(mapper, json));
118 
119         // Then coerce as empty
120         mapper = newJsonMapper();
121         mapper.coercionConfigFor(LogicalType.POJO).setCoercion(shape, CoercionAction.AsEmpty)
122             .setAcceptBlankAsEmpty(allowEmpty);
123         Bean b = _verifyFromEmptyPass(mapper, json);
124         assertNotNull(b);
125 
126         // But also make fail again with 2-level settings
127         mapper = newJsonMapper();
128         mapper.coercionConfigDefaults().setCoercion(shape, CoercionAction.AsNull)
129             .setAcceptBlankAsEmpty(allowEmpty);
130         mapper.coercionConfigFor(LogicalType.POJO).setCoercion(shape,
131                 CoercionAction.Fail);
132         _verifyFromEmptyFail(mapper, json);
133     }
134 
_testPOJOFromEmptyPhysicalTypeConfig(final CoercionInputShape shape, final String json, Boolean allowEmpty)135     private void _testPOJOFromEmptyPhysicalTypeConfig(final CoercionInputShape shape, final String json,
136             Boolean allowEmpty)
137         throws Exception
138     {
139         ObjectMapper mapper;
140 
141         // First, coerce to null
142         mapper = newJsonMapper();
143         mapper.coercionConfigFor(Bean.class).setCoercion(shape, CoercionAction.AsNull)
144             .setAcceptBlankAsEmpty(allowEmpty);
145         assertNull(_verifyFromEmptyPass(mapper, json));
146 
147         // Then coerce as empty
148         mapper = newJsonMapper();
149         mapper.coercionConfigFor(Bean.class).setCoercion(shape, CoercionAction.AsEmpty)
150             .setAcceptBlankAsEmpty(allowEmpty);
151         Bean b = _verifyFromEmptyPass(mapper, json);
152         assertNotNull(b);
153 
154         // But also make fail again with 2-level settings, with physical having precedence
155         mapper = newJsonMapper();
156         mapper.coercionConfigFor(LogicalType.POJO).setCoercion(shape, CoercionAction.AsEmpty)
157             .setAcceptBlankAsEmpty(allowEmpty);
158         mapper.coercionConfigFor(Bean.class).setCoercion(shape, CoercionAction.Fail);
159         _verifyFromEmptyFail(mapper, json);
160     }
161 
_verifyFromEmptyPass(ObjectMapper m, String json)162     private Bean _verifyFromEmptyPass(ObjectMapper m, String json) throws Exception {
163         return _verifyFromEmptyPass(m.reader(), json);
164     }
165 
_verifyFromEmptyPass(ObjectReader r, String json)166     private Bean _verifyFromEmptyPass(ObjectReader r, String json) throws Exception
167     {
168         return r.forType(Bean.class)
169                 .readValue(json);
170     }
171 
_verifyFromEmptyFail(ObjectMapper m, String json)172     private void _verifyFromEmptyFail(ObjectMapper m, String json) throws Exception
173     {
174         try {
175             m.readValue(json, Bean.class);
176             fail("Should not accept Empty/Blank String for POJO with passed settings");
177         } catch (MismatchedInputException e) {
178             _verifyFailMessage(e);
179         }
180     }
181 
_verifyFailMessage(JsonProcessingException e)182     private void _verifyFailMessage(JsonProcessingException e)
183     {
184         verifyException(e, "Cannot deserialize value of type ");
185         verifyException(e, " from empty String ", " from blank String ");
186         assertValidLocation(e.getLocation());
187     }
188 }
189