Peter Penzov
Peter Penzov

Reputation: 1712

Convert java object to XML REST response

I want to return XML response message after API REST call. I tried this simple test:

@RestController
public class HelloWorldRestController {

    @Autowired
    ApiService apiService;
    @RequestMapping(value = "/api", method = RequestMethod.GET)
        public ResponseEntity<VisaResponse> listAllUsers() {
            VisaResponse obj = apiService.visaresponse();
            return new ResponseEntity<VisaResponse>(obj, HttpStatus.OK);
        }
    .......
}

I tried to convert simple object to XML

public class VisaResponse {

    public VisaResponse() {
        jaxbObjectToXML(new VisaResponseHeader());
    }

    private static String jaxbObjectToXML(VisaResponseHeader customer) {
        String xmlString = "";
        try {
            JAXBContext context = JAXBContext.newInstance(VisaResponseHeader.class);
            Marshaller m = context.createMarshaller();

            m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); // To format XML

            StringWriter sw = new StringWriter();
            m.marshal(customer, sw);
            xmlString = sw.toString();

        } catch (JAXBException e) {
            e.printStackTrace();
        }
        return xmlString;
    }
}

public class VisaResponseHeader {

    private int id;

    public VisaResponseHeader() {
        id = 3;
    }   
}

But when I make a rest request nothing happens - no any response. Do you have any idea where I'm wrong? Simple content should be returned.

Upvotes: 0

Views: 6930

Answers (4)

Dharita Chokshi
Dharita Chokshi

Reputation: 1263

  1. Add produces = "application/xml" inside the @RequestMapping. @RequestMapping(value="/api", method=RequestMethod.GET, produces=application/xml")
  2. You need to add number of JAXB annotations to your bean class (VisaResponseHeader) to allow it to be marshalled into XML.

@XmlRootElement: This annotation is used at the top level class to indicate the root element in the XML document. The name attribute in the annotation is optional. If not specified, the class name is used as the root XML element in the document.

@XmlAttribute: This annotation is used to indicate the attribute of the root element.

@XmlElement: This annotation is used on the properties of the class which will be the sub-elements of the root element.

HelloWorldRestController .java

@RestController
public class HelloWorldRestController {

    @Autowired
    ApiService apiService;

    @RequestMapping(value = "/api", method = RequestMethod.GET)
    public ResponseEntity<String> listAllUsers() {
        // get data from database
        VisaResponse visaResponse = apiService.visaresponse();

        // convert bean to XML
        String xmlResponse = jaxbObjectToXML(visaResponse);

        return new ResponseEntity<>(xmlResponse, HttpStatus.OK);
    }

    private static String jaxbObjectToXML(VisaResponse customer) {
        String xmlString = "";
        try {
            JAXBContext context = JAXBContext.newInstance(VisaResponse.class);
            Marshaller m = context.createMarshaller();

            m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
            StringWriter sw = new StringWriter();
            m.marshal(customer, sw);
            xmlString = sw.toString();
        } catch (JAXBException e) {
            e.printStackTrace();
        }
        return xmlString;
    }
}

VisaResponse.java

    @XmlRootElement
    @XmlAccessorType(XmlAccessType.FIELD)
    public class VisaResponse {

        @XmlElement
        private int id;

        // for testing purpose. Remove once database integration is done and data is received via service and repository.
        public VisaResponse() {
            id = 3;
        }
    }

No need of VisaResponseHeader.java class.

Expected output(Tested using Postman) enter image description here

Upvotes: 1

Niranga Sandaruwan
Niranga Sandaruwan

Reputation: 711

 @RequestMapping(value = "/api", method = RequestMethod.GET, produces = {
        "application/xml" })
    public ResponseEntity<VisaResponse> listAllUsers() {
        VisaResponse obj = apiService.visaresponse();
        return new ResponseEntity<VisaResponse>(obj, HttpStatus.OK);
    }



    @XmlRootElement
    public class VisaResponse implements Serializable{

        private int id;

        public VisaResponse() {
            id = 3;
        } 
public getId(){
return id;
}  
public setId(int id) {
this.id = id;
}
    }

Upvotes: 0

pranjal nartam
pranjal nartam

Reputation: 13

Try adding produces = "application/xml" inside the @RequestMapping. Your annotation should be like @RequestMapping(value = "/api", method = RequestMethod.GET,produces = "application/xml").

Along with this, you should add @XmlRootElement(name = "visa") @XmlAccessorType(XmlAccessType.FIELD) to your VisaResponse POJO and @XmlElement to each element you want in the XML.

Edited:

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class VisaResponse {

    @XmlElement
    private int visaNumber;

    public int getVisaNumber() {
        return visaNumber;
    }

    public void setVisaNumber(int visaNumber) {
        this.visaNumber = visaNumber;
    }

}

Hope this helps.

Upvotes: 1

user9869525
user9869525

Reputation:

@XmlRootElement
public class VisaResponseHeader {

    @XmlElement(name = "id")
    private int id;

    public VisaResponseHeader() {
        id = 3;
    }   
}

Upvotes: 1

Related Questions