JSON and XML not matching

238 views Asked by At

I am building a REST API and need to return JSON and XML. I am using Jersey to build the REST API.

Here are my model classes:

import java.util.List;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Certificate {
    private Student student;
    private List<Grade> grades;

    public Certificate() {

    }

    public Student getStudent() {
        return student;
    }

    public void setStudent(Student student) {
        this.student = student;
    }

    public List<Grade> getGrades() {
        return grades;
    }

    public void setGrades(List<Grade> grades) {
        this.grades = grades;
    }
}

-

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Student {
private int id;
private String name;
private String surname;

public Student(){

}

public Student(int id, String name, String surname) {
    this.id = id;
    this.name = name;
    this.surname = surname;
}

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getName() {
    return name;
}

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

public String getSurname() {
    return surname;
}

public void setSurname(String surname) {
    this.surname = surname;
}
}

-

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Grade {
private String subject;
private String mark;

public Grade(){

}

public Grade(String subject, String mark) {
    this.subject = subject;
    this.mark = mark;
}

public String getSubject() {
    return subject;
}

public void setSubject(String subject) {
    this.subject = subject;
}

public String getMark() {
    return mark;
}

public void setMark(String mark) {
    this.mark = mark;
}
}

And here's the REST end point:

import java.util.ArrayList;
import java.util.List;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.hoxha.test.test.Certificate;
import org.hoxha.test.test.Grade;
import org.hoxha.test.test.Student;

@Path("certs")
public class CertificateResource {

@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getCertJson() {
    Certificate cert = getCertificate();
    return Response.ok(cert, MediaType.APPLICATION_JSON).build();
}

private Certificate getCertificate() {
    Certificate cert = new Certificate();
    Student student = new Student(1, "John", "Doe");
    cert.setStudent(student);
    List<Grade> grades = new ArrayList<>();
    grades.add(new Grade("Algorithms", "A"));
    grades.add(new Grade("OOP", "B"));
    grades.add(new Grade("English", "C"));
    cert.setGrades(grades);
    return cert;
}

@GET
@Produces(MediaType.APPLICATION_XML)
public Response getCertXml() {
    Certificate cert = getCertificate();
    return Response.ok(cert, MediaType.APPLICATION_XML).build();
}

}

When I return JSON it works fine. Grades are returned as a proper JSON array. Here's the result:

{
  "grades": [
  {
    "mark": "A",
    "subject": "Algorithms"
  },
  {
    "mark": "B",
    "subject": "OOP"
  },
  {
    "mark": "C",
    "subject": "English"
  }
],
 "student": {
   "id": 1,
   "name": "John",
   "surname": "Doe"
  }
}

How can I get this result in XML format:

<certificate>
  <grades>     
    <grade>
        <mark>A</mark>
        <subject>Algorithms</subject>
    </grade>
    <grade>
        <mark>B</mark>
        <subject>OOP</subject>
    </grade>
    <grade>
        <mark>C</mark>
        <subject>English</subject>
    </grade>
  </grades>
  <student>
      <id>1</id>
      <name>John</name>
      <surname>Doe</surname>
  </student>
</certificate>

The result I'm getting is:

<certificate>
<grades>
    <mark>A</mark>
    <subject>Algorithms</subject>
</grades>
<grades>
    <mark>B</mark>
    <subject>OOP</subject>
</grades>
<grades>
    <mark>C</mark>
    <subject>English</subject>
</grades>
<student>
    <id>1</id>
    <name>John</name>
    <surname>Doe</surname>
</student>
</certificate>

If I fix XML, let's say I add a Grades object which contains a List of Grade objects, then I get an extra (unnecessary) JSON object.

Is there a solution this?

2

There are 2 answers

0
Turik Mirash On BEST ANSWER

@NullPointerException, thanks a lot! You gave me a good hint.

I solved it by adding the @XmlElementWrapper(name="grades") and @XmlElement(name="grade") to the getGrades() method.

@XmlElementWrapper(name = "grades")
@XmlElement(name = "grade")
public List<Grade> getGrades() {
    return grades;
}
2
NullPointerException On

Use @XmlElementWrapper(name = "grades") to your Certificate class

@XmlRootElement
public class Certificate {
private Student student;
@XmlElementWrapper(name = "grades")
private List<Grade> grade;