Reputation: 16631
Using MOXy I'm trying to marshal a java class like this to JSON:
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Request {
String method;
@XmlAnyElement(lax=true)
Object[] arguments;
}
I would expect something like:
{
"method": "test",
"arguments": ["a", "b"]
}
but the JSON output results to:
{
"method": "test",
"value": ["a", "b"]
}
Where is the value
coming from?
If I put a @XmlElementWrapper
over the arguments field, it gets even worse:
{
"method":"test",
"arguments":"a""value":["b"]
}
My JUnit TestCase
looks like this:
import static org.junit.Assert.assertEquals;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.*;
import javax.xml.bind.annotation.*;
import org.junit.Test;
public class JsonRequestTest {
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public static class Request {
String method;
@XmlAnyElement(lax=true)
Object[] arguments;
} // InvocationRequest
@Test
public void testObjectArray() throws JAXBException {
System.setProperty(JAXBContext.class.getName(), "org.eclipse.persistence.jaxb.JAXBContextFactory");
Map<String, Object> props= new HashMap<String, Object>();
props.put("eclipselink.media-type", "application/json");
props.put("eclipselink.json.include-root", false);
JAXBContext ctx = JAXBContext.newInstance(new Class<?>[]{Request.class},props);
Marshaller m = ctx.createMarshaller();
StringWriter writer = new StringWriter();
Request req = new Request();
req.method="test";
req.arguments = new Object[]{"a","b"};
m.marshal(req, writer);
assertEquals("{\"method\":\"test\", \"arguments\":[\"a\",\"b\"]}", writer.toString());
}
} // class JsonRequestTest
Upvotes: 2
Views: 3055
Reputation: 149047
Note: I'm the EclipseLink MOXy lead and a member of the JAXB (JSR-222) expert group.
You can set the following property to override the value
key.
props.put(MarshallerProperties.JSON_VALUE_WRAPPER, "arguments");
Below is the full working test case. In addition to setting the property I removed an extra space you had in your control document to get the test to pass.
import static org.junit.Assert.assertEquals;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.*;
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.jaxb.MarshallerProperties;
import org.junit.Test;
public class JsonRequestTest {
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public static class Request {
String method;
@XmlAnyElement(lax = true)
Object[] arguments;
} // InvocationRequest
@Test
public void testObjectArray() throws JAXBException {
System.setProperty(JAXBContext.class.getName(),
"org.eclipse.persistence.jaxb.JAXBContextFactory");
Map<String, Object> props = new HashMap<String, Object>();
props.put("eclipselink.media-type", "application/json");
props.put("eclipselink.json.include-root", false);
props.put(MarshallerProperties.JSON_VALUE_WRAPPER, "arguments");
JAXBContext ctx = JAXBContext.newInstance(
new Class<?>[] { Request.class }, props);
Marshaller m = ctx.createMarshaller();
StringWriter writer = new StringWriter();
Request req = new Request();
req.method = "test";
req.arguments = new Object[] { "a", "b" };
m.marshal(req, writer);
assertEquals("{\"method\":\"test\",\"arguments\":[\"a\",\"b\"]}",
writer.toString());
}
} // class JsonRequestTest
@XmlElementWrapper
IssueI have opened the following bug for the issue with @XmlElementWrapper
:
Upvotes: 1