Запрос Spring для возврата ответа json ИЛИ xml

У меня есть сопоставление запросов Spring, которое я хотел бы вернуть по умолчанию в формате XML или JSON, если он указан в заголовке запроса. Вот код:

Запросить сопоставление

@RequestMapping(value = "/batch/{progName}", method = RequestMethod.GET, produces = "application/xml)
    public ResponseEntity<JobResults> processTestObject(@PathVariable("progName") String progName,
                                                        @RequestHeader("Content-Type") String contentType) throws Exception {
        HttpHeaders responseHeaders = MccControllerUtils.createCacheDisabledHeaders();
        if (contentType.equals("application/json")) {
            responseHeaders.setContentType(MediaType.APPLICATION_JSON);
        }
        LOGGER.info("Running batch program " + progName);
        JobResults response = batchService.processProgName(progName);
        return new ResponseEntity<JobResults>(response, responseHeaders, HttpStatus.OK);
    }
  • Используя Postman без заголовков, когда я попадаю в эту конечную точку, я получаю Код состояния 400 Bad Request.
  • В поле заголовков почтальона, если я укажу Content-Type как application/xml Я получаю правильный ответ XML.
  • Если я укажу Content-Type как application/json, я получаю сообщение об ошибке сзади: Unexpected '<'

Что я хочу:

Чтобы вернуть XML по умолчанию из конечной точки и вернуть JSON, если он указан в запросе

РЕДАКТИРОВАТЬ

На данный момент запрос возвращает 400 Bad Request, если в Postman нет отправленных Accept или Content-Type. Чтобы получить желаемый ответ, я должен указать Accept и Content-Type для application/xml.

 @RequestMapping(value = "/batch/{progName}", method = RequestMethod.GET)
    public ResponseEntity<JobResults> processTestObject(@PathVariable("progName") String progName,
                                                        @RequestHeader("Content-Type") MediaType contentType) throws Exception {
        HttpHeaders responseHeaders = MccControllerUtils.createCacheDisabledHeaders();
        responseHeaders.setContentType(MediaType.APPLICATION_XML);
        if (!contentType.toString().equals("*/*")) {
            responseHeaders.setContentType(contentType);
        }
        LOGGER.info("Running batch program " + progName);
        JobResults response = batchService.processProgName(progName);
        return new ResponseEntity<JobResults>(response, responseHeaders, HttpStatus.OK);
    }
Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
0
0
963
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваш пример по-прежнему берет Content-Type из запроса, где это должно быть Accept. Во-вторых, убедитесь, что ваш объект JobResults может быть сериализован как json marshaller, так и xml marshaller. В-третьих, если вы хотите, чтобы при запросе json было определенное поведение, вы должны проверить этот конкретный тип носителя, а не общий, например "*/*".

Контроллер:

@RequestMapping(value = "/batch/{progName}", method = RequestMethod.GET)
public ResponseEntity<JobResults> processTestObject(@PathVariable("progName") String progName,
                                                    @RequestHeader("Accept") MediaType accept) throws Exception {
    HttpHeaders responseHeaders = new HttpHeaders();
    responseHeaders.setContentType(MediaType.APPLICATION_XML);
    if (!accept.toString().equals("*/*")) {
        responseHeaders.setContentType(accept);
    }
    JobResults response = new JobResults("23423", "result");
    return new ResponseEntity<JobResults>(response, responseHeaders, HttpStatus.OK);
}

Какой-то объект ответа, но аннотированный.

@XmlRootElement
public class JobResults {
    String id;
    String name;

    public JobResults(String id, String name) {
        this.id = id;
        this.name = name;
    }

    ....
}

Приведенный выше код дает мне application/json при запросе через заголовок Accept.

Почтальон позволяет добавлять собственные заголовки. Content-Type используется для описания содержания запроса. Accept-Type должен передать ваши пожелания в ответ.

Roald Bankras 06.07.2018 15:42

Я не уверен. Когда я отправляю запрос на конечную точку с ключом Accept-Type и значением application/xml, он немедленно возвращает 400 Bad Request. Когда я использую Google для "Accept-Type", я не могу найти никаких результатов его использования.

Josh 06.07.2018 15:46

Виноват. Это заголовок Accept. Эта страница может помочь прояснить ситуацию: baeldung.com/spring-mvc-content-negotiation-json-xml

Roald Bankras 06.07.2018 15:50

Я установил RequestMapping для создания как XML, так и JSON, и теперь я вызываю конечную точку с расширением .xml или .json. Спасибо, это решило половину моих проблем: P

Josh 06.07.2018 16:10

Пожалуйста. Какая у вас другая половина проблем? p.s. подумайте о том, чтобы принять ответ, если он вам помог.

Roald Bankras 06.07.2018 16:12

Ну, проблема в том, что по умолчанию я хочу, чтобы запрос возвращал XML, и только JSON, если он указан

Josh 06.07.2018 17:08

Если вы используете не расширение, а заголовок, как и ваше исходное предложение, это должно сработать.

Roald Bankras 06.07.2018 17:11

Это не так, запрос по умолчанию возвращает ошибку 400 для моей исходной публикации. Я играю с этим сейчас

Josh 06.07.2018 17:20

При отладке я обнаружил, что если заголовок не был указан, значение было «/», что я понял как подстановочный знак. Я реализовал возможность установить accept для любого типа медиафайла, указанного в заголовке. Спасибо за вашу помощь

Josh 10.07.2018 21:58

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