2011-11-04 21 views
7

Tôi có một phần tử được định nghĩa là xsd: double. Nếu tôi thử và đặt một giá trị nói 285 vào phần tử và sau đó tôi sắp xếp nó, tôi nhận được một đầu ra là 285.0 ... Điều đó là tốt. Tuy nhiên, nếu tôi đặt một giá trị nói 285292746, tôi nhận được kết quả là 2.85292746E8 khi Tôi sắp xếp. Tôi thích một cái gì đó để sản lượng tăng gấp đôi không được chuyển đổi thành ký hiệu khoa học với số thập phân? Về cơ bản tôi muốn 285292746 hoặc 2852292746.0000000Jaxb: Chuyển đổi Loại Kết nối Đôi toàn cầu Sử dụng XMLAdapter

java.lang.Double.toString() sử dụng "ký pháp khoa học trên máy vi tính" cho các giá trị nhất định tạo ra các giá trị cho xml.

Tôi biết đại diện kép của giá trị đã cho là tốt. Nhưng thực tế giá trị theo định dạng số mũ, Hệ thống mà tôi đang làm là chấp nhận XML của tôi nhưng không biết phải làm gì với giá trị mũ và làm cho chương trình của tôi không hoạt động chính xác. Thay đổi xsd: loại gấp đôi trong WSDL hoặc máy chủ không khả thi đối với tôi. Tôi đang làm việc ở phía khách hàng.

Tôi gặp Jaxb: ràng buộc cho xsd: double type. Tôi vẫn còn có thời gian khó khăn để khắc phục vấn đề để gửi giá trị gấp đôi giá trị ở định dạng không phải số mũ.

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)); 
    } 

} 

Tôi cần trợ giúp cách sử dụng DoubleSerializer để tôi có thể chuyển các giá trị không có số mũ. Tôi đã thử sử dụng chú thích xmlAdapter trong lớp MyLogClient.java của tôi. Tôi cần phải biết làm thế nào tôi có thể giải quyết tình trạng này.

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: khai báo kiểu là dưới đây: -

<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> 

Output cho lĩnh vực nhận dạng là: -

 <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> 

Trả lời

1

Cách tốt nhất có thể sử dụng một ràng buộc tùy chỉnh (mệnh đề javaType) với trình biên dịch JAXB của bạn. Tài liệu có thể được tìm thấy here. Tùy thuộc vào việc bạn phải so sánh và unmarshall tăng gấp đôi, giải pháp có thể đơn giản như ghi đè ánh xạ tới thứ gì đó như BigDecimal ở mức toàn cầu (với sự hiểu biết rằng mặc dù đôi và số thập phân là những thứ hoàn toàn khác nhau, bạn dường như muốn có một số thập phân đại diện), hoặc sử dụng một bộ chuyển đổi datatype (liên kết ở trên cung cấp cho bạn các ví dụ cho tất cả các tùy chọn này).

+0

Bạn có đưa ra một số ví dụ cụ thể không? Bạn có nghĩ rằng tùy chọn bộ điều hợp xml là tốt. Tôi đã cố gắng sử dụng như được hiển thị ở trên trong ví dụ của tôi JAxDouble Serialzer nhưng không chắc chắn những gì tôi đang mất tích. – user1029083

7

Bạn có thể sử dụng tập tin một ràng buộc bên ngoài như sau:

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> 

gốc.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 Gọi

xjc -d out -b binding.xml root.xsd 

gốc

Lớp tạo cho các loại rễ sẽ có XmlAdapter lớp đăng ký trên các thuộc tính kép:

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; 
    } 

} 

Bộ chuyển đổi1

XmlAdapter sử dụng các phương pháp bạn đã định cấu hình trong tệp 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)); 
    } 

} 
+0

Cảm ơn rất nhiều. Tôi sẽ cố gắng theo cách này. Tôi không có tệp xsd nhưng mã nguồn được tạo từ tệp wsdl mà tệp được xuất bản qua URL. Tôi giả sử tôi sẽ phải sử dụng wsimport hoặc một cái gì đó để làm ràng buộc với wsdl. xjc -d out -b binding.xml (http: //localhost/MyClient.wsdl) hoặc wsimport -d out -b binding.xml location.wsdl. – user1029083

Các vấn đề liên quan