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}
