Javaxml数据格式返回实现操作
前⾔:对于服务器后端开发,接⼝返回的数据格式⼀般要求都是json,但是也有使⽤xml格式
RequestBody注解
对于SpringMVC,很多⼈会认为接⼝⽅法使⽤@Controller搭配@ResponseBody和@RequestMapping注解后,java对象会转换成json格式返回。
但实际上配合@ResponseBody注解后,接⼝返回的数据类型是根据HTTP Request Header中的Accept属性来确定的,可以是XML或者JSON数据
通过适当的HttpMessageConverter对java对象进⾏格式转换,常⽤的有:
ByteArrayHttpMessageConverter
负责读取⼆进制格式的数据和写出⼆进制格式的数据;
StringHttpMessageConverter
负责读取字符串格式的数据和写出⼆进制格式的数据;
ResourceHttpMessageConverter
负责读取资源⽂件和写出资源⽂件数据;
FormHttpMessageConverter
负责读取form提交的数据;
MappingJacksonHttpMessageConverter
负责读取和写⼊json格式的数据;
SouceHttpMessageConverter
负责读取和写⼊ xml 中ansform.Source定义的数据;
Jaxb2RootElementHttpMessageConverter
负责读取和写⼊xml 标签格式的数据;
AtomFeedHttpMessageConverter
负责读取和写⼊Atom格式的数据;
RssChannelHttpMessageConverter
负责读取和写⼊RSS格式的数据
具体使⽤哪个怎么判断这⾥就不细讲了,我们关⼼的是Jaxb2RootElementHttpMessageConverter这个⽅法,后⾯会讲为啥会提
java对象与xml之间互相转换
使⽤Java⾃带注解的⽅式实现(@XmlRootElement,@XmlAccessorType,@XmlElement,@XmlAttribute),具体使⽤⽅法⽹上有很多
这⾥直接代码举例
l.bind.annotation.XmlElement;
l.bind.annotation.XmlRootElement;
l.bind.annotation.XmlType;
@XmlRootElement(name = "city")
@XmlType(propOrder = { "name","province"})
public class City {
private String name;
private String province;
public City() {
}
public City(String name, String province) {
this.name = name;
this.province = province;
}
public String getName() {
return name;
}
@XmlElement
public void setName(String name) {
this.name = name;
}
public String getProvince() {
return province;
}
@XmlElement
public void setProvince(String province) {
this.province = province;
}
}
controller
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class IndexController {
@RequestMapping(path = "/get")
@ResponseBody
public City getXml(){
City city= new City("太原","⼭西");
return city;
}
}
是不很容易就实现接⼝返回xml格式
使⽤<![CDATA[]]>
对象属性中有可能存在计算逻辑'<‘或'>',⽽在xml⽂件中这两个符号是不合法的,会转换为<和>,这样数据就'坏'了,所以<! [CDATA[]]>的加⼊是⾮常有必要的!
⼀般实现:使⽤XmlAdapter定义⼀个CDataAdapter类,⽹上也有很多代码
⼤概的实现如下
public class CDataAdapter extends XmlAdapter<String, String> {
@Override
public String unmarshal(String v) throws Exception {
// 我们这⾥没有xml转java对象,这⾥就不具体实现了
return v;
}
@Override
public String marshal(String v) throws Exception {
return new StringBuilder("<![CDATA[").append(v).append("]]>").toString();
}
}
然后使⽤注解XmlJavaTypeAdapter作⽤于属性变量上
@XmlJavaTypeAdapter(value=CDataAdapter.class)
@XmlElement
public void setProvince(String province) {
this.province = province;
}
结果
但是实际上看源码
这个不是我们希望的,产⽣原因是Jaxb默认会把字符'<', '>'进⾏转义, 下⾯解决这个问题
我们使⽤annotations.XmlCDATA注解来解决
使⽤EclipseLink JAXB (MOXy)
pom⽂件增加
<dependency>
<groupId&lipse.persistence</groupId>
<artifactId&</artifactId>
<version>xx版本</version>
</dependency>
上⼀节中的属性使⽤注解
...
annotations.XmlCDATA;
...
...
@XmlCDATA
@XmlElement
public void setProvince(String province) {
this.province = province;
}
注意:⼀定要设置jaxb.properties⽂件,并且要放在要转换成xml的java对象所在⽬录,并且要编译到target中,不然XmlCDATA注解不⽣效
jaxb.properties⽂件内容,就是指定创建JAXBContext对象的⼯长
到这⾥配置完成!
补充知识:Java Document⽣成和解析XML
⼀)Document介绍
API来源:在JDK中l.*包下
使⽤场景:
1、需要知道XML⽂档所有结构
2、需要把⽂档⼀些元素排序
3、⽂档中的信息被多次使⽤的情况
优势:由于Document是java中⾃带的解析器,兼容性强
缺点:由于Document是⼀次性加载⽂档信息,如果⽂档太⼤,加载耗时长,不太适⽤⼆)Document⽣成XML
实现步骤:
第⼀步:初始化⼀个XML解析⼯⼚
DocumentBuilderFactory factory = wInstance();
第⼆步:创建⼀个DocumentBuilder实例
DocumentBuilder builder = wDocumentBuilder();
第三步:构建⼀个Document实例
Document doc = wDocument();
doc.setXmlStandalone(true);
standalone⽤来表⽰该⽂件是否呼叫其它外部的⽂件。若值是 ”yes” 表⽰没有呼叫外部⽂件第四步:创建⼀个根节点,名称为root,并设置⼀些基本属性
Element element = ateElement("root");
element.setAttribute("attr", "root");//设置节点属性
childTwoTwo.setTextContent("root attr");//设置标签之间的内容
第五步:把节点添加到Document中,再创建⼀些⼦节点加⼊
doc.appendChild(element);
第六步:把构造的XML结构,写⼊到具体的⽂件中
实现源码:
l;
import java.io.File;
l.parsers.DocumentBuilder;
l.parsers.DocumentBuilderFactory;
l.parsers.ParserConfigurationException;
l.transform.OutputKeys;
l.transform.Transformer;
l.transform.TransformerConfigurationException;
l.transform.TransformerException;
l.transform.TransformerFactory;
l.transform.dom.DOMSource;
l.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
/**
* Document⽣成XML
* @author ouyangjun
*/
public class CreateDocument {
public static void main(String[] args) {
// 执⾏Document⽣成XML⽅法
spring怎么读取xml文件createDocument(new File("E:\\l"));
}
public static void createDocument(File file) {
try {
// 初始化⼀个XML解析⼯⼚
DocumentBuilderFactory factory = wInstance();
// 创建⼀个DocumentBuilder实例
DocumentBuilder builder = wDocumentBuilder();
// 构建⼀个Document实例
Document doc = wDocument();
doc.setXmlStandalone(true);
// standalone⽤来表⽰该⽂件是否呼叫其它外部的⽂件。若值是 ”yes” 表⽰没有呼叫外部⽂件
// 创建⼀个根节点
/
/ 说明: ateElement("元素名")、element.setAttribute("属性名","属性值")、element.setTextContent("标签间内容") Element element = ateElement("root");
element.setAttribute("attr", "root");
// 创建根节点第⼀个⼦节点
Element elementChildOne = ateElement("person");
elementChildOne.setAttribute("attr", "personOne");
element.appendChild(elementChildOne);
// 第⼀个⼦节点的第⼀个⼦节点
Element childOneOne = ateElement("people");
childOneOne.setAttribute("attr", "peopleOne");
childOneOne.setTextContent("attr peopleOne");
elementChildOne.appendChild(childOneOne);
// 第⼀个⼦节点的第⼆个⼦节点
Element childOneTwo = ateElement("people");
childOneTwo.setAttribute("attr", "peopleTwo");
childOneTwo.setTextContent("attr peopleTwo");
elementChildOne.appendChild(childOneTwo);
// 创建根节点第⼆个⼦节点
Element elementChildTwo = ateElement("person");
elementChildTwo.setAttribute("attr", "personTwo");
element.appendChild(elementChildTwo);
// 第⼆个⼦节点的第⼀个⼦节点
Element childTwoOne = ateElement("people");
childTwoOne.setAttribute("attr", "peopleOne");
childTwoOne.setTextContent("attr peopleOne");
elementChildTwo.appendChild(childTwoOne);
// 第⼆个⼦节点的第⼆个⼦节点
Element childTwoTwo = ateElement("people");
childTwoTwo.setAttribute("attr", "peopleTwo");
childTwoTwo.setTextContent("attr peopleTwo");
elementChildTwo.appendChild(childTwoTwo);
// 添加根节点
doc.appendChild(element);
// 把构造的XML结构,写⼊到具体的⽂件中
TransformerFactory wInstance();
Transformer wTransformer();
// 换⾏
transformer.setOutputProperty(OutputKeys.INDENT, "YES");
// ⽂档字符编码
transformer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
// 可随意指定⽂件的后缀,效果⼀样,但xml⽐较好解析,⽐如: E:\\等
System.out.println("XML CreateDocument success!");
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (TransformerConfigurationException e) {
e.printStackTrace();
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论