5

我即将开发一个基于 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;
}
}

而这个专业(扩展)类“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;
}
}

所以,MyBasicResponse 对象的编组字符串是

{"msg":"A Message."}

(没关系!)

但是,MySpecialResponse 对象的编组字符串就像

{"@type":"MySpecialResponse","msg":"A Message.","moreInfo":"More Information."}

有没有办法剥离

"@type":"MySpecialResponse"

我的回应?

4

1 回答 1

2

您可以将对象包装在JAXBElement指定要编组的子类的实例中,以摆脱类型键。下面是一个完整的例子。

Java 模型

与问题相同,但package-info添加了以下类以指定字段访问以匹配这些类

@XmlAccessorType(XmlAccessType.FIELD)
package com.example.foo;

import javax.xml.bind.annotation.*;

演示代码

演示

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);
    }

}

输出

我们看到,当对象被编组时,一个type键被编组(对应xsi:type于 XML 表示中的属性),因为对于 MOXy 而言,有必要区分MyBasicResponseMySpecialResponse。当我们将对象包装在一个实例中JAXBElement并限定类型 MOXy 时,不需要添加type键。

{
   "type" : "mySpecialResponse"
}
{
}

了解更多信息

于 2011-06-21T14:15:02.253 回答