I use gson.toJson and gson.fromGson methods. I have a class like below.
@XmlType(name = "CBPR_CancellationReasonCode")
@XmlEnum
public enum CBPRCancellationReasonCode {
DUPL("DUPL"),
CUTA("CUTA"),
UPAY("UPAY"),
CUST("CUST"),
CURR("CURR"),
AGNT("AGNT"),
TECH("TECH"),
FRAD("FRAD"),
COVR("COVR"),
@XmlEnumValue("AM09")
AM_09("AM09"),
NARR("NARR");
private final String value;
CBPRCancellationReasonCode(String v) {
value = v;
}
public String value() {
return value;
}
public static CBPRCancellationReasonCode fromValue(String v) {
for (CBPRCancellationReasonCode c: CBPRCancellationReasonCode.values()) {
if (c.value.equals(v)) {
return c;
}
}
throw new IllegalArgumentException(v);
}
}
I have problem converting values from xml to json or json to xml while using
@XmlEnumValue("AM09")
AM_09("AM09")
I expect to see "AM09" value but it takes AM_09.
How can I solve this problem?
Some parts of my code are as follows.
Gson gson = new GsonBuilder().setFieldNamingStrategy(new XsdAnnotation()).setPrettyPrinting()
.registerTypeHierarchyAdapter(XMLGregorianCalendar.class,
new XMLGregorianCalendarConverter.Serializer())
.registerTypeHierarchyAdapter(XMLGregorianCalendar.class,
new XMLGregorianCalendarConverter.Deserializer())
.create();
gson.toJson(testObject)
public class XsdAnnotation implements FieldNamingStrategy {
@Override
public String translateName(Field field) {
XmlElement fieldNamingPolicyElement = field.getAnnotation(XmlElement.class);
XmlAttribute fieldNamingPolicyAttribute = field.getAnnotation(XmlAttribute.class);
return fieldNamingPolicyElement != null
? fieldNamingPolicyElement.name()
: (fieldNamingPolicyAttribute != null ? fieldNamingPolicyAttribute.name() : field.getName());
}
}
With @Vijay's guidance, my problem was solved with the following code.
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import jakarta.xml.bind.annotation.XmlEnumValue;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class EnumTypeAdapter<T extends Enum<T>> extends TypeAdapter<T> {
private final Map<String, T> nameToConstant = new HashMap<String, T>();
private final Map<T, String> constantToName = new HashMap<T, String>();
public EnumTypeAdapter(Class<T> classOfT) {
try {
for (T constant : classOfT.getEnumConstants()) {
String name = constant.name();
XmlEnumValue annotation = classOfT.getField(name).getAnnotation(XmlEnumValue.class);
if (annotation != null) {
name = annotation.value();
}
nameToConstant.put(name, constant);
constantToName.put(constant, name);
}
} catch (NoSuchFieldException e) {
throw new AssertionError();
}
}
public T read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
return nameToConstant.get(in.nextString());
}
public void write(JsonWriter out, T value) throws IOException {
out.value(value == null ? null : constantToName.get(value));
}
public static final TypeAdapterFactory ENUM_FACTORY = new TypeAdapterFactory() {
@SuppressWarnings({"rawtypes", "unchecked"})
@Override public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
Class<? super T> rawType = typeToken.getRawType();
if (!Enum.class.isAssignableFrom(rawType) || rawType == Enum.class) {
return null;
}
if (!rawType.isEnum()) {
rawType = rawType.getSuperclass();
}
return (TypeAdapter<T>) new EnumTypeAdapter(rawType);
}
};
}
Gson gson = new GsonBuilder().setFieldNamingStrategy(new XsdAnnotation()).setPrettyPrinting()
.registerTypeHierarchyAdapter(XMLGregorianCalendar.class,
new XMLGregorianCalendarConverter.Serializer())
.registerTypeHierarchyAdapter(XMLGregorianCalendar.class,
new XMLGregorianCalendarConverter.Deserializer())
.registerTypeAdapterFactory(EnumTypeAdapter.ENUM_FACTORY)
.create();