1 package com.fasterxml.jackson.databind.ser.std; 2 3 import java.io.IOException; 4 import java.net.InetAddress; 5 6 import com.fasterxml.jackson.annotation.JsonFormat; 7 import com.fasterxml.jackson.core.*; 8 import com.fasterxml.jackson.core.type.WritableTypeId; 9 import com.fasterxml.jackson.databind.BeanProperty; 10 import com.fasterxml.jackson.databind.JsonMappingException; 11 import com.fasterxml.jackson.databind.JsonSerializer; 12 import com.fasterxml.jackson.databind.SerializerProvider; 13 import com.fasterxml.jackson.databind.jsontype.TypeSerializer; 14 import com.fasterxml.jackson.databind.ser.ContextualSerializer; 15 16 /** 17 * Simple serializer for {@link java.net.InetAddress}. Main complexity is 18 * with registration, since same serializer is to be used for sub-classes. 19 *<p> 20 * Since 2.9 allows use of {@link JsonFormat} configuration (annotation, 21 * per-type defaulting) so that if <code>JsonFormat.Shape.NUMBER</code> 22 * (or <code>ARRAY</code>) is used, will serialize as "host address" 23 * (dotted numbers) instead of simple conversion. 24 */ 25 @SuppressWarnings("serial") 26 public class InetAddressSerializer 27 extends StdScalarSerializer<InetAddress> 28 implements ContextualSerializer 29 { 30 /** 31 * @since 2.9 32 */ 33 protected final boolean _asNumeric; 34 InetAddressSerializer()35 public InetAddressSerializer() { 36 this(false); 37 } 38 39 /** 40 * @since 2.9 41 */ InetAddressSerializer(boolean asNumeric)42 public InetAddressSerializer(boolean asNumeric) { 43 super(InetAddress.class); 44 _asNumeric = asNumeric; 45 } 46 47 @Override createContextual(SerializerProvider serializers, BeanProperty property)48 public JsonSerializer<?> createContextual(SerializerProvider serializers, 49 BeanProperty property) throws JsonMappingException 50 { 51 JsonFormat.Value format = findFormatOverrides(serializers, 52 property, handledType()); 53 boolean asNumeric = false; 54 if (format != null) { 55 JsonFormat.Shape shape = format.getShape(); 56 if (shape.isNumeric() || shape == JsonFormat.Shape.ARRAY) { 57 asNumeric = true; 58 } 59 } 60 if (asNumeric != _asNumeric) { 61 return new InetAddressSerializer(asNumeric); 62 } 63 return this; 64 } 65 66 @Override serialize(InetAddress value, JsonGenerator g, SerializerProvider provider)67 public void serialize(InetAddress value, JsonGenerator g, SerializerProvider provider) throws IOException 68 { 69 String str; 70 71 if (_asNumeric) { // since 2.9 72 str = value.getHostAddress(); 73 } else { 74 // Ok: get textual description; choose "more specific" part 75 str = value.toString().trim(); 76 int ix = str.indexOf('/'); 77 if (ix >= 0) { 78 if (ix == 0) { // missing host name; use address 79 str = str.substring(1); 80 } else { // otherwise use name 81 str = str.substring(0, ix); 82 } 83 } 84 } 85 g.writeString(str); 86 } 87 88 @Override serializeWithType(InetAddress value, JsonGenerator g, SerializerProvider provider, TypeSerializer typeSer)89 public void serializeWithType(InetAddress value, JsonGenerator g, 90 SerializerProvider provider, TypeSerializer typeSer) throws IOException 91 { 92 // Better ensure we don't use specific sub-classes... 93 WritableTypeId typeIdDef = typeSer.writeTypePrefix(g, 94 typeSer.typeId(value, InetAddress.class, JsonToken.VALUE_STRING)); 95 serialize(value, g, provider); 96 typeSer.writeTypeSuffix(g, typeIdDef); 97 } 98 } 99