JAXBContext实体类与xml相互转化

1 jaxb基础
    
    JAXB是什么?
        JAXB(即Java Architecturefor XML Binding)是一个业界的标准,
        即是一项可以根据XML Schema产生Java类的技术。
        该过程中,JAXB也提供了将XML实例文档反向生成Java对象树的方法,

        并能将Java对象树的内容重新写到XML实例文档。

两个个JAXB的实体类的例子:
		//例子2
		import java.util.ArrayList;
		import java.util.List;
		import javax.xml.bind.annotation.XmlAccessType;
		import javax.xml.bind.annotation.XmlAccessorType;
		import javax.xml.bind.annotation.XmlAttribute;
		import javax.xml.bind.annotation.XmlElement;
		import javax.xml.bind.annotation.XmlRootElement;
		import javax.xml.bind.annotation.XmlType;

		@XmlAccessorType(XmlAccessType.FIELD)
		@XmlType(name="", propOrder={"log"})
		@XmlRootElement(name="info")
		public class LogReportMsg
		{

		  @XmlElement(required=true)
		  protected List<Log> log;

		  @XmlAttribute
		  protected String id;

		  @XmlAttribute
		  protected String type;

		  public List<Log> getLog()
		  {
		    if (this.log == null) {
		      this.log = new ArrayList();
		    }
		    return this.log;
		  }

		  public String getId()
		  {
		    return this.id;
		  }

		  public void setId(String value)
		  {
		    this.id = value;
		  }

		  public String getType()
		  {
		    if (this.type == null) {
		      return "login_info";
		    }
		    return this.type;
		  }

		  public void setType(String value)
		  {
		    this.type = value;
		  }

		  @XmlAccessorType(XmlAccessType.FIELD)
		  @XmlType(name="")
		  public static class Log
		  {

		    @XmlAttribute
		    protected String account;

		    @XmlAttribute
		    protected String accountType;


		    public String getAccount()
		    {
		      return this.account;
		    }

		    public void setAccount(String value)
		    {
		      this.account = value;
		    }

		    public String getAccountType()
		    {
		      if (this.accountType == null) {
			return "2";
		      }
		      return this.accountType;
		    }

		    public void setAccountType(String value)
		    {
		      this.accountType = value;
		    }
		  }
		}
		
		//模版
		<?xml version="1.0" encoding="UTF-8"?>
		<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
			<xs:element name="info">
				<xs:complexType>
					<xs:sequence maxOccurs="unbounded">
						<xs:element name="log">
							<xs:complexType>
								<xs:attribute name="account" type="xs:string"/>
								<xs:attribute name="accountType" type="xs:string" fixed="2"/>
							</xs:complexType>
						</xs:element>
					</xs:sequence>
					<xs:attribute name="id" type="xs:string"/>
					<xs:attribute name="type" type="xs:string" fixed="cdr_login_info"/>
				</xs:complexType>
			</xs:element>
		</xs:schema>

		//例子2
		import javax.xml.bind.annotation.XmlAccessType;
		import javax.xml.bind.annotation.XmlAccessorType;
		import javax.xml.bind.annotation.XmlAttribute;
		import javax.xml.bind.annotation.XmlElement;
		import javax.xml.bind.annotation.XmlRootElement;
		import javax.xml.bind.annotation.XmlType;


		/**
		 * <p>Java class for anonymous complex type.
		 * 
		 * <p>The following schema fragment specifies the expected content contained within this class.
		 * 
		 * <pre>
		 * <complexType>
		 *   <complexContent>
		 *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
		 *       <sequence>
		 *         <element name="alarmType" type="{http://www.w3.org/2001/XMLSchema}string"/>
		 *         <element name="alarmTime" type="{http://www.w3.org/2001/XMLSchema}string"/>
		 *         <element name="alarmDesc" type="{http://www.w3.org/2001/XMLSchema}string"/>
		 *       </sequence>
		 *       <attribute name="id" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
		 *       <attribute name="type" use="required" type="{http://www.w3.org/2001/XMLSchema}string" fixed="alarm_event" />
		 *     </restriction>
		 *   </complexContent>
		 * </complexType>
		 * </pre>
		 * 
		 * 
		 */
		@XmlAccessorType(XmlAccessType.FIELD)
		@XmlType(name = "", propOrder = {
		    "alarmType",
		    "alarmTime",
		    "alarmDesc"
		})
		@XmlRootElement(name = "info")
		public class AlarmReqMsg {

		    @XmlElement(required = true)
		    protected String alarmType;
		    @XmlElement(required = true)
		    protected String alarmTime;
		    @XmlElement(required = true)
		    protected String alarmDesc;
		    @XmlAttribute(required = true)
		    protected String id;
		    @XmlAttribute(required = true)
		    protected String type;

		   //自动生成的 set/get 方法
		}
		
		//模版
		<?xml version="1.0" encoding="UTF-8"?>
		<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
			<xs:element name="info">
				<xs:complexType>
					<xs:sequence>
						<xs:element name="alarmType" type="xs:string"/>
						<xs:element name="alarmTime" type="xs:string"/>
						<xs:element name="alarmDesc" type="xs:string"/>
					</xs:sequence>
					<xs:attribute name="id" type="xs:string" use="required"/>
					<xs:attribute name="type" type="xs:string" use="required" fixed="alarm_event"/>
				</xs:complexType>
			</xs:element>
		</xs:schema>

    注解介绍
        1)        @XmlType
        2)        @XmlElement
        3)        @XmlRootElement
        4)        @XmlAttribute
        5)        @XmlAccessorType
        6)        @XmlAccessorOrder (不常用)
        7)        @XmlTransient (不常用)
        8)        @XmlJavaTypeAdapter (不常用)

        1)        @XmlType
                @XmlType用在class类的注解,常与@XmlRootElement,@XmlAccessorType一起使用。
                它有三个属性:name、propOrder、namespace,经常使用的只有前两个属性。如:

                @XmlType(name = "basicStruct", propOrder = {
                    "intValue",
                    "stringArray",
                    "stringValue"
                )

                在使用@XmlType的propOrder 属性时,必须列出JavaBean对象中的所有属性,否则会报错。
                在上面的例子中,不用列出也没事

        2)        @XmlElement
                @XmlElement将java对象的属性映射为xml的节点,在使用@XmlElement时,可通过name属性改变java对象属性在xml中显示的名称。如:

                @XmlElement(name="Address")  
                private String yourAddress;


        3)        @XmlRootElement
                @XmlRootElement用于类级别的注解,对应xml的跟元素,常与 @XmlType 和 @XmlAccessorType一起使用。如:

                @XmlType
                @XmlAccessorType(XmlAccessType.FIELD)
                @XmlRootElement
                public class Address {}

        4)        @XmlAttribute
                @XmlAttribute用于把java对象的属性映射为xml的属性,并可通过name属性为生成的xml属性指定别名。如:
                @XmlAttribute(name="Country")
                private String state;

        5)        @XmlAccessorType
                @XmlAccessorType用于指定由java对象生成xml文件时对java对象属性的访问方式。
                常与@XmlRootElement、@XmlType一起使用。它的属性值是XmlAccessType的4个枚举值,分   
                别为:
                XmlAccessType.FIELD:java对象中的所有成员变量
                XmlAccessType.PROPERTY:java对象中所有通过getter/setter方式访问的成员变量
                XmlAccessType.PUBLIC_MEMBER:java对象中所有的public访问权限的成员变量和通过getter/setter方式访问的成员变量
                XmlAccessType.NONE:java对象的所有属性都不映射为xml的元素

                注意:@XmlAccessorType的默认访问级别是XmlAccessType.PUBLIC_MEMBER,
                因此,如果java对象中的private成员变量设置了public权限的getter/setter方法,就不要在   
                private变量上使用@XmlElement和@XmlAttribute注解,否则在由java对象生成xml时会报同一个属性在java类里存在两次的错误。
                
                同理,如果@XmlAccessorType的访问权限为XmlAccessType.NONE,
                如果在java的成员变量上使用了@XmlElement或@XmlAttribute注解,
                这些成员变量依然可以映射到xml文件。

        6)        @XmlAccessorOrder
                @XmlAccessorOrder用于对java对象生成的xml元素进行排序。它有两个属性值:
                  AccessorOrder.ALPHABETICAL:对生成的xml元素按字母书序排序
                  XmlAccessOrder.UNDEFINED:不排序

        7)        @XmlTransient
                @XmlTransient用于标示在由java对象映射xml时,忽略此属性。即,在生成的xml文件中不出现此元素。

        8)        @XmlJavaTypeAdapter
                @XmlJavaTypeAdapter常用在转换比较复杂的对象时,如map类型或者格式化日期等。使用此注解时,需要自己写一个adapter类继承XmlAdapter抽象类,并实现里面的方法。

                @XmlJavaTypeAdapter(value=xxx.class),value为自己定义的adapter类

                XmlAdapter如下:

                public abstract class XmlAdapter<ValueType,BoundType> {
                    // Do-nothing constructor for the derived classes.
                    protected XmlAdapter() {}
                    // Convert a value type to a bound type.
                    public abstract BoundType unmarshal(ValueType v);
                    // Convert a bound type to a value type.
                    public abstract ValueType marshal(BoundType v);
                 }



2 使用举例

例子1:
		package test;

		public class Classroom {
			
			private int id;
			private String name;
			private int grade;
			
			public Classroom() {
				super();
			}

			public Classroom(int id, String name, int grade) {
				super();
				this.id = id;
				this.name = name;
				this.grade = grade;
			}

			public int getId() {
				return id;
			}

			public void setId(int id) {
				this.id = id;
			}

			public String getName() {
				return name;
			}

			public void setName(String name) {
				this.name = name;
			}

			public int getGrade() {
				return grade;
			}

			public void setGrade(int grade) {
				this.grade = grade;
			}

		}

		package test;

		import javax.xml.bind.annotation.XmlRootElement;

		@XmlRootElement
		public class Student {
			
			private int id;
			private String name;
			private int age;
			private Classroom classroom;

			public Student() {
				super();
			}
			
			public Student(int id, String name, int age, Classroom classroom) {
				super();
				this.id = id;
				this.name = name;
				this.age = age;
				this.classroom = classroom;
			}

			public int getId() {
				return id;
			}
			public void setId(int id) {
				this.id = id;
			}
			public String getName() {
				return name;
			}
			public void setName(String name) {
				this.name = name;
			}
			public int getAge() {
				return age;
			}
			public void setAge(int age) {
				this.age = age;
			}
			public Classroom getClassroom() {
				return classroom;
			}
			public void setClassroom(Classroom classroom) {
				this.classroom = classroom;
			}
			
		}

		package test;

		import java.io.StringReader;

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

		public class Test {

			public static void beanToXML(){
				Classroom classroom = new Classroom(1, "软件工程", 4);
				Student student = new Student(101,"张三", 22, classroom);
				
				try {
					JAXBContext context = JAXBContext.newInstance(Student.class);
					Marshaller marshaller = context.createMarshaller();
					marshaller.marshal(student, System.out);
				
				} catch (JAXBException e) {
					e.printStackTrace();
				}
			}
			
			public static void XMLStringToBean(){
				
				//
				String xmlStr = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" +
						"<student><age>22</age>" +
						"<classroom><grade>4</grade><id>1</id><name>软件工程</name></classroom>" +
						"<id>101</id><name>张三</name></student>";  
				
				
				try {
					JAXBContext context = JAXBContext.newInstance(Student.class);
					Unmarshaller unmarshaller = context.createUnmarshaller();
					Student student = (Student)unmarshaller.unmarshal(new StringReader(xmlStr));
					
					System.out.println(student.getAge());
					System.out.println(student.getClassroom().getName());
					
				} catch (JAXBException e) {
					e.printStackTrace();
				}
				
			}
			
			public static void main(String[] args) {
				beanToXML();
		//		XMLStringToBean();
			}
		}

	
		结果:
			生成文件为
			<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

			<student>
				<age>22</age>
				<classroom>
					<grade>4</grade>
					<id>1</id>
					<name>软件工程</name>
				</classroom>
				<id>101</id>
				<name>张三</name>
			</student>


		
	例子2

		import java.io.BufferedReader;
		import java.io.IOException;
		import java.io.InputStream;
		import java.io.InputStreamReader;
		import java.io.StringReader;
		import java.io.StringWriter;
		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;

		public class MessageHelper {
			
			final private Logger LOGGER = LoggerFactory.getLogger(getClass());
			
			private Map<Class<? extends Object>, JAXBContext> contextMap = new HashMap<Class<? extends Object>, JAXBContext>();
			
			private static MessageHelper instance;
			
			private MessageHelper(){
				InputStream in =getClass().getClassLoader().getResourceAsStream("msgClasses"); //将需要处理的类放在这里,带包名
				BufferedReader reader = new BufferedReader(new InputStreamReader(in));
				String line ="";
				while(true){
					try {
						line = reader.readLine();
					} catch (IOException e) {
						LOGGER.error("read msgClasses error",e);
					}
					if(line == null){
						break;
					}else{
						String className = line.trim();
						Class<? extends Object> clazz;
						try {
							clazz = Class.forName(className);
							JAXBContext context = JAXBContext.newInstance(clazz);
							contextMap.put(clazz, context);
						} catch (ClassNotFoundException e) {
							LOGGER.error("ClassNotFound",e);
						} catch (JAXBException e) {
							LOGGER.error("init jaxbContext error className is"+className,e);
						}
					}
				}
			}
			
			public static MessageHelper getInstance(){
				if(instance == null){
					synchronized(MessageHelper.class){
						if(instance == null){
							instance = new MessageHelper();
						}
					}
				}
				return instance;
			}
			
			@SuppressWarnings("unchecked")
			public <T>T unmarshal(String str,Class<T> clazz){
				T result = null;
				StringReader reader = new StringReader(str); //字符读
				try {
					Unmarshaller unmarshaller = contextMap.get(clazz).createUnmarshaller();
					result = (T) unmarshaller.unmarshal(reader);
				} catch (JAXBException e) {
					LOGGER.error("unmarshal xml error",e);
				}
				return result;
			}
			
			public <T> String marshal(Object obj,Class<T> clazz) {
				StringWriter writer = new StringWriter(); //字符串写
				writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
				try {
					Marshaller marshaller = contextMap.get(clazz).createMarshaller();
					marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
					marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
					marshaller.marshal(obj, writer);
				} catch (JAXBException e) {
					LOGGER.error("marshal xml error",e);
				}
				return writer.toString();
			}
		}

		//调用
		MessageHelper.getInstance().marshal(AA, AA.class)
		MessageHelper.getInstance().unmarshal(sb.toString(), AA.class);





  • 5
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值