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;

		  @XmlAttribute
		  protected String id;

		  @XmlAttribute
		  protected String type;

		  public List 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;
		    }
		  }
		}
		
		//模版
		
		
			
				
					
						
							
								
								
							
						
					
					
					
				
			
		

		//例子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;


		/**
		 * 

Java class for anonymous complex type. * *

The following schema fragment specifies the expected content contained within this class. * *

		 * 
		 *   
		 *     
		 *       
		 *         
		 *         
		 *         
		 *       
		 *       
		 *       
		 *     
		 *   
		 * 
		 * 
* * */ @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 方法 } //模版

    注解介绍
        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 {
                    // 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 = "" +
						"22" +
						"41软件工程" +
						"101张三";  
				
				
				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();
			}
		}

	
		结果:
			生成文件为
			

			
				22
				
					4
					1
					软件工程
				
				101
				张三
			


		
	例子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, JAXBContext> contextMap = new HashMap, 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 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 unmarshal(String str,Class 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  String marshal(Object obj,Class clazz) {
				StringWriter writer = new StringWriter(); //字符串写
				writer.write("\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);





你可能感兴趣的:(xml)