CXF JSONProvider 编组导致无法将类型 "java.lang.String" 编组为元素,因为它缺少 @XmlRootElement 注释
CXF JSONProvider marshalling causes unable to marshal type "java.lang.String" as an element because it is missing an @XmlRootElement annotation
我正尝试在 org.apache.cxf.jaxrs.provider.json.JSONProvider 上编写测试。
我只需要显示给定 class 的 JSON 表示。
我知道还有其他 JSON 提供商,例如 Jackson,但对于此测试,它需要来自 cxf 的提供商。
如果我运行下面测试
package be.axi.jackson;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.core.MediaType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import org.apache.cxf.jaxrs.impl.MetadataMap;
import org.apache.cxf.jaxrs.provider.json.JSONProvider;
import org.junit.Assert;
import org.junit.Test;
public class JacksonTest {
@XmlRootElement(name = "Simple", namespace = "be.axi.test")
static class Simple {
@XmlElement(name = "values")
@XmlElementWrapper(name = "data")
protected List<String> _list;
public List<String> getList() {
return _list;
}
public void setList(List<String> l) {
_list = l;
}
}
@Test
public void testCxf() throws IOException {
JSONProvider<Object> jsonProvider = new JSONProvider<Object>();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
List<String> l = new ArrayList<String>();
l.add("foo");
l.add("bar");
Simple s = new Simple();
s.setList(l);
jsonProvider.writeTo(l, Simple.class, Simple.class.getAnnotations(), MediaType.APPLICATION_JSON_TYPE, null, bos);
String expected = "{\"data\":{\"values\":[\"foo\"]}}";
Assert.assertEquals(expected, bos.toString());
}
}
我明白了
feb 02, 2017 9:47:19 AM org.apache.cxf.jaxrs.provider.AbstractJAXBProvider handleJAXBException
WARNING: javax.xml.bind.MarshalException
- with linked exception:
[com.sun.istack.SAXException2: unable to marshal type "java.lang.String" as an element because it is missing an @XmlRootElement annotation]
我该如何解决这个问题?
我真的只需要从 org.apache.cxf.jaxrs 实现中获取 Simple.class 的 JSON 表示。
谢谢
您正在向 jsonProvider.writeTo(l,
提供 List<String> l
实例而不是 Simple
。更改为 s
jsonProvider.writeTo(s, Simple.class, Simple.class.getAnnotations(), MediaType.APPLICATION_JSON_TYPE, null, bos);
要获得预期的输出,请添加
jsonProvider.setDropRootElement(true);
并将属性的@XmlElement
和@XmlElementWrapper
改为getter。这将是代码
package be.axi.jackson;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.core.MediaType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import org.apache.cxf.jaxrs.provider.json.JSONProvider;
import org.junit.Assert;
import org.junit.Test;
public class JettisonTest {
@XmlRootElement(name = "Simple", namespace = "be.axi.test")
static class Simple {
protected List<String> _list;
@XmlElement(name = "values")
@XmlElementWrapper(name = "data")
public List<String> getList() {
return _list;
}
public void setList(List<String> l) {
_list = l;
}
}
@Test
public void testCxf() throws IOException {
JSONProvider<Object> jsonProvider = new JSONProvider<Object>();
jsonProvider.setDropRootElement(true);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
List<String> l = new ArrayList<String>();
l.add("foo");
l.add("bar");
Simple s = new Simple();
s.setList(l);
jsonProvider.writeTo(s, Simple.class, Simple.class.getAnnotations(), MediaType.APPLICATION_JSON_TYPE, null, bos);
String res = bos.toString();
String expected = "{\"data\":{\"values\":[\"foo\",\"bar\"]}}";
Assert.assertEquals(expected, res);
}
}
请注意,您使用的是 CXF 的默认 JSON 实现,即 Jettison,而不是 jackson
我正尝试在 org.apache.cxf.jaxrs.provider.json.JSONProvider 上编写测试。 我只需要显示给定 class 的 JSON 表示。 我知道还有其他 JSON 提供商,例如 Jackson,但对于此测试,它需要来自 cxf 的提供商。
如果我运行下面测试
package be.axi.jackson;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.core.MediaType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import org.apache.cxf.jaxrs.impl.MetadataMap;
import org.apache.cxf.jaxrs.provider.json.JSONProvider;
import org.junit.Assert;
import org.junit.Test;
public class JacksonTest {
@XmlRootElement(name = "Simple", namespace = "be.axi.test")
static class Simple {
@XmlElement(name = "values")
@XmlElementWrapper(name = "data")
protected List<String> _list;
public List<String> getList() {
return _list;
}
public void setList(List<String> l) {
_list = l;
}
}
@Test
public void testCxf() throws IOException {
JSONProvider<Object> jsonProvider = new JSONProvider<Object>();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
List<String> l = new ArrayList<String>();
l.add("foo");
l.add("bar");
Simple s = new Simple();
s.setList(l);
jsonProvider.writeTo(l, Simple.class, Simple.class.getAnnotations(), MediaType.APPLICATION_JSON_TYPE, null, bos);
String expected = "{\"data\":{\"values\":[\"foo\"]}}";
Assert.assertEquals(expected, bos.toString());
}
}
我明白了
feb 02, 2017 9:47:19 AM org.apache.cxf.jaxrs.provider.AbstractJAXBProvider handleJAXBException
WARNING: javax.xml.bind.MarshalException
- with linked exception:
[com.sun.istack.SAXException2: unable to marshal type "java.lang.String" as an element because it is missing an @XmlRootElement annotation]
我该如何解决这个问题? 我真的只需要从 org.apache.cxf.jaxrs 实现中获取 Simple.class 的 JSON 表示。
谢谢
您正在向 jsonProvider.writeTo(l,
提供 List<String> l
实例而不是 Simple
。更改为 s
jsonProvider.writeTo(s, Simple.class, Simple.class.getAnnotations(), MediaType.APPLICATION_JSON_TYPE, null, bos);
要获得预期的输出,请添加
jsonProvider.setDropRootElement(true);
并将属性的@XmlElement
和@XmlElementWrapper
改为getter。这将是代码
package be.axi.jackson;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.core.MediaType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import org.apache.cxf.jaxrs.provider.json.JSONProvider;
import org.junit.Assert;
import org.junit.Test;
public class JettisonTest {
@XmlRootElement(name = "Simple", namespace = "be.axi.test")
static class Simple {
protected List<String> _list;
@XmlElement(name = "values")
@XmlElementWrapper(name = "data")
public List<String> getList() {
return _list;
}
public void setList(List<String> l) {
_list = l;
}
}
@Test
public void testCxf() throws IOException {
JSONProvider<Object> jsonProvider = new JSONProvider<Object>();
jsonProvider.setDropRootElement(true);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
List<String> l = new ArrayList<String>();
l.add("foo");
l.add("bar");
Simple s = new Simple();
s.setList(l);
jsonProvider.writeTo(s, Simple.class, Simple.class.getAnnotations(), MediaType.APPLICATION_JSON_TYPE, null, bos);
String res = bos.toString();
String expected = "{\"data\":{\"values\":[\"foo\",\"bar\"]}}";
Assert.assertEquals(expected, res);
}
}
请注意,您使用的是 CXF 的默认 JSON 实现,即 Jettison,而不是 jackson