最近需要做一个接收xml字符串,转化为java对象并录入数据库功能
说一下我的业务,
我是先从rabbitmq中拿到固定格式的字符串形式的xml,且目标数据是在某一个标签中,是一串base64加密的字符串,转换后是对应的字符串形式的xml
所以我需要先将字符串转换为xml对象获取对应的节点(也可以通过java字符串查找截取,但可能比较费事)并再次字符串转换为xml对象,再将xml对象转换为java对象存到数据库中。
引入依赖
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
</dependency>
难点,我的最终xml解析出来 对应的标签比较混乱
准备一个测试xml
我是菜鸟
RUNOOB
www.runoob.com
Google
www.google.com
Facebook
www.facebook.com
RUNOOB
www.runoob.com
RUNOOB
www.runoob.com
RUNOOB
www.runoob.com
这个xml代表了转换时候遇到的几种情况
1 多条用一个总标签给包起来的(sites -> site)
2 多个标签就直接出现在xml中 (user)
3 直接就是唯一的标签(这种最简单直接转换 singleEle)
JAXB 用对象给转换xml对象时,是按照标签层级来一步一步对照的,比如这个sites标签内的site怎么转换成list呢,我们可以多创建一个java对象来对应,这个java对象的根目录注解就是sites 创建这个sites对象,这个对象里面再如法炮制创建list对象
对于第二个直接在我们创建的xml根目录类上面定义list
单独bena 直接 定义单独对象好了
上图
再来看一下sites
再看一下 site
对应的话大致就是这样,这里说一句@XmlRootElement 一定要按层级一级一级来,一个类一个这个注解对应一层标签,另外@XmlAccessorType 这个注解也不可少,表明是文件类型,不然会报错,报错还有一种方案是在get方法上加注解,一时忘了是啥注解,你可以百度一下,好了例子举证完,看一下我的项目结构就上代码了
entity 里面是对应的注解文件
tools 是解析文件
调用在test文件 因为main执行就可以没有走接口
好了上代码
entity 代码
package com.example.demo.entity;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "rootEle")
@XmlAccessorType(XmlAccessType.FIELD)
public class XmlTest {
@XmlElement(name = "sites")
private Sites sites;
@XmlElement(name = "user")
private List<User> users;
@XmlElement(name = "singleEle")
private SingleEle singleEle;
/**
* @return the singleEle
*/
public SingleEle getSingleEle() {
return singleEle;
}
/**
* @param singleEle the singleEle to set
*/
public void setSingleEle(SingleEle singleEle) {
this.singleEle = singleEle;
}
/**
* @return the sites
*/
public Sites getSites() {
return sites;
}
/**
* @param sites the sites to set
*/
public void setSites(Sites sites) {
this.sites = sites;
}
/**
* @return the users
*/
public List<User> getUsers() {
return users;
}
/**
* @param users the users to set
*/
public void setUsers(List<User> users) {
this.users = users;
}
/**
* @return
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "Test [sites=" + sites + ", users=" + users + ", singleEle=" + singleEle + "]";
}
}
package com.example.demo.entity;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "sites")
@XmlAccessorType(XmlAccessType.FIELD)
public class Sites {
@XmlElement(name = "site")
private List<Site> sites;
/**
* @return
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "Sites [sites=" + sites + "]";
}
/**
* @return the sites
*/
public List<Site> getSites() {
return sites;
}
/**
* @param sites the sites to set
*/
public void setSites(List<Site> sites) {
this.sites = sites;
}
}
package com.example.demo.entity;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "site")
@XmlAccessorType(XmlAccessType.FIELD)
public class Site {
@XmlElement(name = "name")
private String name;
@XmlElement(name = "url")
private String url;
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the url
*/
public String getUrl() {
return url;
}
/**
* @param url the url to set
*/
public void setUrl(String url) {
this.url = url;
}
/**
* @return
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "Site [name=" + name + ", url=" + url + "]";
}
}
package com.example.demo.entity;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "user")
@XmlAccessorType(XmlAccessType.FIELD)
public class User {
@XmlElement(name = "name")
private String name;
@XmlElement(name = "url")
private String url;
/**
* @return
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "User [name=" + name + ", url=" + url + "]";
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the url
*/
public String getUrl() {
return url;
}
/**
* @param url the url to set
*/
public void setUrl(String url) {
this.url = url;
}
}
package com.example.demo.entity;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "singleEle")
@XmlAccessorType(XmlAccessType.FIELD)
public class SingleEle {
@XmlElement(name = "name")
private String name;
@XmlElement(name = "url")
private String url;
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the url
*/
public String getUrl() {
return url;
}
/**
* @param url the url to set
*/
public void setUrl(String url) {
this.url = url;
}
/**
* @return
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "Site [name=" + name + ", url=" + url + "]";
}
}
tools代码
package com.example.demo.tools;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.StringReader;
import java.io.StringWriter;
public class XmlUtils {
/**
* bean转成xml
* @param t :
* @return string
*/
public static <T> String beanToXml(T t){
try {
JAXBContext context = JAXBContext.newInstance(t.getClass());
Marshaller m = context.createMarshaller();
StringWriter sw = new StringWriter();
m.marshal(t,sw);
return sw.toString();
} catch (JAXBException e) {
e.printStackTrace();
}
return "";
}
/**
* bean转成xml(泛型使用)
* @param t :
* @return java.lang.String
*/
public static <T> String beanToXml(T t, Class c) {
try {
JAXBContext context = JAXBContext.newInstance(t.getClass(),c);
Marshaller m = context.createMarshaller();
StringWriter sw = new StringWriter();
m.marshal(t,sw);
return sw.toString();
} catch (JAXBException e) {
e.printStackTrace();
}
return "";
}
/**
* xml 转成 bean
* @param xml :
* @param t :
* @return T
*/
public static <T> T xmlToBean(String xml, T t) {
try {
JAXBContext context = JAXBContext.newInstance(t.getClass());
Unmarshaller um = context.createUnmarshaller();
StringReader sr = new StringReader(xml);
t = (T) um.unmarshal(sr);
return t;
} catch (JAXBException e) {
e.printStackTrace();
}
return null;
}
/**
* xml 转成 bean(泛型使用)
* @param t, t
* @param xml xml
* @param c t]
* @return T
*/
public static <T> T xmlToBean(String xml, T t, Class c){
try {
JAXBContext context = JAXBContext.newInstance(t.getClass(),c);
Unmarshaller um = context.createUnmarshaller();
StringReader sr = new StringReader(xml);
t = (T) um.unmarshal(sr);
return t;
} catch (JAXBException e) {
e.printStackTrace();
}
return null;
}
}
接下来是调用代码
package com.example.demo;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.w3c.dom.Document;
import com.example.demo.entity.XmlTest;
import com.example.demo.tools.XmlUtils;
@SpringBootTest
class DemoApplicationTests {
@Test
void contextLoads() {
}
public static void main(String[] args) {
String xml = "我是菜鸟 RUNOOB www.runoob.com Google www.google.com Facebook www.facebook.com RUNOOB www.runoob.com RUNOOB www.runoob.com RUNOOB www.runoob.com ";
XmlTest test = new XmlTest();
Document doc = StringToXml(xml);
if (doc == null) {
//异常数据处理
}
String nodePath = "rootEle/title";
String nodeValue = getNodeValue(doc, nodePath);
if("".equals(nodeValue)) {
//异常数据处理
}
test = XmlUtils.xmlToBean(xml, test,XmlTest.class);
System.out.println("xml转成bean格式为:\n" + test);
}
/**
*
* @param xml形状的str串
* @return Document 对象
*/
public static Document StringToXml(String str) {
StringBuilder sXML = new StringBuilder();
sXML.append(str);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
Document doc = null;
InputStream is = null;
try {
is = new ByteArrayInputStream(sXML.toString().getBytes("utf-8"));
doc = dbf.newDocumentBuilder().parse(is);
} catch (Exception e) {
e.printStackTrace();
} finally {
//关闭输入流
if (is != null)
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return doc;
}
/**
*
* @param xml的document 和string 路径
* @return String 目标节点的字符串值
*/
public static String getNodeValue(Document document, String nodePaht) {
XPathFactory xpfactory = XPathFactory.newInstance();
XPath path = xpfactory.newXPath();
String servInitrBrch = "";
try {
servInitrBrch = path.evaluate(nodePaht, document);
} catch (XPathExpressionException e) {
e.printStackTrace();
}
return servInitrBrch;
}
}