本文主要涉及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验证
- 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;
}
}
- 生成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;
}
}