У меня есть сопоставление запросов 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);
}
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);
}

Ваш пример по-прежнему берет 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.
Я не уверен. Когда я отправляю запрос на конечную точку с ключом Accept-Type и значением application/xml, он немедленно возвращает 400 Bad Request. Когда я использую Google для "Accept-Type", я не могу найти никаких результатов его использования.
Виноват. Это заголовок Accept. Эта страница может помочь прояснить ситуацию: baeldung.com/spring-mvc-content-negotiation-json-xml
Я установил RequestMapping для создания как XML, так и JSON, и теперь я вызываю конечную точку с расширением .xml или .json. Спасибо, это решило половину моих проблем: P
Пожалуйста. Какая у вас другая половина проблем? p.s. подумайте о том, чтобы принять ответ, если он вам помог.
Ну, проблема в том, что по умолчанию я хочу, чтобы запрос возвращал XML, и только JSON, если он указан
Если вы используете не расширение, а заголовок, как и ваше исходное предложение, это должно сработать.
Это не так, запрос по умолчанию возвращает ошибку 400 для моей исходной публикации. Я играю с этим сейчас
При отладке я обнаружил, что если заголовок не был указан, значение было «/», что я понял как подстановочный знак. Я реализовал возможность установить accept для любого типа медиафайла, указанного в заголовке. Спасибо за вашу помощь
Почтальон позволяет добавлять собственные заголовки.
Content-Typeиспользуется для описания содержания запроса.Accept-Typeдолжен передать ваши пожелания в ответ.