The XML output contains the wrapper "credentials" altough I excluded it with defaultUseWrapper(false).
UserDAO
public class UserDAO {
@JacksonXmlProperty(isAttribute = true)
private int id;
private Credentials credentials;
@JacksonXmlProperty(localName = "todos")
private TasksDAO tasks;
// getter, setter
}
Credentials
public class Credentials {
@JacksonXmlProperty(localName = "name")
@JsonProperty("name")
private String username;
private String password;
// getter, setter
}
XmlWrapper config
XmlMapper
.builder()
.defaultUseWrapper(false)
.addModule(new JavaTimeModule())
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.build()
XML output
<users>
<user id="1">
<credentials>
<password>123</password>
<name>Steve</name>
</credentials>
<todos/>
</user>
</users>
My goal is to have it flat with user and password. How should I do to remove the wrapper credentials?
Desired Output
<users>
<user id="1">
<password>123</password>
<name>Steve</name>
<todos/>
</user>
</users>
Dirty Solution
package org.example;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator;
import java.io.IOException;
public class UserDAOSerializer extends StdSerializer<UserDAO> {
public UserDAOSerializer() {
this(null);
}
public UserDAOSerializer(Class<UserDAO> t) {
super(t);
}
@Override
public void serialize(UserDAO value, JsonGenerator gen, SerializerProvider provider) throws IOException {
Object jsonGenerator;
if (gen instanceof ToXmlGenerator) {
final ToXmlGenerator xmlGenerator = (ToXmlGenerator) gen;
gen.writeStartObject();
xmlGenerator.setNextIsAttribute(true);
gen.writeStringField("id",String.valueOf(value.getId()));
xmlGenerator.setNextIsAttribute(false);
gen.writeStringField("password",value.getCredentials().getPassword());
gen.writeStringField("name",value.getCredentials().getUsername());
gen.writeEndObject();
} else {
//TODO JSON MAPPING
}
}
}
package org.example;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
@JsonSerialize(using = UserDAOSerializer.class)
public class UserDAO {
@JacksonXmlProperty(isAttribute = true)
private int id;
private Credentials credentials;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Credentials getCredentials() {
return credentials;
}
public void setCredentials(Credentials credentials) {
this.credentials = credentials;
}
}
package org.example;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
public class Main2 {
public static void main(String[] args) throws JsonProcessingException {
Credentials c1=new Credentials();
c1.setUsername("Steve");
c1.setPassword("123");
UserDAO u1=new UserDAO();
u1.setId(1);
u1.setCredentials(c1);
XmlMapper xmlMapper = new XmlMapper();
String s2=xmlMapper.writeValueAsString(u1);
System.out.println(s2);
}
}
package org.example;
import com.fasterxml.jackson.annotation.JsonProperty;
public class Credentials {
// @JacksonXmlProperty(localName = "name")
@JsonProperty("name")
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
<UserDAO id="1">
<password>123</password>
<name>Steve</name>
</UserDAO>
Jackson: Registering a custom XML serializer for Map data structure
@Bender answer
I know this is not exactly what you asked for, this is just a POC.
I think you can handle others.
I hope this answer can solve your problem.