1 package com.fasterxml.jackson.databind.ser; 2 3 import java.io.*; 4 import java.util.*; 5 6 import com.fasterxml.jackson.core.JsonGenerator; 7 8 import com.fasterxml.jackson.databind.*; 9 10 /** 11 * Unit tests for checking handling of some of {@link MapperFeature}s 12 * and {@link SerializationFeature}s for serialization. 13 */ 14 public class SerializationFeaturesTest 15 extends BaseMapTest 16 { 17 static class CloseableBean implements Closeable 18 { 19 public int a = 3; 20 21 protected boolean wasClosed = false; 22 23 @Override close()24 public void close() throws IOException { 25 wasClosed = true; 26 } 27 } 28 29 private static class StringListBean { 30 @SuppressWarnings("unused") 31 public Collection<String> values; 32 StringListBean(Collection<String> v)33 public StringListBean(Collection<String> v) { values = v; } 34 } 35 36 /* 37 /********************************************************** 38 /* Test methods 39 /********************************************************** 40 */ 41 42 // Test for [JACKSON-282] 43 @SuppressWarnings("resource") testCloseCloseable()44 public void testCloseCloseable() throws IOException 45 { 46 ObjectMapper m = new ObjectMapper(); 47 // default should be disabled: 48 CloseableBean bean = new CloseableBean(); 49 m.writeValueAsString(bean); 50 assertFalse(bean.wasClosed); 51 52 // but can enable it: 53 m.configure(SerializationFeature.CLOSE_CLOSEABLE, true); 54 bean = new CloseableBean(); 55 m.writeValueAsString(bean); 56 assertTrue(bean.wasClosed); 57 58 // also: let's ensure that ObjectWriter won't interfere with it 59 bean = new CloseableBean(); 60 m.writerFor(CloseableBean.class).writeValueAsString(bean); 61 assertTrue(bean.wasClosed); 62 } 63 64 // Test for [JACKSON-289] testCharArrays()65 public void testCharArrays() throws IOException 66 { 67 char[] chars = new char[] { 'a','b','c' }; 68 ObjectMapper m = new ObjectMapper(); 69 // default: serialize as Strings 70 assertEquals(quote("abc"), m.writeValueAsString(chars)); 71 72 // new feature: serialize as JSON array: 73 m.configure(SerializationFeature.WRITE_CHAR_ARRAYS_AS_JSON_ARRAYS, true); 74 assertEquals("[\"a\",\"b\",\"c\"]", m.writeValueAsString(chars)); 75 } 76 77 // Test for [JACKSON-401] testFlushingAutomatic()78 public void testFlushingAutomatic() throws IOException 79 { 80 ObjectMapper mapper = new ObjectMapper(); 81 assertTrue(mapper.getSerializationConfig().isEnabled(SerializationFeature.FLUSH_AFTER_WRITE_VALUE)); 82 // default is to flush after writeValue() 83 StringWriter sw = new StringWriter(); 84 JsonGenerator g = mapper.createGenerator(sw); 85 mapper.writeValue(g, Integer.valueOf(13)); 86 assertEquals("13", sw.toString()); 87 g.close(); 88 89 // ditto with ObjectWriter 90 sw = new StringWriter(); 91 g = mapper.createGenerator(sw); 92 ObjectWriter ow = mapper.writer(); 93 ow.writeValue(g, Integer.valueOf(99)); 94 assertEquals("99", sw.toString()); 95 g.close(); 96 } 97 testFlushingNotAutomatic()98 public void testFlushingNotAutomatic() throws IOException 99 { 100 // but should not occur if configured otherwise 101 ObjectMapper mapper = new ObjectMapper(); 102 mapper.configure(SerializationFeature.FLUSH_AFTER_WRITE_VALUE, false); 103 StringWriter sw = new StringWriter(); 104 JsonGenerator g = mapper.createGenerator(sw); 105 106 mapper.writeValue(g, Integer.valueOf(13)); 107 // no flushing now: 108 assertEquals("", sw.toString()); 109 // except when actually flushing 110 g.flush(); 111 assertEquals("13", sw.toString()); 112 g.close(); 113 // Also, same should happen with ObjectWriter 114 sw = new StringWriter(); 115 g = mapper.createGenerator(sw); 116 ObjectWriter ow = mapper.writer(); 117 ow.writeValue(g, Integer.valueOf(99)); 118 assertEquals("", sw.toString()); 119 // except when actually flushing 120 g.flush(); 121 assertEquals("99", sw.toString()); 122 g.close(); 123 } 124 testSingleElementCollections()125 public void testSingleElementCollections() throws IOException 126 { 127 final ObjectWriter writer = objectWriter().with(SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED); 128 129 // Lists: 130 ArrayList<String> strs = new ArrayList<String>(); 131 strs.add("xyz"); 132 assertEquals(quote("xyz"), writer.writeValueAsString(strs)); 133 ArrayList<Integer> ints = new ArrayList<Integer>(); 134 ints.add(13); 135 assertEquals("13", writer.writeValueAsString(ints)); 136 137 // other Collections, like Sets: 138 HashSet<Long> longs = new HashSet<Long>(); 139 longs.add(42L); 140 assertEquals("42", writer.writeValueAsString(longs)); 141 // [databind#180] 142 final String EXP_STRINGS = "{\"values\":\"foo\"}"; 143 assertEquals(EXP_STRINGS, writer.writeValueAsString(new StringListBean(Collections.singletonList("foo")))); 144 145 final Set<String> SET = new HashSet<String>(); 146 SET.add("foo"); 147 assertEquals(EXP_STRINGS, writer.writeValueAsString(new StringListBean(SET))); 148 149 // arrays: 150 assertEquals("true", writer.writeValueAsString(new boolean[] { true })); 151 assertEquals("[true,false]", writer.writeValueAsString(new boolean[] { true, false })); 152 assertEquals("true", writer.writeValueAsString(new Boolean[] { Boolean.TRUE })); 153 154 assertEquals("3", writer.writeValueAsString(new short[] { 3 })); 155 assertEquals("[3,2]", writer.writeValueAsString(new short[] { 3, 2 })); 156 157 assertEquals("3", writer.writeValueAsString(new int[] { 3 })); 158 assertEquals("[3,2]", writer.writeValueAsString(new int[] { 3, 2 })); 159 160 assertEquals("1", writer.writeValueAsString(new long[] { 1L })); 161 assertEquals("[-1,4]", writer.writeValueAsString(new long[] { -1L, 4L })); 162 163 assertEquals("0.5", writer.writeValueAsString(new double[] { 0.5 })); 164 assertEquals("[0.5,2.5]", writer.writeValueAsString(new double[] { 0.5, 2.5 })); 165 166 assertEquals("0.5", writer.writeValueAsString(new float[] { 0.5f })); 167 assertEquals("[0.5,2.5]", writer.writeValueAsString(new float[] { 0.5f, 2.5f })); 168 169 assertEquals(quote("foo"), writer.writeValueAsString(new String[] { "foo" })); 170 } 171 } 172