1. 程式人生 > >jaxb xml to Bean 生成物件為值null

jaxb xml to Bean 生成物件為值null

jaxb to Bean 生成物件為值null

事情處理結果

直接將名稱空間給replace掉

xml.replace("xmlns=\"http://www.aaa.bb.ccc\"", "")

起因

因為系統對接需要,現在需要將一段xml解析出來,雖然可以使用dom方式去解析,但是總感覺很麻煩,想通過jaxb的這種方式,直接將xml對映到JavaBean上,通過get和set去取對應的值,感覺這樣比較順手,所以直接開幹

同事不知道從哪借鑑(抄)過來一個工具類,程式碼如下

package net.wdm.tools.xml;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author 
[email protected]
* @since 2013-7-26 下午4:41:53 */ public class XmlConvert { private static final Logger log = LoggerFactory.getLogger(XmlConvert.class); public static XmlConvert instance = new XmlConvert(); private static final Map<Class<?>, Marshaller> JAXB_MARSHALL_MAP = Collections .synchronizedMap(new HashMap<Class<?>, Marshaller>()); private static final Map<Class<?>, Unmarshaller> JAXB_UNMARSHALL_MAP = Collections .synchronizedMap(new HashMap<Class<?>, Unmarshaller>()); /** * @param xml * @param clazz * @return */ @SuppressWarnings("unchecked") public <X> X toBean(String xml, Class<X> clazz) { try { JAXBContext context = JAXBContext.newInstance(clazz); Unmarshaller unmarshaller = context.createUnmarshaller(); StringReader sw = new StringReader(xml); return (X) unmarshaller.unmarshal(sw); } catch (Exception e) { log.warn("異常物件:" + xml); log.error(e.getMessage(), e); JAXB_UNMARSHALL_MAP.put(clazz, null); } return null; } @SuppressWarnings("unchecked") public <X> X toBean(InputStream xmlStream, Class<X> clazz) { try { Unmarshaller msl = JAXB_UNMARSHALL_MAP.get(clazz); if (msl == null) { JAXBContext context = JAXBContext.newInstance(clazz); msl = context.createUnmarshaller(); JAXB_UNMARSHALL_MAP.put(clazz, msl); } synchronized (msl) { return (X) msl.unmarshal(xmlStream); } } catch (Exception e) { log.error(e.getMessage(), e); // 解決出現異常後,該資訊一直出現的問題 JAXB_UNMARSHALL_MAP.put(clazz, null); } return null; } /** * @param bean * @return */ public String toXML(Object bean) { if (bean == null) { log.error("傳入物件為空!請檢查程式。"); return null; } try { Marshaller msl = JAXB_MARSHALL_MAP.get(bean.getClass()); if (msl == null) { JAXBContext context = JAXBContext.newInstance(bean.getClass()); msl = context.createMarshaller(); msl.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); JAXB_MARSHALL_MAP.put(bean.getClass(), msl); } StringWriter sw = new StringWriter(); synchronized (msl) { msl.marshal(bean, sw); } return sw.toString(); } catch (Exception e) { log.error(e.getMessage(), e); // 解決出現異常後,該資訊一直出現的問題 JAXB_MARSHALL_MAP.put(bean.getClass(), null); } return null; } /** * @param bean * @return */ public void toXML(Object bean, OutputStream out) { try { Marshaller msl = JAXB_MARSHALL_MAP.get(bean.getClass()); if (msl == null) { JAXBContext context = JAXBContext.newInstance(bean.getClass()); msl = context.createMarshaller(); // 是否格式化生成的字串 msl.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); JAXB_MARSHALL_MAP.put(bean.getClass(), msl); } synchronized (msl) { msl.marshal(bean, out); } } catch (JAXBException e) { log.error(e.getMessage(), e); // 解決出現異常後,該資訊一直出現的問題 JAXB_MARSHALL_MAP.put(bean.getClass(), null); } } }

因為有public <X> X toBean(InputStream xmlStream, Class<X> clazz)這個方法,感覺toBean是個很容易的事情,事實上並沒有這麼簡單

經過

首先,我有兩個類

package com.wdm.pang.entity.xintong.IOrder;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "CEB312Message", namespace = "http://www.aaa.bb.ccc")
public class CEB312Message {

	@XmlElement(name = "OrderReturn")
	private OrderReturn orderReturn;

	public OrderReturn getOrderReturn() {
		return this.orderReturn;
	}

	public void setOrderReturn(OrderReturn orderReturn) {
		this.orderReturn = orderReturn;
	}

	@Override
	public String toString() {
		return "CEB312Message [orderReturn=" + orderReturn + "]";
	}

}
package com.wdm.pang.entity.xintong.IOrder;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "OrderReturn")
public class OrderReturn {

	@XmlElement(name = "guid")
	private String guid;

	@XmlElement(name = "ebpCode")
	private String ebpCode;

	@XmlElement(name = "ebcCode")
	private String ebcCode;

	@XmlElement(name = "orderNo")
	private String orderNo;

	@XmlElement(name = "returnStatus")
	private Integer returnStatus;

	@XmlElement(name = "returnTime")
	private String returnTime;

	@XmlElement(name = "returnInfo")
	private String returnInfo;

	public String getGuid() {
		return this.guid;
	}

	public void setGuid(String guid) {
		this.guid = guid;
	}

	public String getEbpCode() {
		return this.ebpCode;
	}

	public void setEbpCode(String ebpCode) {
		this.ebpCode = ebpCode;
	}

	public String getEbcCode() {
		return this.ebcCode;
	}

	public void setEbcCode(String ebcCode) {
		this.ebcCode = ebcCode;
	}

	public String getOrderNo() {
		return this.orderNo;
	}

	public void setOrderNo(String orderNo) {
		this.orderNo = orderNo;
	}

	public Integer getReturnStatus() {
		return returnStatus;
	}

	public void setReturnStatus(Integer returnStatus) {
		this.returnStatus = returnStatus;
	}

	public String getReturnTime() {
		return this.returnTime;
	}

	public void setReturnTime(String returnTime) {
		this.returnTime = returnTime;
	}

	public String getReturnInfo() {
		return this.returnInfo;
	}

	public void setReturnInfo(String returnInfo) {
		this.returnInfo = returnInfo;
	}

	@Override
	public String toString() {
		return "OrderReturn [guid=" + guid + ", ebpCode=" + ebpCode + ", ebcCode=" + ebcCode + ", orderNo=" + orderNo
				+ ", returnStatus=" + returnStatus + ", returnTime=" + returnTime + ", returnInfo=" + returnInfo + "]";
	}

}

然後我有一個字串:

<?xml version="1.0" encoding="UTF-8" xmlns="http://www.aaa.bb.ccc" ? >
<OrderReturn>
    <guid>83B32909-6855-46BD-ACED-B153BC252446</guid>
    <ebpCode>1</ebpCode>
    <ebcCode>1</ebcCode>
    <orderNo>1</orderNo>
    <returnStatus>5</returnStatus>
    <returnTime>20180926165332552</returnTime>
    <returnInfo>預處理成功</returnInfo>
</OrderReturn>

按照我正常的思路,只需要這樣CEB312Message message = XmlConvert.instance.toBean(xml, CEB312Message.class);message物件裡面就會有值,然而並不是,System.out.println(message );的結果只是CEB312Message [orderReturn=null],那麼問題就來了,究竟是什麼原因導致的呢?

抱著疑問,我把原來的類上的註解@XmlRootElement(name = "CEB312Message", namespace = "http://www.aaa.bb.ccc")中的名稱空間刪除,直接改為@XmlRootElement(name = "CEB312Message"),然後就可以了麼?不,事情並沒有那麼簡單,報錯了。。。

javax.xml.bind.UnmarshalException: 意外的元素 (uri:"http://www.aaa.bb.ccc", local:"CEB312Message")。所需元素為<{}CEB312Message>,<{}OrderReturn>
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:726)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:247)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:242)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:109)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement(UnmarshallingContext.java:1131)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:556)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:538)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:153)
	at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:509)
	at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:374)
	at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl$NSContentDriver.scanRootElementHook(XMLNSDocumentScannerImpl.java:613)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3132)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:852)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:602)
	at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:112)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:505)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:841)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:770)
	at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
	at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
	at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:643)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:243)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:214)
	at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:157)
	at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:214)
	at com.wdm.pang.controller.entity.dto.Test.toBean(Test.java:72)
	at com.wdm.pang.controller.entity.dto.Test.main(Test.java:41)

那怎麼辦呢,改回去吧。

我又在想,難道是我的JavaBean註解沒對?

那我從Bean生成一個xml對比一下看看效果先,於是乎一把梭

		CEB312Message ceb312Message = new CEB312Message();
		CEB312Message stringToObject = XmlConvert.instance.toBean(back, CEB312Message.class);
		System.out.println(stringToObject);
		OrderReturn orderReturn = new OrderReturn();
		orderReturn.setGuid("83B32909-6855-46BD-ACED-B153BC252446");
		orderReturn.setEbcCode("1");
		orderReturn.setEbpCode("1");
		orderReturn.setOrderNo("1");
		orderReturn.setReturnInfo("預處理成功");
		orderReturn.setReturnStatus(5);
		orderReturn.setReturnTime("20180926165332552");
		ceb312Message.setOrderReturn(orderReturn);
		String xml = XmlConvert.instance.toXML(ceb312Message);
		System.out.println(xml);

-----------------------輸出結果-----------------------------
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:CEB312Message xmlns:ns2="http://www.aaa.bb.ccc">
    <OrderReturn>
        <guid>83B32909-6855-46BD-ACED-B153BC252446</guid>
        <ebpCode>1</ebpCode>
        <ebcCode>1</ebcCode>
        <orderNo>1</orderNo>
        <returnStatus>5</returnStatus>
        <returnTime>20180926165332552</returnTime>
        <returnInfo>預處理成功</returnInfo>
    </OrderReturn>
</ns2:CEB312Message>

那麼問題又來了,這個ns2:是個什麼鬼,好像我也沒有什麼地方寫了這個東西啊,真是頭大,一頓瘋狂的百度,然後找到下面的這些資料:

這些資料都寫的很好,非常有效的解決了ns2:這個字首問題,然而我的目的並不是要生成xml,我的初衷是要去解析xml到javaBean
所以,我又回到了正題,既然我是因為namespace的問題導致的解析不正確問題,那我可不可以不要這個namespace,直接刪掉試試,於是就有了如下程式碼:

CEB312Message ceb312Message = XmlConvert.instance.toBean(xml.replace("xmlns=\"http://www.chinaport.gov.cn/ceb\"", ""),CEB312Message.class);

System.out.println(ceb312Message);

----------------------輸出結果---------------------------
CEB312Message [orderReturn=OrderReturn [guid=83B32909-6855-46BD-ACED-B153BC252446, ebpCode=1, ebcCode=1, orderNo=1, returnStatus=5, returnTime=20180926165332552, returnInfo=預處理成功]]

然後居然有值了,emmmm簡直是。

附上Maven引用

<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-core</artifactId>
    <version>2.2.11</version>
</dependency>

<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-impl</artifactId>
    <version>2.3.0.1</version>
</dependency>

雖然這個方法太草率了,先將就用著,畢竟時間緊任務重,如果有大佬做過,並且很好的解決了這個問題,歡迎留言告訴我,3Q

相關推薦

jaxb xml to Bean 生成物件null

jaxb to Bean 生成物件為值null 事情處理結果 直接將名稱空間給replace掉 xml.replace("xmlns=\"http://www.aaa.bb.ccc\"", "") 起因 因為系統對接需要,現在需要將一段xml解析出來,雖然可以

Spring_(3)通過xml配置bean+建立物件

先來看整體專案的結構 HelloWorld.java package com.spring.beans; public class HelloWorld { private String name; public void setName(String na

xstream解析xml字串和生成物件

一 目錄 二 程式碼 1 Person.java package com.jn.xstream.bean; import java.util.ArrayList; import java.util.HashMap; import java.util.List; imp

MyBatis xml檔案動態生成物件,網上找的自己進行了優化。

主要針對動態分頁查詢,因為日常中查詢,可以利用其實現動態分頁操作,實現所有的select都能夠動態生成以此基礎。 {******************************方法應用*********************************************

元件使用總結:使用 JAXB 實現 XML檔案和java物件互轉

JAXB JAXB:實現xml和java物件互轉 JAXB是一個業界的標準,實現XML檔案和Java物件的互轉。 JAXB是JDK 的組成部分。我們不需要下載第三方jar包 即可做到輕鬆轉換。 複製程式碼 重要類和介面: ○ JAXBContext類,是應用的入口,用於管理XML/Java繫結資訊。

過濾物件屬性空的屬性

一般介面允許傳參為空的話,就不需要用 let trans = { a:22, b:'' }; let pam = {} for(let i in trans){ if(trans[i]){

IDEA用Maven外掛生成Mybatis的mapper,xmlbean

一、專案下建好資料夾 二、generatorConfig.xml檔案 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ge

java中將物件null,對垃圾回收有用嗎?

相信,網上很多java效能優化的帖子裡都會有這麼一條:儘量把不使用的物件顯式得置為null.這樣有助於記憶體回收      可以明確的說,這個觀點是基本錯誤的.sun jdk遠比我們想象中的機智.完全能判斷出物件是否已經no ref..但是,我上面用的詞是"

JS隨機生成6數字並賦給input

<html> <head> </head> <script> function code(){         var Num="";         for(var i=0;i<6;i++){             N

java中new出來一個物件和定義一個物件空有什麼不同

new 一個物件出來,比如SomeClass sc=new SomeClass();這個時候已經為sc這個物件分配了指向 new SomeClass() 所建立的記憶體空間。即對這個物件sc進行了例項化。而SomeClass sc=null,則sc物件未進行例項化,是一個空的物件,未能指向任何記憶體空間。

jaxb實現xmlbean的相互轉化

jaxb使用說明   這裡邊有提到MessageFormat,可以瞭解下。下邊還有一個其他部落格粘過來的幾行程式碼,記錄一下。  這裡以《書》為例,寫一個完整的測試程式碼,xml包含了各種元素和集合。  test.xml <?xml version="1.0" enco

JAXB實現JAVA BEANXML之間的轉換

JAXB主要用來實現物件和XML之間的序列化和反序列化,關於JAXB的介紹就不多說了,網上一搜一大把,這裡主要總結下基本使用方法和一些注意事項 首先定義兩個示例類ClassA,ClassB,用於後續的示例演示 public class ClassA { pri

物件null時 記憶體分配情況,以及什麼時候使用效率高

對於成員變數也就是instance member來說是沒區別的,物件初始化的時候會自動賦值成null。但是對於區域性變數也就是local variable來說,不賦值初始化使用編譯會報錯。 對於一般的物件成員來說 分配好空間都會預先分配一個null值。所以寫不寫這個沒什麼特

如何在前臺獲取後臺的物件bean以及其中的

比如後臺一個物件 User ,屬性是 name 和 age 其實只要把這個User放到session中,而且給這個user提供get和set方法,name、age也提供get和set方法,前臺就可以通

jni 自定義物件引數和返回

 android JNI 提供了很強大的支援,不僅可以採用基本型別做為引數和返回值,同時也支援自定義物件做為引數和返回值,以下舉例說明。 一、定義作為輸入和返回的自定義類 (僅提供兩個簡單型別和一個列印函式) package com.example.jniexample;   import andr

XmlBean互轉 jaxb

JAXB:Java Architecture for XML Binding 是一個業界的標準,是一項可以根據XML Schema產生java類的技術.該過程中jaxb也提供了講xml例項文件反向生成java物件方法,並能講java物件書的內容重新寫到xml例項文件中. 從另一方面來講,ja

echarts 無法獲取屬性“getAttribute”的: 物件 null 或未定義 錯誤解決方法

  使用百度的echarts時,在IE9下執行時有時會報如題的錯誤,有時重新整理下又正常,造成這種錯誤的原因是 echarts.js引用放在head中或者放在body中HTML程式碼的前面了,造成載入時阻塞後面的html。 解決方法就是將echarts.js的引用放在<

利用hashtable以類物件鍵儲存

class hello { public static void main(String[] args) throws ParseException { Hashtable<Animal, String> map = new Hashtable<>(); ma

使用JAXB包實現beanxml的互轉

前言 由於專案需要,呼叫第三方介面,介面返回格式為xml格式。遂用上了javax.xml 用於實現Bean和xml互轉 首先我們看看工具類XmlUtil /** * XML轉物件 * * @param xmlStr xml字串

JAXB實現xmlbean之間的轉換

public class JAXBUtils { public static String convertToXml(Object obj, boolean format) throws Exception { try { St