5

I'm about to develop a JAX-RS based RESTful web service and I use MOXy (JAXB) in order to automatically generate my web service's JSON responses.

Everything is cool, but due to the fact that the web service will be the back-end of a JavaScript-based web application and therefore publicly accessible I don't want to expose certain details like class names, etc.

But, I've realized that under certain conditions MOXy embeds a "@type" entry into the marshalled string and this entry is followed by the class name of the object that has just been marshalled.

In particular, I've realized that MOXy behaves in this way when marshalling instances of extended classes.

Assume the following super class "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;
}
}

And this specialized (extended) class "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;
}
}

So, the MyBasicResponse object's marshalled string is

{"msg":"A Message."}

(That's okay!)

But, the MySpecialResponse object's marshalled string is like

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

Is there a way to strip the

"@type":"MySpecialResponse"

out of my response?

Matt Ball
  • 354,903
  • 100
  • 647
  • 710
Philipp T.
  • 51
  • 2

1 Answers1

2

You can wrap your object in an instance of JAXBElement specifying the subclass being marshalled to get rid of the type key. Below is a full example.

Java Model

Same as from the question, but with the following package-info class added to specifying the field access to match those classes

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

import javax.xml.bind.annotation.*;

Demo Code

Demo

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

}

Output

We see that when the object was marshalled an type key was marshalled (corresponding to the xsi:type attribute in the XML representation), because as MOXy is concerned it was necessary to distinguish between MyBasicResponse and MySpecialResponse. When we wrapped the object in an instance of JAXBElement and qualified the type MOXy didn't need to add the type key.

{
   "type" : "mySpecialResponse"
}
{
}

For More Information

bdoughan
  • 147,609
  • 23
  • 300
  • 400
  • How exactly can I hide the @type attribute? I was not able to find it in the release notes. I'm currently using moxy 2.5.1 and I get type instead of type. How can I hide it? – siddhadev Nov 21 '13 at 09:15
  • @siddhadev - Was that down vote from you? Is your use case the same as the one in this question? In not do want to start a new one with some details on your use case? – bdoughan Nov 21 '13 at 10:24
  • yes, down vote was from me! Sorry, but just referring to the release notes, does not answer the question, how to hide the @type field. If referring to release notes, would be an answer, than we could answer all questions like that! – siddhadev Nov 21 '13 at 15:45
  • If you could add an annotation or something that would hide the @type field, I would vote one up! – siddhadev Nov 21 '13 at 15:45
  • @siddhadev - Done. I had to down vote your answer as it would cause people problems on the unmarshalling use case. – bdoughan Nov 21 '13 at 16:25