大家好,又见面了,我是你们的朋友全栈君。
前言:对于服务器后端开发,接口返回的数据格式一般要求都是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 中javax.xml.transform.Source定义的数据;
- Jaxb2RootElementHttpMessageConverter: 负责读取和写入xml 标签格式的数据;
- AtomFeedHttpMessageConverter: 负责读取和写入Atom格式的数据;
- RssChannelHttpMessageConverter: 负责读取和写入RSS格式的数据
具体使用哪个怎么判断这里就不细讲了,我们关心的是Jaxb2RootElementHttpMessageConverter这个方法,后面会讲为啥会提
java对象与xml之间互相转换
使用Java自带注解的方式实现(@XmlRootElement,@XmlAccessorType,@XmlElement,@XmlAttribute),具体使用方法网上有很多
这里直接代码举例
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.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;
}
}
请求http://localhost:8080/get 返回结果如下
是不很容易就实现接口返回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默认会把字符’<’, ‘>’进行转义, 下面解决这个问题
我们使用org.eclipse.persistence.oxm.annotations.XmlCDATA注解来解决
使用EclipseLink JAXB (MOXy)
pom文件增加
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.moxy</artifactId>
<version>xx版本</version>
</dependency>
上一节中的属性使用注解
...
import org.eclipse.persistence.oxm.annotations.XmlCDATA;
...
...
@XmlCDATA
@XmlElement
public void setProvince(String province) {
this.province = province;
}
注意:一定要设置jaxb.properties文件,并且要放在要转换成xml的java对象所在目录,并且要编译到target中,不然XmlCDATA注解不生效
jaxb.properties文件内容,就是指定创建JAXBContext对象的工长
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
到这里配置完成
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/162512.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...