Java – get different JSON representations of the same object
Give a Java object serialized as a JSON string with Jackson
Compression:
{ "a":"123","s":"100" }
Or normal:
{ "altitude":"123","speed":"100" }
Edit: the goal I want to achieve through this goal is to have a long JSON format, which is suitable for debugging (human readable) and has a compressed format that provides minimum space
Solution
You can do this in many ways It depends on your requirements I suggest you implement your own attribute naming strategy See the following example:
class CompressedPropertyNamingStrategy extends PropertyNamingStrategyBase { private static final long serialVersionUID = 1L; @Override public String translate(String name) { return String.valueOf(name.charAt(0)); } }
You can use it this way:
ObjectMapper mapper = new ObjectMapper(); mapper.setPropertyNamingStrategy(new CompressedPropertyNamingStrategy()); String json = mapper.writeValueAsString(new Pojo());
If you don't want to compress attribute names, just delete line 2
Editor 1 after the @ aumand comment, I want to inform you that this solution does not apply to entities that contain many attributes starting with the same letter We have to write more complex solutions For example:
class CompressedPropertyNamingStrategy extends PropertyNamingStrategyBase { private static final long serialVersionUID = 1L; private final int length; public CompressedPropertyNamingStrategy(int length) { this.length = length; } @Override public String translate(String name) { if (name.length() < length) { return name; } return name.substring(0,length); } }
Edit 2 if you really want to control property names during serialization, you should implement your own comments For example:
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(value = { ElementType.METHOD,ElementType.FIELD }) @Retention(value = RetentionPolicy.RUNTIME) public @interface CompressedName { String value(); }
In this case, your naming policy might be as follows:
class CompressedPropertyNamingStrategy extends PropertyNamingStrategy { private static final long serialVersionUID = 1L; @Override public String nameForGetterMethod(MapperConfig<?> config,AnnotatedMethod method,String defaultName) { CompressedName compressedProperty = method.getAnnotation(CompressedName.class); if (compressedProperty != null) { return compressedProperty.value(); } // Implement default value: first letter,or something else return defaultName; } }
Now you must add comments to the entity method:
class Entity { private long altitude = 123; private int speed = 100; @CompressedName("a") public long getAltitude() { return altitude; } public void setAltitude(long altitude) { this.altitude = altitude; } @CompressedName("sp") public int getSpeed() { return speed; } public void setSpeed(int speed) { this.speed = speed; } }
In this scenario example, JSON may be as follows:
{"a":123,"sp":100}