Java 是否要将构造函数参数传递给JAXB适配器?
我在自己编写的Web服务中使用Spring3IOC和JAXB/JAX-WS。我现在有一个小问题,数据必须在返回给消费者之前四舍五入,因为它们无法处理值的完整精度 为了尽量减少对WS-design和计算的影响,我选择使用JAXBXMLAdapter在整理响应时对值进行四舍五入。一切正常 我现在的问题是,我想让它变得灵活。Ie:在某些情况下,我需要四舍五入到小数点后2位,大约4位,等等。。现在,我必须创建一个TwoDecimalAdapter和一个FourDecimalAdapter,并在模型定义中使用适当的一个。这意味着代码重复 是否有创建通用舍入适配器并向其传递参数的方法?例如,而不是:Java 是否要将构造函数参数传递给JAXB适配器?,java,spring,jaxb,adapter,Java,Spring,Jaxb,Adapter,我在自己编写的Web服务中使用Spring3IOC和JAXB/JAX-WS。我现在有一个小问题,数据必须在返回给消费者之前四舍五入,因为它们无法处理值的完整精度 为了尽量减少对WS-design和计算的影响,我选择使用JAXBXMLAdapter在整理响应时对值进行四舍五入。一切正常 我现在的问题是,我想让它变得灵活。Ie:在某些情况下,我需要四舍五入到小数点后2位,大约4位,等等。。现在,我必须创建一个TwoDecimalAdapter和一个FourDecimalAdapter,并在模型定义中
@javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter(value=FourDecimalRoundingAdapter.class,type=java.math.BigDecimal.class)
我希望能够做到以下几点:
@javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter(value=new RoundingAdapter(4),type=java.math.BigDecimal.class)
显然,当JAXB实例化适配器本身时,这不起作用,但是有什么技术可以用来将参数传递给适配器吗?我希望能够在Spring中声明舍入适配器,并以这种方式使用它,但同样,我无法设计出一个可重用的解决方案
谢谢
Eric我不确定如何使用Spring实现这一点,但下面是对可以利用的JAXB机制的描述 如果您有以下情况:
@javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter(value=RoundingAdapter.class,type=java.math.BigDecimal.class)
然后使用独立的JAXB API,您可以执行以下操作。下面的代码表示每当遇到RoundingAdapter
时,都应使用指定的实例
marshaller.setAdapter(new RoundingAdapter(4));
unmarshaller.setAdapter(new RoundingAdapter(4));
了解更多信息
import com.company.BigDecimalAdapter.X$XXXX;
...
@XmlElement(name = "QTY")
@XmlJavaTypeAdapter(X$XXXX.class)
private BigDecimal quantity;
大十进制自适应
import static java.math.RoundingMode.HALF_UP;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class BigDecimalAdapter extends XmlAdapter<String, BigDecimal> {
public static final class X$XX extends BigDecimalAdapter {
public X$XX() {
super("#.##");
}
}
public static final class X$00 extends BigDecimalAdapter {
public X$00() {
super("#.00");
}
}
public static final class X$XXXX extends BigDecimalAdapter {
public X$XXXX() {
super("#.####");
}
}
private final ThreadLocal<DecimalFormat> format;
public BigDecimalAdapter(String pattern) {
format = ThreadLocal.withInitial(() -> {
DecimalFormat df = new DecimalFormat(pattern);
df.setRoundingMode(HALF_UP);
return df;
});
}
@Override
public String marshal(BigDecimal v) throws Exception {
return format.get().format(v);
}
@Override
public BigDecimal unmarshal(String v) throws Exception {
return new BigDecimal(v);
}
}
导入静态java.math.RoundingMode.HALF\u UP;
导入java.math.BigDecimal;
导入java.text.DecimalFormat;
导入javax.xml.bind.annotation.adapters.XmlAdapter;
公共类BigDecimalAdapter扩展了XmlAdapter{
公共静态最终类X$XX扩展了BigDecimalAdapter{
公共X$XX(){
超级(“#.###”);
}
}
公共静态最终类X$00扩展BigDecimalAdapter{
公共X$00(){
超级(“0.00”);
}
}
公共静态最终类X$XXXX扩展BigDecimalAdapter{
公共X$XXXX(){
超级(“#.#####””;
}
}
私有本地格式;
公共BigDecimalAdapter(字符串模式){
格式=ThreadLocal.withInitial(()->{
DecimalFormat df=新的DecimalFormat(模式);
df.设置舍入模式(半向上);
返回df;
});
}
@凌驾
公共字符串封送处理程序(BigDecimal v)引发异常{
返回format.get().format(v);
}
@凌驾
公共BigDecimal解组器(字符串v)引发异常{
返回新的BigDecimal(v);
}
}
在我自己控制编组/解编组的上下文中,这似乎相当简单。但是在JAX-WS的环境中,它神奇地为我完成了所有的工作,而不必亲自处理,我如何向它表明我想要使用新的RoundingAdapter(4)?我从未用JAX-WS实例化过任何封送器/解封器……我仍然不明白您是如何做到这一点的。我还希望执行类似的操作,需要将类参数传递给XMLAdapter
,并访问其Getter方法: