我有一个定义为xsd:double的元素。如果我尝试将一个值285放入元素然后我编组它我得到285.0的输出......那很好。但是,如果我输入一个值285292746,我得到2.85292746E8的输出我是元帅。 我喜欢这样的东西,以便双输出不会转换为带小数的科学记数法?基本上我想要285292746或2852292746.0000000
java.lang.Double.toString()对于为xml生成isues的某些值使用“computerized science notation”。
我知道给定值的双重表示很好。但是值是指数格式的事实,我正在研究的系统是接受我的XML但不知道如何处理指数值并导致我的程序无法正常工作。在WSDL或服务器中更改xsd:double类型对我来说是不可行的。我在客户端工作。
我遇到了Jaxb:绑定xsd:double类型。我仍然很难解决问题,以非扩展格式发送值double值。
package com.logger.client
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.bind.DatatypeConverter;
public class JaxbDoubleSerializer extends XmlAdapter<String, Double>
{
public Double unmarshal(String value) {
return ((double)javax.xml.bind.DatatypeConverter.parseDouble(value));
}
public String marshal(Double value) {
if (value == null) {
return null;
}
return (javax.xml.bind.DatatypeConverter.printDouble((double)(double)value));
}
}
我需要帮助如何使用DoubleSerializer,以便我可以传递没有指数的值。我尝试在我的类MyLogClient.java中使用xmlAdapter Annotation。我需要知道如何解决这种情况。
package com.logger.client
import javax.xml.ws.BindingProvider;
import javax.xml.bind.JAXBElement;import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlValue;
public class MyLogClient
{
//Private member fields
/** Object factory used to create user-and-role specific objects. */
private static final ObjectFactory _of = new ObjectFactory();
@XmlJavaTypeAdapter(JaxbDoubleSerializer.class)
public JAXBElement<Double> msgFileId;
@XmlJavaTypeAdapter(JaxbDoubleSerializer.class)
public Double dNumber;
public final void createEntry;
(
final String userName,
final String time,
final String logMsgStringId,
final Params logMsgParamsVal,
final Integer logMessageFieldID
)
throws JAXBException
{
JAXBElement<String> username = _of.createParamsParam(userName);
JAXBElement<String> strTime = _of.createLogRequestTime(time);
// Build the LogRequest request.
final LogRequest _LogRequest = _of.createLogRequest();
_LogRequest.setUserName(userName);
_LogRequest.setTime(strTime);
//Following is the main problem
int nMsgArgs = 285292746;
dNumber = Double.parseDouble(Integer.toString(nMsgArgs));
//After parsing double Value I get dNumber is now 2.85292746E8
//MsgFile Id is of Type JAXBElement<Double>
//CreateLogMessageIdentifier takes Double param
//So the main problem is here..the value of double field in soap request
//is being sent in exponential format. I need to send as I explained above
//285292746.
msgFileId = _of.createLogMessageIdentifier(dNumber);
JAXBElement<String> strIdVal = _of.createLogMessageFileId(logMsgStringId);
final LogMessage logMessage = _of.createLogMessage();
JAXBElement<Params> _logMsgParams =_of.createLogMessageParams(logMsgParamsVal);
//Following is where I am trying to use marshall for double type.
JAXBContext context = JAXBContext.newInstance("package com.logger.client ");
context.createMarshaller().marshal(msgFileId, System.out);
logMessage.setIdentifier(msgFileId); //Method takes JAXBElement<Double>
logMessage.setFileId(strIdVal );
logMessage.setParams(_logMsgParams);
JAXBElement<LogMessage> logMsgValue = _of.createLogRequestLogMessage(logMessage);
_LogRequest.setLogMessage(logMsgValue);
// Set the log entry
port.log(_LogRequest); //Request is sent to server.
}
WSDL xsd:类型声明如下: -
<xsd:complexType name="LogMessage">
<xsd:sequence>
<xsd:element name="fileId" type="xsd:string" minOccurs="0" nillable="true" />
<xsd:element name="identifier" type="xsd:double" minOccurs="0" nillable="true" />
<xsd:element name="params" type="tns:Params" minOccurs="0" nillable="true" />
</xsd:sequence>
</xsd:complexType>
标识符字段的输出为: -
<identifier> 2.85292746E8</indentifier>
Whereas I want to send as. Because system does accept/recognize following types.
<identifier> 285292746</indentifier>
or
<identifier> 285292746.00000000</indentifier>
答案 0 :(得分:8)
您可以使用如下所示的外部绑定文件:
<强> binding.xml 强>
<jxb:bindings
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
version="2.1">
<jxb:globalBindings>
<jxb:javaType name="java.lang.Double"
xmlType="xs:double"
parseMethod="javax.xml.bind.DatatypeConverter.parseDouble"
printMethod="javax.xml.bind.DatatypeConverter.printDouble" />
</jxb:globalBindings>
</jxb:bindings>
<强> root.xsd 强>
<?xml version="1.0"?>
<xs:schema
elementFormDefault="qualified"
targetNamespace="http://www.example.com"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="root">
<xs:sequence>
<xs:element name="foo" type="xs:double" />
<xs:element name="bar" type="xs:double" />
</xs:sequence>
</xs:complexType>
</xs:schema>
XJC致电
xjc -d out -b binding.xml root.xsd
<强>根强>
为根类型生成的类将在Double属性上注册XmlAdapter
个类:
package com.example;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.w3._2001.xmlschema.Adapter1;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "root", propOrder = {
"foo",
"bar"
})
public class Root {
@XmlElement(required = true, type = String.class)
@XmlJavaTypeAdapter(Adapter1 .class)
@XmlSchemaType(name = "double")
protected Double foo;
@XmlElement(required = true, type = String.class)
@XmlJavaTypeAdapter(Adapter1 .class)
@XmlSchemaType(name = "double")
protected Double bar;
public Double getFoo() {
return foo;
}
public void setFoo(Double value) {
this.foo = value;
}
public Double getBar() {
return bar;
}
public void setBar(Double value) {
this.bar = value;
}
}
<强>适配器1 强>
XmlAdapter
使用您在binding.xml文件中配置的方法。
package org.w3._2001.xmlschema;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class Adapter1 extends XmlAdapter<String, Double> {
public Double unmarshal(String value) {
return (javax.xml.bind.DatatypeConverter.parseDouble(value));
}
public String marshal(Double value) {
if (value == null) {
return null;
}
return (javax.xml.bind.DatatypeConverter.printDouble(value));
}
}
答案 1 :(得分:1)
最好的方法可能是在JAXB编译器中使用自定义绑定(javaType子句)。可以找到文档here。根据你是否必须编组和解组双打,解决方案可能就像覆盖全局级别的BigDecimal之类的映射一样简单(虽然理解虽然双精度和小数是完全不同的东西,但你似乎想要一个小数表示),或使用数据类型转换器(上面的链接为您提供了所有这些选项的示例)。