使用jaxb 實現物件與xml之間的轉換,並且是 soap報文與物件轉換
阿新 • • 發佈:2018-12-04
使用jaxb 實現物件與xml之間的轉換,並且是 soap報文與物件轉換
1.測試用例
public class TestJaxb { @Test public void testToObject(){ JaxbBinder jaxbBinder = new JaxbBinder(SoapEnvelope.class); URL url = this.getClass().getClassLoader().getResource("receB2COrderResponse.xml"); String xml = null; try { xml = FileUtils.readFileToString(new File(url.getPath())) ; } catch (IOException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } SoapEnvelope envelope =jaxbBinder.fromXml(xml); Assert.notNull(envelope,"envelope資料為空"); Assert.notNull(envelope.getBody(),"body資料為空"); Assert.notNull(envelope.getBody().getReceB2COrderResponseList(),"body.list資料為空"); Assert.notNull(envelope.getBody().getReceB2COrderResponseList().get(0),"body.list[0]資料為空"); Assert.notNull(envelope.getBody().getReceB2COrderResponseList().get(0).getOrderNo(),"body.list[0]資料為空"); System.out.println("getOrderNo="+envelope.getBody().getReceB2COrderResponseList().get(0).getOrderNo()); System.out.println("\ndata="+ (envelope).toString()); } @Test public void testToXml(){ ReceB2COrderRequest re = new ReceB2COrderRequest(); re.setBuyerContact("test111123123"); re.setBuyerId("asdfsadfasdf"); re.setBuyerName("aaaaaaaaaaa"); SoapBody body = new SoapBody(); body.setReceB2COrderRequestList(Arrays.asList(re)); SoapEnvelope envelope = new SoapEnvelope(null,body); JaxbBinder jaxbBinder = new JaxbBinder(SoapEnvelope.class); String xml =jaxbBinder.toXml(envelope,"utf-8"); System.out.println("\nxml="+ xml); }
2.轉換工具
import javax.xml.bind.*; import javax.xml.namespace.QName; import java.io.File; import java.io.InputStream; import java.io.StringReader; import java.io.StringWriter; import java.util.Collection; /** * 使用Jaxb2.0實現XML<->Java Object的Binder. * 特別支援Root物件是List的情形. */ public class JaxbBinder { //多執行緒安全的Context. private JAXBContext jaxbContext; /** * @param types 所有需要序列化的Root物件的型別. */ public JaxbBinder(Class<?>... types) { try { jaxbContext = JAXBContext.newInstance(types); } catch (JAXBException e) { throw new RuntimeException(e); } } /** * Java Object->Xml. */ public String toXml(Object root, String encoding) { try { StringWriter writer = new StringWriter(); createMarshaller(encoding).marshal(root, writer); return writer.toString(); } catch (JAXBException e) { throw new RuntimeException(e); } } /** * Java Object->Xml, 特別支援對Root Element是Collection的情形. */ @SuppressWarnings("unchecked") public String toXml(Collection root, String rootName, String encoding) { try { CollectionWrapper wrapper = new CollectionWrapper(); wrapper.collection = root; JAXBElement<CollectionWrapper> wrapperElement = new JAXBElement<CollectionWrapper>(new QName(rootName), CollectionWrapper.class, wrapper); StringWriter writer = new StringWriter(); createMarshaller(encoding).marshal(wrapperElement, writer); return writer.toString(); } catch (JAXBException e) { throw new RuntimeException(e); } } /** * Xml->Java Object. */ @SuppressWarnings("unchecked") public <T> T fromXml(String xml) { try { StringReader reader = new StringReader(xml); return (T) createUnmarshaller().unmarshal(reader); } catch (JAXBException e) { throw new RuntimeException(e); } } /** * 建立Marshaller, 設定encoding(可為Null). */ public Marshaller createMarshaller(String encoding) { try { Marshaller marshaller = jaxbContext.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); if (StringUtils.isNotBlank(encoding)) { marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding); } return marshaller; } catch (JAXBException e) { throw new RuntimeException(e); } } /** * 建立UnMarshaller. */ public Unmarshaller createUnmarshaller() { try { return jaxbContext.createUnmarshaller(); } catch (JAXBException e) { throw new RuntimeException(e); } } /** * 封裝Root Element 是 Collection的情況. */ public static class CollectionWrapper { @SuppressWarnings("unchecked") @XmlAnyElement protected Collection collection; } @SuppressWarnings("unchecked") public <T> T fromXML(String fileName) { return (T)fromXML(new File(fileName)); } @SuppressWarnings("unchecked") public <T> T fromXML(File file) { try { Unmarshaller unmarshaller = createUnmarshaller(); return (T) unmarshaller.unmarshal(file); } catch (JAXBException e) { throw new RuntimeException(e); } } @SuppressWarnings("unchecked") public <T> T fromXML(InputStream stream) { try { Unmarshaller unmarshaller = createUnmarshaller(); return (T) unmarshaller.unmarshal(stream); } catch (JAXBException e) { throw new RuntimeException(e); } }
3.XML報文例項(receB2COrderResponse.xml)
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <ns1:receiveB2COrderResponse xmlns:ns1="http://www.sdo.com/mas/api/receive/"> <return> <customerName>愛奇藝</customerName> <customerNo>332396</customerNo> <orderAmount>30.00</orderAmount> <orderNo>2014081809451210442</orderNo> <orderType>OT001</orderType> <returnInfo/> <sessionId>72041119-5d40-42dc-afec-980cbf0122a4</sessionId> <signature/> <tokenId>4A8A8F14C3BED9151F51C0096319A664AAFD91E5B2982EAB21DDE8C557FC5A52B887E8CBF9AE3B19</tokenId> <transNo>C20140818094536462081</transNo> <transStatus>00</transStatus> <transTime>20140818094518</transTime> </return> </ns1:receiveB2COrderResponse> </soap:Body> </soap:Envelope>
4.testToXml()輸出的報文內容:
<?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:rec="http://www.sdo.com/mas/api/receive/"> <soapenv:Header> </soapenv:Header> <soapenv:Body> <rec:receiveB2COrder> <arg0> <buyerContact></buyerContact> <buyerId></buyerId> <buyerIp></buyerIp> <buyerName></buyerName> <cardPayInfo></cardPayInfo> <cardValue></cardValue> <currency>CNY</currency> <depositId></depositId> <depositIdType></depositIdType> <expireTime></expireTime> <instCode></instCode> <language>zh-CN</language> <notifyUrl>sntCode=sdocard</notifyUrl> <orderAmount>1.00</orderAmount> <orderNo>2014081319114151822</orderNo> <orderTime>20140813191141</orderTime> <pageUrl>fdction?paymentCode=sdocard</pageUrl> <payChannel></payChannel> <payType></payType> <payeeId></payeeId> <payerAuthTicket></payerAuthTicket> <payerId></payerId> <payerMobileNo></payerMobileNo> <productDesc></productDesc> <productId></productId> <productName></productName> <productNum></productNum> <productUrl></productUrl> <sellerId></sellerId> <terminalType></terminalType> <unitPrice></unitPrice> </arg0> </rec:receiveB2COrder> </soapenv:Body> </soapenv:Envelope>
5.java的物件(省略了getter/setter)
@XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(name = "Envelope", namespace = NAMESPACE_OF_ENVELOPE) public class SoapEnvelope { /** * soap 中 envelope namespace */ public static final String NAMESPACE_OF_ENVELOPE = "http://schemas.xmlsoap.org/soap/envelope/"; /** * soap 中 receiveB2COrderResponse namespace */ public static final String NAMESPACE_OF_RECEIVEB2CORDER = "http://www.sdo.com/mas/api/receive/"; @XmlElement(name = "Header", namespace = NAMESPACE_OF_ENVELOPE) private SoapHeader header; @XmlElement(name = "Body", namespace = NAMESPACE_OF_ENVELOPE ) private SoapBody body; } @XmlAccessorType(XmlAccessType.FIELD) public class SoapBody { /** * soap 中 envelope namespace */ public static final String NAMESPACE_OF_ENVELOPE = "http://schemas.xmlsoap.org/soap/envelope/"; /** * soap 中 receiveB2COrderResponse namespace */ public static final String NAMESPACE_OF_RECEIVEB2CORDER = "http://www.sdo.com/mas/api/receive/"; @XmlElement(name = "Fault", namespace = NAMESPACE_OF_ENVELOPE) private Fault fault; @XmlElementWrapper(name = "receiveB2COrder", namespace = NAMESPACE_OF_RECEIVEB2CORDER) @XmlElement(name = "arg0") private List<ReceB2COrderRequest> receB2COrderRequestList; @XmlElementWrapper(name = "receiveB2COrderResponse", namespace = NAMESPACE_OF_RECEIVEB2CORDER) @XmlElement(name = "return") private List<ReceB2COrderResponse> receB2COrderResponseList; } @XmlAccessorType(XmlAccessType.FIELD) public class ReceB2COrderRequest { private String orderNo; private String orderAmount; private String orderTime; private String expireTime; private String currency; private String payType; private String payChannel; private String instCode; private String cardValue; private String language; private String pageUrl; private String notifyUrl; } @XmlAccessorType(XmlAccessType.FIELD) public class ReceB2COrderResponse{ private String orderNo; private String transNo; private String customerName; private String customerNo; private String customerLogoUrl; private String orderType; private String orderAmount; private String transStatus; private String transTime; private String tokenId; private String sessionId; } @XmlAccessorType(XmlAccessType.FIELD) public static class SoapHeader { }