1. 程式人生 > >JAXB和XML驗證

JAXB和XML驗證

一、XML驗證

  1. model實體物件
package com.soft.webservice.model;

import java.io.Serializable;
import java.sql.Timestamp;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

import com.soft.webservice.adapter.DateAdapter;

/**
 * 使用者類
 */
@XmlRootElement(name="user")
@XmlAccessorType(XmlAccessType.FIELD)
public class User implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 7823921784743906881L;
	/**
	 * 使用者ID
	 */
	private String userId;
	/**
	 * 使用者姓名
	 */
	private String userName;
	/**
	 * 使用者賬號
	 */
	private String accountName;
	/**
	 * 年齡
	 */
	private int age;
	/**
	 * 性別(0:男;1:女)
	 */
	private String sex;
	/**
	 * 身高(cm)
	 */
	private Double height;
	/**
	 * 建立時間
	 */
	@XmlJavaTypeAdapter(DateAdapter.class)
	private Timestamp createTime;
	
	public User() {
		super();
	}
	
	public User(String userId, String userName, String accountName, int age,
			String sex, Double height, Timestamp createTime) {
		super();
		this.userId = userId;
		this.userName = userName;
		this.accountName = accountName;
		this.age = age;
		this.sex = sex;
		this.height = height;
		this.createTime = createTime;
	}

	public String getUserId() {
		return userId;
	}

	public void setUserId(String userId) {
		this.userId = userId;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getAccountName() {
		return accountName;
	}

	public void setAccountName(String accountName) {
		this.accountName = accountName;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

	@Override
	public String toString() {
		return "User [userId=" + userId + ", userName=" + userName
				+ ", accountName=" + accountName + ", age=" + age + ", sex="
				+ sex + ", height=" + height + ", createTime=" + createTime.toString()
				+ "]";
	}

	public Double getHeight() {
		return height;
	}

	public void setHeight(Double height) {
		this.height = height;
	}

	public Timestamp getCreateTime() {
		return createTime;
	}

	public void setCreateTime(Timestamp createTime) {
		this.createTime = createTime;
	}
}

  1. 生成XML Schema檔案
package ssm;

import java.io.File;
import java.io.IOException;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.SchemaOutputResolver;
import javax.xml.transform.Result;
import javax.xml.transform.stream.StreamResult;

import com.soft.webservice.model.User;

/**
 *XML Schema檔案生成工具
 */
public class JAXBExportSchema {
	
	/**
	 * 
	 * 生成schema1.xsd  檔案
	 */
	public static void main(String[] args)  {
		try {
			JAXBContext jaxbContext = JAXBContext.newInstance(User.class);
			jaxbContext.generateSchema(new Resolver());
		} catch (JAXBException | IOException e) {
			e.printStackTrace();
		}
	}

}

class Resolver extends SchemaOutputResolver {

	@Override
	public Result createOutput(String namespaceUri, String suggestedFileName)
			throws IOException {
		File file = new File("d:\\", suggestedFileName);
		StreamResult result = new StreamResult(file);
		result.setSystemId(file.toURI().toURL().toString());
		return result;
	}

}

3.user.xsd檔案修改

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">

	<xs:element name="user" type="user" />

	<xs:complexType name="user">
		<xs:sequence>
		    <!-- id字串值長度必須大於5並且小於8 -->
			<xs:element name="userId" minOccurs="1">
				<xs:simpleType>
					<xs:restriction base="xs:string">
						<xs:minLength value="5" />
						<xs:maxLength value="8" />
					</xs:restriction>
				</xs:simpleType>
			</xs:element>
			<xs:element name="userName" type="xs:string" minOccurs="0" />
			<xs:element name="accountName" type="xs:string" minOccurs="0" />
			<!-- 年齡必須大於1並且小於120的正整數 -->
			<xs:element name="age">
				<xs:simpleType>
					<xs:restriction base="xs:integer">
						<xs:minInclusive value="1" />
						<xs:maxInclusive value="120" />
					</xs:restriction>
				</xs:simpleType>
			</xs:element>
			<!-- 性別值 必須是0或者1 -->
			<xs:element name="sex"  minOccurs="1">
				<xs:simpleType>
					<xs:restriction base="xs:string">
						<xs:pattern value="[01]" />
					</xs:restriction>
				</xs:simpleType>
			</xs:element>
			<!-- 身高 十進位制數 -->
			<xs:element name="height" type="xs:decimal" minOccurs="1" />
			<!-- 建立時間是 日期時間資料型別  格式必須是  YYYY-MM-DDThh:mm:ss -->
			<xs:element name="createTime" type="xs:dateTime" minOccurs="1" />
		</xs:sequence>
	</xs:complexType>
</xs:schema>

4.驗證XML格式

public static void main(String[] args) {
		String xmlModel = "<user><userId><![CDATA[[email protected]#$>llo]]></userId><userName>陳某某</userName>"
				+ "<accountName>chenmm</accountName><age>23</age><sex>0</sex><height>178.5</height>"
				+ "<createTime>2018-10-01T12:12:12</createTime></user>";

		boolean result = validateXML("../schema/user.xsd", xmlModel);
		System.out.println(result);

		try {
			User user = (User) JAXBUtil.unmarshal(xmlModel.getBytes(),
					User.class);
			System.out.println(user.toString());
		} catch (JAXBException e) {
			e.printStackTrace();
		}

	}

	/**
	 * 根據Schema xsd檔案驗證 xml 檔案
	 * 
	 * @param xsdPath
	 * @param xmlStr
	 * @return
	 */
	public static boolean validateXML(String xsdPath, String xmlStr) {
		try {
			SchemaFactory factory = SchemaFactory
					.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
			// Schema schema = factory.newSchema(new File(xsdPath));
			Schema schema = factory.newSchema(JAXBTest.class
					.getResource(xsdPath));
			Reader xmlReader = new StringReader(xmlStr);
			Source xmlSource = new StreamSource(xmlReader);

			Validator validator = schema.newValidator();
			validator.validate(xmlSource);

		} catch (IOException | SAXException e) {
			System.out.println("Exception: " + e.getMessage());
			return false;
		}
		return true;

	}

結果為:

true User [[email protected]#$>llo, userName=陳某某, accountName=chenmm, age=23, sex=0, height=178.5, createTime=2018-10-01 12:12:12.0]

5.日期格式化

<properties>
        <jodd.version>3.7</jodd.version>
 </properties>
  <dependency>
    <groupId>org.jodd</groupId>
    <artifactId>jodd-core</artifactId>
    <version>${jodd.version}</version>
</dependency>
jodd3.7支援jdk1.7 ,  3.8以後必須要jdk1.8才行

package com.soft.webservice.adapter;

import java.sql.Timestamp;

import javax.xml.bind.annotation.adapters.XmlAdapter;

import jodd.datetime.JDateTime;

/**
 1. 格式化處理
 2. 日期時間格式化處理
 */
public class DateAdapter extends XmlAdapter<String, Timestamp>{

	/**
	 * 反序列化成物件時
	 */
	@Override
	public Timestamp unmarshal(String dateTime) throws Exception {
		JDateTime date = new JDateTime(dateTime,"YYYY-MM-DDThh:mm:ss");
		Timestamp timestamp = new Timestamp(date.getTimeInMillis());
		return timestamp;
	}

	/**
	 * 序列化成字串時
	 */
	@Override
	public String marshal(Timestamp timestamp) throws Exception {
		JDateTime dateTime = new JDateTime(timestamp);
		return dateTime.toString("YYYY-MM-DD hh:mm:ss");
	}
}

二、JavaBean和XML相互轉換

1.model實體物件

package com.soft.webservice.model;

import java.util.List;

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

/**
 * 作者物件
 */
@XmlRootElement(name="base_author")
@XmlAccessorType(XmlAccessType.FIELD)
public class Author {
    /**
     * ID
     */
	private String authorId;
	/**
	 * 作者姓名
	 */
	private String authorUserName;
	/**
	 * 作者郵箱
	 */
	private String authorEmail;
	/**
	 * 作者手機號碼
	 */
	private String authorMobile;
	/**
	 * 作者年齡
	 */
	private int authorAge;
	/**
	 * 作者性別
	 */
	private String authorSex;
	/**
	 * 文章列表
	 */
	@XmlElementWrapper(name="blogs")
	private List<Blog> blog;
	
	public Author() {
		super();
	}

	public String getAuthorId() {
		return authorId;
	}

	public void setAuthorId(String authorId) {
		this.authorId = authorId;
	}

	public String getAuthorUserName() {
		return authorUserName;
	}

	public void setAuthorUserName(String authorUserName) {
		this.authorUserName = authorUserName;
	}

	public String getAuthorEmail() {
		return authorEmail;
	}

	public void setAuthorEmail(String authorEmail) {
		this.authorEmail = authorEmail;
	}

	public String getAuthorMobile() {
		return authorMobile;
	}

	public void setAuthorMobile(String authorMobile) {
		this.authorMobile = authorMobile;
	}

	public int getAuthorAge() {
		return authorAge;
	}

	public void setAuthorAge(int authorAge) {
		this.authorAge = authorAge;
	}

	public String getAuthorSex() {
		return authorSex;
	}

	public void setAuthorSex(String authorSex) {
		this.authorSex = authorSex;
	}

	public List<Blog> getBlog() {
		return blog;
	}

	public void setBlog(List<Blog> blog) {
		this.blog = blog;
	}

	@Override
	public String toString() {
		return "Author [authorId=" + authorId + ", authorUserName="
				+ authorUserName + ", authorEmail=" + authorEmail
				+ ", authorMobile=" + authorMobile + ", authorAge=" + authorAge
				+ ", authorSex=" + authorSex + "]";
	}

}
package com.soft.webservice.model;

import java.sql.Timestamp;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

import com.soft.webservice.adapter.DateAdapter;

/**
 * 部落格物件
 */
@XmlRootElement(name="blog")
@XmlAccessorType(XmlAccessType.FIELD)
public class Blog {
	/**
	 * ID
	 */
	private String blogId;
	/**
	 * 標題
	 */
	private String blogTitle;
	/**
	 * 作者ID
	 */
	private String blogAuthorId;
	/**
	 * 部落格內容
	 */
	private String blogContent;
	/**
	 * 釋出時間
	 */
	@XmlJavaTypeAdapter(DateAdapter.class)
	private Timestamp blogPublishTime;
     
	/**
	 * 無引數構造
	 */
	public Blog() {
		super();
	}

	public String getBlogId() {
		return blogId;
	}

	public void setBlogId(String blogId) {
		this.blogId = blogId;
	}

	public String getBlogTitle() {
		return blogTitle;
	}

	public void setBlogTitle(String blogTitle) {
		this.blogTitle = blogTitle;
	}

	public String getBlogAuthorId() {
		return blogAuthorId;
	}

	public void setBlogAuthorId(String blogAuthorId) {
		this.blogAuthorId = blogAuthorId;
	}

	public String getBlogContent() {
		return blogContent;
	}

	public void setBlogContent(String blogContent) {
		this.blogContent = blogContent;
	}

	public Timestamp getBlogPublishTime() {
		return blogPublishTime;
	}

	public void setBlogPublishTime(Timestamp blogPublishTime) {
		this.blogPublishTime = blogPublishTime;
	}

	@Override
	public String toString() {
		return "Blog [blogId=" + blogId + ", blogTitle=" + blogTitle
				+ ", blogAuthorId=" + blogAuthorId + ", blogContent="
				+ blogContent + ", blogPublishTime=" + blogPublishTime + "]";
	}
}

2.JAXBUtil工具類(JavaBean2xml)

package ssm;

import java.io.ByteArrayInputStream;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

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

import org.apache.commons.io.IOUtils;

import com.soft.webservice.model.Author;
import com.soft.webservice.model.Blog;


/**
 * JAXB工具類
 */
public class JAXBUtil {
	/**
	 * Java實體物件轉換為XML byte陣列
	 * 
	 * @param obj
	 * @throws JAXBException
	 */
	public static byte[] marshal(Object obj) throws JAXBException {
		JAXBContext context = JAXBCache.getInstance().getJAXBContext(
				obj.getClass());
		Marshaller m = context.createMarshaller();
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		// 格式化輸出,即按標籤自動換行,否則就是一行輸出
		m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
		// 設定編碼(預設編碼就是utf-8)
		m.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
		// 是否省略xml頭資訊,預設不省略(false)
		m.setProperty(Marshaller.JAXB_FRAGMENT, false);
		// 將Java物件序列化為XML資料;
		m.marshal(obj, outputStream);
		byte[] result = outputStream.toByteArray();
		return result;
	}

	/**
	 * 將XML資料反序列化為Java物件。
	 * 
	 * @param data
	 * @param classe
	 * @throws JAXBException
	 */
	public static Object unmarshal(byte[] data, Class<?> classe)
			throws JAXBException {
		JAXBContext context = JAXBCache.getInstance().getJAXBContext(classe);
		Unmarshaller m = context.createUnmarshaller();
		ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
		Object obj = m.unmarshal(inputStream);
		return obj;
	}

	/**
	 * 將XML資料反序列化為Java物件。
	 * 
	 * @param in
	 * @param classe
	 * @throws JAXBException
	 * @throws IOException
	 */
	public static Object unmarshal(InputStream in, Class<?> classe)
			throws JAXBException, IOException {
		JAXBContext context = JAXBCache.getInstance().getJAXBContext(classe);
		byte[] data = IOUtils.toByteArray(in);
		Unmarshaller m = context.createUnmarshaller();
		ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
		Object obj = m.unmarshal(inputStream);
		return obj;
	}

	/**
	 * 測試
	 * 
	 * @param args
	 * @throws JAXBException
	 */
	public static void main(String[] args) throws JAXBException {
		Author author = new Author();
		author.setAuthorId("a2354asde5wdsf234");
		author.setAuthorEmail("[email protected]");
		author.setAuthorAge(23);
		author.setAuthorUserName("陳某某");
		author.setAuthorMobile("18046056457");
		author.setAuthorSex("");

		List<Blog> blogs = new ArrayList<Blog>();
		Blog javaBlog = new Blog();
		javaBlog.setBlogContent("關於Java");
		javaBlog.setBlogTitle("Java連線資料庫JDBC入門");
		javaBlog.setBlogPublishTime(new Timestamp(System.currentTimeMillis()));

		Blog htmlBlog = new Blog();
		htmlBlog.setBlogContent("關於HTML");
		htmlBlog.setBlogTitle("HTML標籤元素學習");
		htmlBlog.setBlogPublishTime(new Timestamp(System.currentTimeMillis()));
		blogs.add(javaBlog);
		blogs.add(htmlBlog);
		author.setBlog(blogs);

		byte[] xmlByte = marshal(author);
		String xmlStr = new String(xmlByte);
		System.out.println(xmlStr);

	}
}

輸出結果為:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<base_author>
    <authorId>a2354asde5wdsf234</authorId>
    <authorUserName>陳某某</authorUserName>
    <authorEmail>[email protected]</authorEmail>
    <authorMobile>18046056457</authorMobile>
    <authorAge>23</authorAge>
    <authorSex></authorSex>
    <blogs>
        <blog>
            <blogTitle>Java連線資料庫JDBC入門</blogTitle>
            <blogContent>關於Java</blogContent>
            <blogPublishTime>2018-10-01 15:26:25</blogPublishTime>
        </blog>
        <blog>
            <blogTitle>HTML標籤元素學習</blogTitle>
            <blogContent>關於HTML</blogContent>
            <blogPublishTime>2018-10-01 15:26:25</blogPublishTime>
        </blog>
    </blogs>
</base_author>

3.xml轉JavaBean author.xsd

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:element name="base_author" type="author"/>

  <xs:element name="blog" type="blog"/>

  <xs:complexType name="author">
    <xs:sequence>
      <xs:element name="authorId" type="xs:string" minOccurs="0"/>
      <xs:element name="authorUserName" type="xs:string" minOccurs="0"/>
      <xs:element name="authorEmail" type="xs:string" minOccurs="0"/>
      <xs:element name="authorMobile" type="xs:string" minOccurs="0"/>
      <xs:element name="authorAge" type="xs:int"/>
      <xs:element name="authorSex" type="xs:string" minOccurs="0"/>
      <xs:element name="blogs" minOccurs="1">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="blog" type="blog" nillable="true" minOccurs="1" maxOccurs="unbounded"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="blog">
    <xs:sequence>
      <xs:element name="blogId" type="xs:string" minOccurs="0"/>
      <xs:element name="blogTitle" type="xs:string" minOccurs="0"/>
      <xs:element name="blogAuthorId" type="xs:string" minOccurs="0"/>
      <xs:element name="blogContent" type="xs:string" minOccurs="0"/>
      <xs:element name="blogPublishTime" type="xs:dateTime" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>
package ssm;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.util.List;

import javax.xml.XMLConstants;
import javax.xml.bind.JAXBException;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;

import org.xml.sax.SAXException;

import com.soft.webservice.model.Author;
import com.soft.webservice.model.Blog;

public class XmlToBean {

	public static void main(String[] args) {
		String xmlModel = "<base_author>"
				+ "<authorId>a2354asde5wdsf234</authorId>"
				+ "<authorUserName>陳某某</authorUserName><authorEmail>[email protected]</authorEmail>"
				+ "<authorMobile>18046056457</authorMobile><authorAge>23</authorAge>"
				+ "<authorSex>1</authorSex>"
				+ "<blogs>"
				+ "    <blog><blogTitle>Java連線資料庫JDBC入門</blogTitle><blogContent>關於Java</blogContent><blogPublishTime>2018-10-01T16:42:20</blogPublishTime></blog>"
				+ "    <blog><blogTitle>HTML標籤元素學習</blogTitle><blogContent>關於HTML</blogContent><blogPublishTime>2018-10-01T16:42:20</blogPublishTime></blog>"
				+ "</blogs>"
				+ "</base_author>";

		boolean result = validateXML("../schema/author.xsd", xmlModel);
		System.out.println(result);
		try {
			Author author = (Author) JAXBUtil.unmarshal(xmlModel.getBytes("UTF-8"), Author.class);
			System.out.println(author.toString());
			List<Blog> blogs = author.getBlog();
			for(Blog blog:blogs){
				System.out.println(blog.toString());
			}
			
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (JAXBException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 根據Schema xsd檔案驗證 xml 檔案
	 * 
	 * @param xsdPath
	 * @param xmlStr
	 * @return
	 */
	public static boolean validateXML(String xsdPath, String xmlStr) {
		try {
			SchemaFactory factory = SchemaFactory
					.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
			// Schema schema = factory.newSchema(new File(xsdPath));
			Schema schema = factory.newSchema(JAXBTest.class
					.getResource(xsdPath));
			Reader xmlReader = new StringReader(xmlStr);
			Source xmlSource = new StreamSource(xmlReader);

			Validator validator = schema.newValidator();
			validator.validate(xmlSource);

		} catch (IOException | SAXException e) {
			System.out.println("Exception: " + e.getMessage());
			return false;
		}
		return true;

	}

}