Serialização e desserialização de XML com Jackson
1. Visão geral
Neste tutorial, vamos dar uma olhada emhow to serialize Java objects to XML data using Jackson 2.x and deserialize it back to a POJO.
Vamos nos concentrar na operação básica que não requer muita complexidade ou personalização.
2. XmlMapper Objeto
XmlMapper é a classe principal do Jackson 2.x que nos ajuda na serialização, portanto, precisaremos criar uma instância dela:
XmlMapper mapper = new XmlMapper();
Estemapper está disponível no jarjackson-dataformat-xml, então temos que adicioná-lo como uma dependência ao nossopom.xml:
com.fasterxml.jackson.dataformat
jackson-dataformat-xml
2.9.8
Verifiquethe latest version of Jackson dependency aqui.
3. Serializar Java para XML
XmlMapper é uma subclasse deObjectMapper que é usada na serialização JSON. No entanto, ele adiciona alguns ajustes específicos de XML à classe pai.
Agora podemos ver como usá-lo para fazer a serialização real. Vamos criar uma classe Java primeiro:
class SimpleBean {
private int x = 1;
private int y = 2;
//standard setters and getters
}
3.1. Serializar para XMLString
Podemos serializar nosso objeto Java no XMLString:
@Test
public void whenJavaSerializedToXmlStr_thenCorrect() throws JsonProcessingException {
XmlMapper xmlMapper = new XmlMapper();
String xml = xmlMapper.writeValueAsString(new SimpleBean());
assertNotNull(xml);
}
Como resultado, obteremos:
1
2
3.2. Serializar para o arquivo XML
Também podemos serializar nosso objeto Java no arquivo XML:
@Test
public void whenJavaSerializedToXmlFile_thenCorrect() throws IOException {
XmlMapper xmlMapper = new XmlMapper();
xmlMapper.writeValue(new File("simple_bean.xml"), new SimpleBean());
File file = new File("simple_bean.xml");
assertNotNull(file);
}
E abaixo podemos ver o conteúdo do arquivo resultante denominadosimple_bean.xml:
1
2
4. Desserializar XML para Java
Nesta seção, veremos como obter objetos Java de XML.
4.1. Desserializar da string XML
Assim como na serialização, também podemos desserializar uma String XML de volta para um objeto Java:
@Test
public void whenJavaGotFromXmlStr_thenCorrect() throws IOException {
XmlMapper xmlMapper = new XmlMapper();
SimpleBean value
= xmlMapper.readValue("1 2 ", SimpleBean.class);
assertTrue(value.getX() == 1 && value.getY() == 2);
}
4.2. Desserializar do arquivo XML
Da mesma forma, se tivermos um arquivo XML, podemos convertê-lo novamente em um objeto Java.
Aqui, primeiro lemos o arquivo em um fluxo de entrada e depois convertemos o fluxo de entrada emString com um método utilitário simples.
O restante do código é semelhante ao da seção 4.1:
@Test
public void whenJavaGotFromXmlFile_thenCorrect() throws IOException {
File file = new File("simple_bean.xml");
XmlMapper xmlMapper = new XmlMapper();
String xml = inputStreamToString(new FileInputStream(file));
SimpleBean value = xmlMapper.readValue(xml, SimpleBean.class);
assertTrue(value.getX() == 1 && value.getY() == 2);
}
O método utilitário:
public String inputStreamToString(InputStream is) throws IOException {
StringBuilder sb = new StringBuilder();
String line;
BufferedReader br = new BufferedReader(new InputStreamReader(is));
while ((line = br.readLine()) != null) {
sb.append(line);
}
br.close();
return sb.toString();
}
5. Manipulação de elementos em maiúsculas
Nesta seção, veremos como lidar com cenários em que temos XML com elementos em maiúsculas para desserializar ou precisamos serializar objetos Java para XML com um ou mais elementos em maiúsculas.
5.1. Desserializar do XMLString
Digamos que temos um XML com um campo em maiúscula:
1
2
Para lidar corretamente com os elementos capitalizados, precisamos anotar o campo “x” com a anotação@JsonProperty:
class SimpleBeanForCapitalizedFields {
@JsonProperty("X")
private int x = 1;
private int y = 2;
// standard getters, setters
}
Agora podemos desserializar corretamente um XMLString de volta para um objeto Java:
@Test
public void whenJavaGotFromXmlStrWithCapitalElem_thenCorrect() throws IOException {
XmlMapper xmlMapper = new XmlMapper();
SimpleBeanForCapitalizedFields value
= xmlMapper.readValue(
"1 2 ",
SimpleBeanForCapitalizedFields.class);
assertTrue(value.getX() == 1 && value.getY() == 2);
}
5.2. Serializar para a string XML
Anotando os campos obrigatórios com@JsonProperty,, podemos serializar corretamente um objeto Java em um XMLString com um ou mais elementos em maiúsculas:
@Test
public void whenJavaSerializedToXmlFileWithCapitalizedField_thenCorrect()
throws IOException {
XmlMapper xmlMapper = new XmlMapper();
xmlMapper.writeValue(new File("target/simple_bean_capitalized.xml"),
new SimpleBeanForCapitalizedFields());
File file = new File("target/simple_bean_capitalized.xml");
assertNotNull(file);
}
6. Serialize List to XML
OXmlMapper é capaz de serializar um Java bean inteiro em um documento. Para converter o objeto Java em XML, vamos dar um exemplo simples com o objeto aninhado e matrizes.
Nossa intenção é serializar um objetoPerson, junto com seu objetoAddress composto, em XML.
Nosso XML final será parecido com:
Rohan
Daye
9911034731
9911033478
Name1
City1
Name2
City2
Observe que nossos números de telefone estão encapsulados em um wrapperphoneNumbers, enquanto nosso endereço não está.
Podemos expressar essa nuance por meio da anotação@JacksonXMLElementWrapper em nossa classePerson:
public final class Person {
private String firstName;
private String lastName;
private List phoneNumbers = new ArrayList<>();
@JacksonXmlElementWrapper(useWrapping = false)
private List address = new ArrayList<>();
//standard setters and getters
}
Na verdade, podemos alterar o nome do elemento de empacotamento com@JacksonXmlElementWrapper(localName = ‘phoneNumbers'). Ou, se não quisermos encapsular nossos elementos, podemos desabilitar o mapeamento com@JacksonXmlElementWrapper(useWrapping = false).
E então vamos definir nosso tipoAddress :
public class Address {
String streetName;
String city;
//standard setters and getters
}
Jackson takes care of the rest for us. Como antes, podemos simplesmente chamarwriteValue novamente:
private static final String XML = "... ";
@Test
public void whenJavaSerializedToXmlFile_thenSuccess() throws IOException {
XmlMapper xmlMapper = new XmlMapper();
Person person = testPerson(); // test data
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
xmlMapper.writeValue(byteArrayOutputStream, person);
assertEquals(XML, byteArrayOutputStream.toString());
}
7. Desserializar XML paraList
Jackson também pode ler XML que contém listas de objetos.
Se pegarmos nosso mesmo XML de antes, o métodoreadValue funciona perfeitamente:
@Test
public void whenJavaDeserializedFromXmlFile_thenCorrect() throws IOException {
XmlMapper xmlMapper = new XmlMapper();
Person value = xmlMapper.readValue(XML, Person.class);
assertEquals("City1", value.getAddress().get(0).getCity());
assertEquals("City2", value.getAddress().get(1).getCity());
}
8. Conclusão
Este artigo simples ilustrou como serializar um POJO simples para XML e obter um POJO a partir de dados XML básicos.
Também analisamos como serializar e desserializar beans complexos que contêm coleções.
O código-fonte que acompanha este artigo está disponível emGitHub.