Skip to main content

Transform Object into XML using JAXB (Part 2)

In one of the posts we had seen how to convert Java objects into XML. This was done using JAXB and XSD

What if you don't like to write XSD by hand. Well, you can use any online or offline tools available, to generate the desired XSD from XML. Most of the times the generated XSD will be nearly accurate and you have to hand edit them to make it 100% perfect.

Alright. What if you don't know XSD at all. Is there a simpler way? Yes there is.

Here we are going to use a different approach to achieve exactly the same result that we have got in the old post.

Open Netbeans and create a Java Application
  • File->New Project->Java Application
  • Enter "XMLBinding2" in the Project Name field
  • Click Finish
  • Create the following Java classes

Replace the Java files with the following contents appropriately.

package xmlbinding2;

import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Report {

    private List<Student> students;

    public List<Student> getStudents() {
        return students;
    }

    public void setStudents(List<Student> students) {
        this.students = students;
    }
}

package xmlbinding2;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Student {

    private String name;
    private Marks marks;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Marks getMarks() {
        return marks;
    }

    public void setMarks(Marks marks) {
        this.marks = marks;
    }
}

package xmlbinding2;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Marks {

    private int maths;
    private int physics;
    private int chemistry;
    private int biology;

    public int getMaths() {
        return maths;
    }

    public void setMaths(int maths) {
        this.maths = maths;
    }

    public int getPhysics() {
        return physics;
    }

    public void setPhysics(int physics) {
        this.physics = physics;
    }

    public int getChemistry() {
        return chemistry;
    }

    public void setChemistry(int chemistry) {
        this.chemistry = chemistry;
    }

    public int getBiology() {
        return biology;
    }

    public void setBiology(int biology) {
        this.biology = biology;
    }
}

Create the main class as in the last post, but with slight modification as shown below.

package xmlbinding2;

import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

public class XmlBinding2 {

    public static void main(String[] args) throws JAXBException {
        Report report = new Report();
        List<Student> students = new ArrayList<>();
        Student student = new Student();
        student.setName("Lydia");
        Marks marks = new Marks();
        marks.setMaths(100);
        marks.setPhysics(98);
        marks.setChemistry(85);
        marks.setBiology(93);
        student.setMarks(marks);
        students.add(student);

        student = new Student();
        student.setName("Angel");
        marks = new Marks();
        marks.setMaths(100);
        marks.setPhysics(88);
        marks.setChemistry(95);
        marks.setBiology(94);
        student.setMarks(marks);
        students.add(student);

        report.setStudents(students);

        JAXBContext jaxbContext = JAXBContext.newInstance(Report.class);
        Marshaller marshaller = jaxbContext.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(report, System.out);
    }
}

Run the project. You will see the following output.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<report>
    <students>
        <marks>
            <biology>93</biology>
            <chemistry>85</chemistry>
            <maths>100</maths>
            <physics>98</physics>
        </marks>
        <name>Lydia</name>
    </students>
    <students>
        <marks>
            <biology>94</biology>
            <chemistry>95</chemistry>
            <maths>100</maths>
            <physics>88</physics>
        </marks>
        <name>Angel</name>
    </students>
</report>

There is a little difference between the output that we have got here and in old post. The <student> tag is missing. Let's try to make them same.

Add the following two annotations to the Report.getStudents() method.

    @XmlElementWrapper(name = "students")
    @XmlElement(name = "student")

Your Report.java class will now look like the following.
package xmlbinding2;

import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Report {

    private List<Student> students;

    @XmlElementWrapper(name = "students")
    @XmlElement(name = "student")
    public List<Student> getStudents() {
        return students;
    }

    public void setStudents(List<Student> students) {
        this.students = students;
    }
}

Here is the output.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<report>
    <students>
        <student>
            <marks>
                <biology>93</biology>
                <chemistry>85</chemistry>
                <maths>100</maths>
                <physics>98</physics>
            </marks>
            <name>Lydia</name>
        </student>
        <student>
            <marks>
                <biology>94</biology>
                <chemistry>95</chemistry>
                <maths>100</maths>
                <physics>88</physics>
            </marks>
            <name>Angel</name>
        </student>
    </students>
</report>

Is it same as the old post. Yes it is!

Comments

Popular posts from this blog

Using Nginx as proxy server for Keycloak

I have used Keycloak  in its very early stage ( when it is was in 2.x version). But now it has come a long way (at this time of writing it is in 21.x) In this article let's configure Keycloak behind Nginx. Here are the points to consider.  If you want to configure Apache2 as a proxy server for your java application, please check  this article . We are going to use a domain name other than localhost Anything other than localhost will require Keycloak to run in production mode which requires SSL configurations etc. Or it requires a proxy server. Lets begin. Requirements Keycloak distribution Ubuntu 22.04 server Configuring Keycloak 1. Download Keycloak from here . 2. Extract it using tar -xvzf  keycloak-21.0.1.tar.gz 3. Create a script file called keycloak.sh with the following contents #!/bin/bash export KEYCLOAK_ADMIN=<admin-username-here> export KEYCLOAK_ADMIN_PASSWORD=<admin-password-here> nohup keycloak-21.0.0/bin/kc.sh start-dev --proxy edge --hostname-strict=fa

Installing GoDaddy certificate in Wildfly/Keycloak

In the previous post we saw how to set up Keycloak . Here we will see how to generate and install GoDaddy.com certificate in Keycloak. The steps are similar for Wildfly as well. Step 1: Generate CSR file Run the following commands in your terminal. <mydomain.com> has to be replaced with your actual domain name. keytool -genkey -alias mydomain_com -keyalg RSA -keysize 2048 -keystore mydomain_com.jks keytool -certreq -alias mydomain_com -file mydomain_com.csr -keystore mydomain_com.jks Step 2: Generate certificate Upload  mydomain_com . csr  file content into GoDaddy.com, generate and download certificate for tomcat server (steps to generating SSL certificate is beyond the scope of this article). If you unzip the file, you will see the following files. gd_bundle-g2-g1.crt ..5f8c...3a89.crt   #some file with alphanumeric name gdig2.crt Files 1 and 2 are of our interest. Third file is not required. Step 3: Import certificate to key store Download r

Hibernate & Postgresql

If you are using Hibernate 3.5 or above to talk to Postgresql database, have you ever tried to store a byte array? Let's take an example. Here is the mapping which will store and read byte[] from the database. @Lob @Column(name = "image") private byte[] image; Here is the JPA mapping file configuration. <persistence version="2.0"  xmlns="http://java.sun.com/xml/ns/persistence"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">   <persistence-unit name="testPU" transaction-type="JTA">     <provider>org.hibernate.ejb.HibernatePersistence</provider>     <jta-data-source>test</jta-data-source>     <properties>     </properties>   </persistence-unit> </persistence> When you try to save your entity you will get t

Dynamic SOAP Service Client

If you have written SOAP service client, you might know that you need the WSDL file; need to generate Java code for that,compile that Java classes and add it as dependency for your module. What would you do if you have to incorporate your code with a new SOAP service every now and then? What would you do if all you need is to consume the service and do a little processing on the output, i.e., you need the data in XML format? What would you do if you don't have a complete WSDL? What would you do if your service is in .NET whose WSDL is having problem while generating Java classes? Is there a way to write a dynamic client which can consume any SOAP service? .... YES!... there is a way. Let's quickly write a web (SOAP) service. Software used: Java 7 NetBeans IDE 7.4 GlassFish 4.0 Maven Create a web project and choose Glassfish as server. Now add web service (not a rest service) as below. Edit the SimpleService.java as follows. package com.mycom

How to retry a method call in Spring or Quarkus?

Have you ever come across a situation where you wanted to retry a method invocation automatically? Let's say you are calling a stock ticker service for a given stock and get a transient error. Since it is a transient error, you will try again and it may work in second attempt. But what if it doesn't? Well, you will try third time. But how many times can you try like that? More importantly after how much time will you retry? Imagine if you have a handful of methods like this. Your code will become convoluted with retry logic. Is there a better way? Well, if you are using spring/spring boot, you are in luck. Here is how you can do that using spring. Let's write our business service as follows. import java.time.LocalDateTime; import java.util.concurrent.CompletableFuture; import lombok.extern.slf4j.Slf4j; import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Retryable; import org.springframework.scheduling.annotation.Async; import