如何为 JAXB 设置浮点格式(json 使用 eclipse moxy)
How to set floating point format for JAXB (json using eclipse moxy)
我有一个简单的 pojo class:
@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 returns 一个字符串(不是因为 FORMAT 放置了引号。它没有)
是否有任何 JAXB/moxy 注释可以让我在不将字段转换为 json 字符串的情况下控制格式?
此解决方案正在使用 EclipseLink MOXy
中的 transformation annotations。
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);
}
}
我有一个简单的 pojo class:
@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 returns 一个字符串(不是因为 FORMAT 放置了引号。它没有)
是否有任何 JAXB/moxy 注释可以让我在不将字段转换为 json 字符串的情况下控制格式?
此解决方案正在使用 EclipseLink MOXy
中的 transformation annotations。
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);
}
}