Преобразование объекта Java в ответ XML REST

Я хочу вернуть ответное сообщение XML после вызова API REST. Я попробовал этот простой тест:

@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);
        }
    .......
}

Я попытался преобразовать простой объект в 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;
    }   
}

Но когда я делаю запрос на отдых, ничего не происходит - никакого ответа. Вы хоть представляете, в чем я ошибаюсь? Должен быть возвращен простой контент.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
4 441
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий
  1. Добавьте производит = "application / xml" внутри @RequestMapping. @RequestMapping(value = "/api", method=RequestMethod.GET, produces=application/xml")
  2. Вам нужно добавить номер Аннотации JAXB к вашему классу bean-компонента (VisaResponseHeader), чтобы его можно было упорядочить в XML.

@XmlRootElement: Эта аннотация используется в классе верхнего уровня для обозначения корневого элемента в документе XML. Атрибут имени в аннотации не является обязательным. Если не указано, имя класса используется в качестве корневого элемента XML в документе.

@XmlAttribute: Эта аннотация используется для указания атрибута корневого элемента.

@XmlElement: Эта аннотация используется для свойств класса, которые будут подэлементами корневого элемента.

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;
        }
    }

Класс VisaResponseHeader.java не нужен.

Ожидаемый результат (проверено с помощью Postman)

@PeterPenzov Попробуйте модифицированный код. Это работает нормально, давая ожидаемый вывод XML

Dharita Chokshi 30.05.2018 15:10

Похоже, у меня неправильная настройка проекта. Могу я попросить вас загрузить свой проект?

Peter Penzov 30.05.2018 15:36

Я загрузил свой образец проекта на github.com/Dharita/Java_object_to_XML_REST_Response. Вы можете его клонировать.

Dharita Chokshi 31.05.2018 08:19

Большое вам спасибо. Если у вас есть время, вы можете показать мне, как я могу добавить аутентификацию и шифрование SSL при общении?

Peter Penzov 31.05.2018 09:51
@XmlRootElement
public class VisaResponseHeader {

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

    public VisaResponseHeader() {
        id = 3;
    }   
}

К сожалению, я снова получаю пустой результат.

Peter Penzov 30.05.2018 12:36

Попробуйте добавить produces = "application/xml" в @RequestMapping. Ваша аннотация должна быть похожа на @RequestMapping(value = "/api", method = RequestMethod.GET,produces = "application/xml").

Наряду с этим вы должны добавить @XmlRootElement(name = "visa") @XmlAccessorType(XmlAccessType.FIELD) к вашему POJO VisaResponse и @XmlElement к каждому элементу, который вы хотите в XML.

Отредактировано:

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;
    }

}

Надеюсь это поможет.

наверное вы имеете в виду класс VisaResponseHeader?

Peter Penzov 30.05.2018 12:56

@PeterPenzov да

pranjal nartam 30.05.2018 13:00
 @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;
}
    }

Другие вопросы по теме