前两节讲了socket服务端,客户端的建立以及报文的封装。今天就来讲一下java对象和xml格式文件的相互转换。
上一节中我们列举了一个报文格式,其实我们可以理解为其实就是一个字符串。但是我们不可能每次都去写字符串啊,这样的话肯定要疯。既然是面向对象的编程,肯定会有好的办法来解决这个问题。我们使用JAXBContext这个工具。
package cn.com.egj.entity.shortcutTransfer.test; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.io.StringReader; import java.net.URLEncoder; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamWriter; /** * Jaxb2工具类 */ @XmlRootElement public class JaxbUtil { /** * JavaBean转换成xml * * @param obj * @param encoding * @return */ public static String convertToXml(Object obj) { try { JAXBContext context = JAXBContext.newInstance(obj.getClass()); Marshaller marshaller = context.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_ENCODING, "GBK"); marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true); ByteArrayOutputStream baos = new ByteArrayOutputStream(); //注意jdk版本 XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newInstance(); XMLStreamWriter xmlStreamWriter = xmlOutputFactory .createXMLStreamWriter(baos, (String) marshaller .getProperty(Marshaller.JAXB_ENCODING)); xmlStreamWriter.writeStartDocument( (String) marshaller.getProperty(Marshaller.JAXB_ENCODING), "1.0"); marshaller.marshal(obj, xmlStreamWriter); xmlStreamWriter.writeEndDocument(); xmlStreamWriter.close(); return new String(baos.toString("GBK")); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } /** * xml转换成JavaBean * * @param xml * @param c * @return */ @SuppressWarnings("unchecked") public static <T> T converyToJavaBean(String xml, Class<T> c) { T t = null; try { JAXBContext context = JAXBContext.newInstance(c); Unmarshaller unmarshaller = context.createUnmarshaller(); t = (T) unmarshaller.unmarshal(new StringReader(xml)); } catch (Exception e) { e.printStackTrace(); } return t; } }
以上两个方法可以将java对象可xml文件相互转换。
接下来我们看看怎么使用。
1)首先我们要建立需要转换的类:
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; @XmlAccessorType(XmlAccessType.FIELD)//表示使用这个类中的 private 非静态字段作为 XML 的序列化的属性或者元素,对应属性要使用get、set方法。 @XmlRootElement(name="ROOT") @XmlType(propOrder={"code","name","age"})//xml格式数据的显示的顺序名字要和定义变量的一样,而不是@XmlElement中的name public class MySocket { @XmlElement(name="Code",required=true)//定义xml中显示的数据 private String code; @XmlElement(name="Name",required=true) private String name; @XmlElement(name="Age",required=true) private String age; public String getCode() { return code; } public String getName() { return name; } public String getAge() { return age; } public void setCode(String code) { this.code = code; } public void setName(String name) { this.name = name; } public void setAge(String age) { this.age = age; } public String toString(){ return this.name+","+this.age+","+this.code; } }
public class Test { public static void main(String[] args) { objectToXml(); } public static void objectToXml(){ MySocket mySocket = new MySocket(); mySocket.setName("张三"); mySocket.setCode("00012"); mySocket.setAge("25"); String xml = JaxbUtil.convertToXml(mySocket); System.out.println(xml); } }
运行测试类,我们将看到控制台输出:<?xml version="1.0" encoding="GBK"?><ROOT><Code>00012</Code><Age>25</Age></ROOT>
对于Object转xml,我们建立测试方法:
public static void xmlToObjetct(){ String xml = "<?xml version=\"1.0\" encoding=\"GBK\"?><ROOT><Code>00011</Code><Name>李四</Name><Age>26</Age></ROOT>"; MySocket mySocket= JaxbUtil.converyToJavaBean(xml, MySocket.class); System.out.println(mySocket.toString()); }
运行测试类,我们将看到控制台输出:李四,26,00011
3)有时候我们的java对象中会存在集合,这时我们像如下这么做:
3.1)首先我们建立袋集合的对象:
@XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(name="ROOT") @XmlType(propOrder={"name","age","books"}) public class ListSocket { @XmlElement(name="Name",required=true) private String name; @XmlElement(name="Age",required=true) private String age; @XmlElementWrapper(name="ROWS")//@XmlElementWrapper注解表示生成一个包装 XML 表示形式的包装器元素。 此元素主要用于生成一个包装集合的包装器 XML 元素 @XmlElement(name="LIST",required=true) private List<Book> books; public String getName() { return name; } public String getAge() { return age; } public List<Book> getBooks() { return books; } public void setName(String name) { this.name = name; } public void setAge(String age) { this.age = age; } public void setBooks(List<Book> books) { this.books = books; } public String toString(){ String result = ""; result=this.age+","+this.name+",集合的数据:"; for (Book book:books) { result+=book.getAuthor()+book.getTime()+book.getBookName(); } return result; } }
@XmlAccessorType(XmlAccessType.FIELD) @XmlType(propOrder={"bookName","time","author"}) public class Book { @XmlElement(name="BookName") private String bookName; @XmlElement(name="Time") private String time; @XmlElement(name="Author") private String author; public String getBookName() { return bookName; } public String getTime() { return time; } public String getAuthor() { return author; } public void setBookName(String bookName) { this.bookName = bookName; } public void setTime(String time) { this.time = time; } public void setAuthor(String author) { this.author = author; } }3.2)建立测试类:
public class ListSocketTest { public static void main(String[] args) { objectToXml(); xmlToObject(); } public static void objectToXml(){ ListSocket listSocket = new ListSocket(); listSocket.setName("张三"); listSocket.setAge("26"); List<Book> books = new ArrayList<Book>(); Book book1 = new Book(); book1.setAuthor("作者1"); book1.setTime("2014-12-28"); book1.setBookName("How to use JAXB"); Book book2= new Book(); book2.setAuthor("作者2"); book2.setTime("2014-06-06"); book2.setBookName("How to use SOCKET"); books.add(book1); books.add(book2); listSocket.setBooks(books); String xml = JaxbUtil.convertToXml(listSocket); System.out.println(xml); } public static void xmlToObject(){ String xml = "<?xml version=\"1.0\" encoding=\"GBK\"?><ROOT><Name>张三</Name><Age>26</Age><ROWS><LIST>" +"<BookName>How to use JAXB</BookName><Time>2014-12-28</Time><Author>作者1</Author>" +"</LIST><LIST><BookName>How to use SOCKET</BookName><Time>2014-06-06</Time><Author>作者2</Author></LIST></ROWS></ROOT>"; ListSocket listSocket = JaxbUtil.converyToJavaBean(xml, ListSocket.class); System.out.println(listSocket); }