Phi*_* T. 5 json jax-rs jaxb eclipselink moxy
我即将开发基于JAX-RS的RESTful Web服务,我使用MOXy(JAXB)来自动生成我的Web服务的JSON响应.
一切都很酷,但由于Web服务将成为基于JavaScript的Web应用程序的后端,因此可公开访问,我不希望暴露某些细节,如类名等.
但是,我已经意识到在某些条件下MOXy在编组的字符串中嵌入了一个"@type"条目,这个条目后面跟着刚被编组的对象的类名.
特别是,我已经意识到MOXy在编组扩展类的实例时会以这种方式运行.
假设以下超类"MyBasicResponse"
@XmlRootElement(name="res")
public class MyBasicResponse {
@XmlElement
private String msg;
public MyBasicResponse() {
// Just for conformity
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
Run Code Online (Sandbox Code Playgroud)
而这个专门(扩展)类"MySpecialResponse"
@XmlRootElement(name="res")
public class MySpecialResponse extends MyBasicResponse {
@XmlElement
private String moreInfo;
public MySpecialResponse() {
// Just for conformity
}
public String getMoreInfo() {
return moreInfo;
}
public void setMoreInfo(String moreInfo) {
this.moreInfo = moreInfo;
}
}
Run Code Online (Sandbox Code Playgroud)
所以,MyBasicResponse对象的编组字符串是
{"msg":"A Message."}
Run Code Online (Sandbox Code Playgroud)
(没关系!)
但是,MySpecialResponse对象的编组字符串就像
{"@type":"MySpecialResponse","msg":"A Message.","moreInfo":"More Information."}
Run Code Online (Sandbox Code Playgroud)
有没有办法剥夺
"@type":"MySpecialResponse"
Run Code Online (Sandbox Code Playgroud)
出于我的回应?
您可以将对象包装在指定要编组的子类的实例中,JAXBElement以摆脱类型键。下面是一个完整的例子。
与问题相同,但package-info添加了以下类来指定字段访问以匹配这些类
@XmlAccessorType(XmlAccessType.FIELD)
package com.example.foo;
import javax.xml.bind.annotation.*;
Run Code Online (Sandbox Code Playgroud)
演示
import java.util.*;
import javax.xml.bind.*;
import javax.xml.namespace.QName;
import org.eclipse.persistence.jaxb.JAXBContextProperties;
public class Demo {
public static void main(String[] args) throws Exception {
Map<String, Object> properties = new HashMap<String, Object>(2);
properties.put(JAXBContextProperties.MEDIA_TYPE, "application/json");
properties.put(JAXBContextProperties.JSON_INCLUDE_ROOT, false);
JAXBContext jc = JAXBContext.newInstance(new Class[] {MySpecialResponse.class}, properties);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
MySpecialResponse msr = new MySpecialResponse();
marshaller.marshal(msr, System.out);
JAXBElement<MySpecialResponse> jaxbElement = new JAXBElement(new QName(""), MySpecialResponse.class, msr);
marshaller.marshal(jaxbElement, System.out);
}
}
Run Code Online (Sandbox Code Playgroud)
输出
我们看到,当对象被编组时,一个type键被编组(对应于xsi:typeXML 表示中的属性),因为对于 MOXy 而言,有必要区分MyBasicResponse和MySpecialResponse。当我们将对象包装在 的实例中JAXBElement并限定类型 MOXy 时,不需要添加密钥type。
{
"type" : "mySpecialResponse"
}
{
}
Run Code Online (Sandbox Code Playgroud)