JAXB和XML验证

本文主要涉及JAXB实现JavaBean和XML相互转换 和 XML验证
JDK:1.8
本文涉及的代码大部分参考来自以下几篇文章
JAXB:
https://www.cnblogs.com/chenbenbuyi/p/8283657.html
https://www.cnblogs.com/cnsdhzzl/p/8390514.html
XSD验证
http://www.cnblogs.com/newsouls/archive/2011/10/28/2227765.html

一、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[d@#$>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 [userId=d@#$>llo, userName=陈某某, accountName=chenmm, age=23, sex=0, height=178.5, createTime=2018-10-01 12:12:12.0]

5.日期格式化

日期格式转换 依赖了jodd类库(https://jodd.org/)

<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);

	}
}
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

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

public class JAXBCache {
	
	private static final JAXBCache instance = new JAXBCache ();
	
	private final ConcurrentMap<String, JAXBContext> contextCache = new ConcurrentHashMap<String, JAXBContext>();
	
	private JAXBCache (){}
	
	public static JAXBCache  getInstance(){
		return instance;
	}
	
	public  JAXBContext getJAXBContext(Class<?> clazz) throws JAXBException{
		JAXBContext context = contextCache.get(clazz.getName());
		if(null == context){
			context = JAXBContext.newInstance(clazz);
			contextCache.put(clazz.getName(), context);
		}
		
		return context;
	}

}

输出结果为:

<?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;

	}

}

猜你喜欢

转载自blog.csdn.net/linjinhuo/article/details/82916593