The following XML
is what JBPM
spits out for variables used in a process. In other words, it is machine generated. I have tried for several hours to pa
If XML
payload contains recursive structure you need to build similar Java
POJO
model classes. All values could extends the same interface
or abstract class
. Take a look on below example model:
@JsonTypeName("map-type")
class Root {
@JacksonXmlProperty(localName = "entry")
@JacksonXmlElementWrapper(localName = "entries")
private List<Entry> entries;
public List<Entry> getEntries() {
return entries;
}
public void setEntries(List<Entry> entries) {
this.entries = entries;
}
}
@JsonTypeInfo(include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "type", use = JsonTypeInfo.Id.NAME)
@JsonSubTypes({
@JsonSubTypes.Type(name = "xs:string", value = StringType.class),
@JsonSubTypes.Type(name = "jaxbMap", value = MapType.class)
})
interface JBPMValue {
}
class StringType implements JBPMValue {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
@JsonAnySetter
public void anySetter(String key, String value) {
this.value = value.trim();
}
@Override
public String toString() {
return value;
}
}
class MapType implements JBPMValue {
@JacksonXmlProperty(localName = "entry")
@JacksonXmlElementWrapper(localName = "entries")
private List<Entry> entries;
public List<Entry> getEntries() {
return entries;
}
public void setEntries(List<Entry> entries) {
this.entries = entries;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("MapType{");
sb.append(System.lineSeparator());
entries.forEach(e -> sb.append(e.toString()).append(System.lineSeparator()));
sb.append('}');
return sb.toString();
}
}
class Entry {
private String key;
private JBPMValue value;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public JBPMValue getValue() {
return value;
}
public void setValue(JBPMValue value) {
this.value = value;
}
@Override
public String toString() {
return "{" + key + "=" + value + "}";
}
}
As you can see I used @JsonTypeInfo
and @JsonSubTypes
to define POJO
classes for each type in XML
. @JacksonXmlProperty
and @JacksonXmlElementWrapper
annotation are used to represent wrapped collections.
Now, we can create simple example how to use it:
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeName;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import java.io.File;
import java.util.List;
public class XmlMapperApp {
public static void main(String... args) throws Exception {
File xmlFile = new File("./resource/test.xml").getAbsoluteFile();
XmlMapper mapper = XmlMapper.xmlBuilder().build();
Root root = mapper.readValue(xmlFile, Root.class);
root.getEntries().forEach(System.out::println);
}
}
Above code for your XML
payload prints:
{document=MapType{
{org.jbpm.document.service.impl.DocumentImpl=MapType{
{identifier=fc3a87c9-d22c-449b-b772-756fcc9a385d}
{size=1186}
{name=dmv-registration.txt}
{link=fc3a87c9-d22c-449b-b772-756fcc9a385d}
{attributes=null}
{lastModified=Mon Mar 09
18:19:25 PDT 2020}
{content=null}
}}
{uploader_name=murthy}
{uploader_mail=gandikotam@gmail.com}
}}
{initiator=kieserver}