我有一个简单的 pojo 类:
@XmlRootElement
public static class MyClass {
private double f; //[0-1]
@XmlAttribute
//@XmlJavaTypeAdapter(FixedFloatingPointXmlAdapter.class) <-- has issues
public double getF() {
return f;
}
}
字段 f 保存范围 [0,1] 内的值,该范围有时可能很小。我想避免看到诸如 1.234E-7(科学计数法)之类的内容,并希望设置用于打印字段 f 的格式。
我已经看到其他建议为此使用 XmlAdapter 的答案,如下所示:
public class FixedFloatingPointXmlAdapter extends XmlAdapter<String, Double> {
private static final DecimalFormat FORMAT = new DecimalFormat("0.00000000");
@Override
public Double unmarshal(String v) throws Exception {
return v == null ? null : Double.parseDouble(v);
}
@Override
public String marshal(Double v) throws Exception {
return v == null ? null : FORMAT.format(v);
}
}
但这样做的问题是,该值将作为 json STRING 打印出来(因此 "0.25000000"
而不是 0.25000000
) - 因为 XmlAdapter 返回一个字符串(不是因为 FORMAT 放置了引号。它没有)
是否有任何 JAXB/moxy 注释可以让我控制格式而不将字段转换为 json 字符串?
最佳答案
此解决方案使用 transformation annotations EclipseLink MOXy
。
import org.eclipse.persistence.oxm.annotations.XmlTransformation;
import org.eclipse.persistence.oxm.annotations.XmlWriteTransformer;
@XmlRootElement
public static class MyClass {
@XmlAttribute
@XmlReadTransformer(transformerClass=FixedFloatingTransformer.class)
@XmlWriteTransformer(xmlPath="@f", transformerClass=FixedFloatingTransformer.class)
private double f; //[0-1]
public double getF() {
return f;
}
}
这是transformerClass
的实现。
import java.text.DecimalFormat;
import org.eclipse.persistence.mappings.foundation.AbstractTransformationMapping;
import org.eclipse.persistence.mappings.transformers.AttributeTransformer;
import org.eclipse.persistence.mappings.transformers.FieldTransformer;
import org.eclipse.persistence.sessions.Record;
import org.eclipse.persistence.sessions.Session;
public class FixedFloatingTransformer implements FieldTransformer, AttributeTransformer {
private AbstractTransformationMapping mapping;
private static DecimalFormat FORMAT = new DecimalFormat("0.00000000");
public Object buildAttributeValue(Record r, Object obj, Session arg2) {
return r.get(mapping.getFields().get(0));
}
public Object buildFieldValue(Object instance, String xpath, Session session) {
Object o2 = mapping.getAttributeValueFromObject(instance);
if (o2 instanceof Number) {
return ((DecimalFormat)FORMAT.clone()).format((Number)o2);
}
return null;
}
public void initialize(AbstractTransformationMapping mapping) {
this.mapping = mapping;
}
}
2016/12/13更新
当 moxy
将对象解码为 JSON 字符串时,将引用 @XmlSchemaType
。
如果name
是boolean
或number type
,moxy
将输出不带引号的字符的值字符串。
Sample 1: You have to set formated value to
f
.
public static class MyClass {
private String f;
@XmlAttribute
@XmlSchemaType(name="double")
public String getF() {
return f;
}
}
Sample 2 : Add extra getter to return formatted value.
public static class MyClass {
private double f;
@XmlTransient //preventing the mapping
public double getF() {
return f;
}
@XmlAttribute(name="f")
@XmlSchemaType(name="double")
public String getFAsString() {
return new DecimalFormat("0.00000000").format(f);
}
}
关于java - 如何为JAXB设置浮点格式(使用eclipse moxy的json),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41029066/