如何使用jaxb注释使用Jersey将json解组为java bean时使用一些间接 [英] how to use some indirection when unmarshalling json to java bean using Jersey using jaxb annotations
问题描述
我正在尝试解散一些收到的json(来自Jira restful web service)。
I'm trying to unmarshall some received json (from Jira restful web service).
问题是:问题有一个摘要属性和一个字段列表。
Problem is: an "issue" has a "summary" property and a list of fields.
摘要在接收的json中不作为属性存在,而是作为fields属性的值。我坚持要对这个结构进行解组:
Summary is not present as an attribute in the received json, but as a value of the "fields" attribute. I insist on unmarshalling to this structure:
@XmlRootElement
class Issue {
String summary;
List<Field> fields;
// getters/setters and lots of other fields
}
收到JSON :
{
"expand":"html",
"self":"https://example.com/jira/rest/api/latest/issue/XYZ-1234",
"key":"XYZ-1234",
"fields":
{
"summary":
{
"name":"summary",
"type":"java.lang.String",
"value":"test 1234"
},
"customfield_10080":
{
"name":"Testeur",
"type":"com.atlassian.jira.plugin.system.customfieldtypes:userpicker"
},
"status":
{
"name":"status",
"type":"com.atlassian.jira.issue.status.Status",
"value":
{
"self":"https://example.com/jira/rest/api/latest/status/5",
"name":"Resolved"
}
},
...
},
"transitions":"https://example.com/jira/rest/api/latest/issue/XYZ-1234/transitions"
}
我不想使用Jira自己的客户端(我的应用程序中不需要太多依赖项) 。
I don't want to use Jira's own client (too many dependencies which I don't want in my app).
编辑:我问我的问题另一种方法,试图说清楚:如何使用jax-rs将bean结构映射到不同的模式
edit: I asked my question another way to try to make it clear: how to map a bean structure to a different schema with jax-rs
推荐答案
您的带注释的类应该是双射的:它应允许生成相同的输入被解散了。如果您仍想使用非双射对象图,可以使用 @XmlAnyElement
,方法如下:
Your annotated class should be bijective: it should allow to generate the same input from which it was unmarshalled. If you still want to use a non-bijective object graph, you can use @XmlAnyElement
the following way:
public class Issue {
@XmlElement(required = true)
protected Fields fields;
public Fields getFields() {
return fields;
}
}
在您提供的输入中,字段不是列表,但是一个字段(JSON使用[]来分隔列表):
In the input you gave, fields is not a list, but a field (JSON uses [] to delimit lists):
public class Fields {
@XmlElement(required = true)
protected Summary summary;
@XmlAnyElement
private List<Element> fields;
public List<Element> getFields() {
return fields;
}
public Summary getSummary() {
return summary;
}
}
为了捕捉摘要,你必须定义一个专门的类。剩余字段将分组在字段
元素列表中。
In order to catch Summary, you'll have to define a dedicated class. Remaining fields will be grouped in the fields
list of elements.
public class Summary {
@XmlAttribute
protected String name;
public String getName() {
return name;
}
}
下面,使用您输入的单元测试显示一切work:
Below, a unit test using your input shows that everything work:
public class JaxbTest {
@Test
public void unmarshal() throws JAXBException, IOException {
URL xmlUrl = Resources.getResource("json.txt");
InputStream stream = Resources.newInputStreamSupplier(xmlUrl).getInput();
Issue issue = parse(stream, Issue.class);
assertEquals("summary", issue.getFields().getSummary().getName());
Element element = issue.getFields().getFields().get(0);
assertEquals("customfield_10080", element.getTagName());
assertEquals("name", element.getFirstChild().getLocalName());
assertEquals("Testeur", element.getFirstChild().getFirstChild().getTextContent());
}
private <T> T parse(InputStream stream, Class<T> clazz) throws JAXBException {
JSONUnmarshaller unmarshaller = JsonContextNatural().createJSONUnmarshaller();
return unmarshaller.unmarshalFromJSON(stream, clazz);
}
private JSONJAXBContext JsonContextNatural() throws JAXBException {
return new JSONJAXBContext(JSONConfiguration.natural().build(), Issue.class);
}
}
此测试显示不使用专用类,代码很快就会难以阅读。
This tests shows that without using dedicated classes, your code will quickly be hard to read.
您将需要这些maven依赖项来运行它:
You will need those maven dependencies to run it:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>r08</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.6</version>
</dependency>
这篇关于如何使用jaxb注释使用Jersey将json解组为java bean时使用一些间接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!