Spring Boot REST API 返回 XML 作为响应
Posted
技术标签:
【中文标题】Spring Boot REST API 返回 XML 作为响应【英文标题】:SprintBoot REST API to return XML as response 【发布时间】:2022-01-23 20:19:04 【问题描述】:我正在学习 SpringBoot,并且拥有能够理解传入 JSON 响应并将 JSON 响应返回给客户端 (POSTMAN) 的这段代码。我正在尝试体验 SpringBoot,并希望将其配置为返回 XML 响应。
@PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE )
public ResponseEntity<Movie> addMovies(@RequestBody Movie movie)
service.addToMovies(movie);
// Return a ResponseEntity instead.
return new ResponseEntity<Movie>(movie, HttpStatus.OK);
如果我使用值 application/xml 设置 Accept HTTP 标头,我会收到此错误:
Resolved [org.springframework.http.converter.HttpMessageNotWritableException: No converter for [class io.fireacademy.restapi.restapiaws.models.Movie] with preset Content-Type 'null']
不知道为什么会出现这个错误。另外,为什么它说,已解决? 我查看了现有的线程,发现我的 pom.xml 已经有条目:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
我的 SpringBoot 控制器类代码:
package io.fireacademy.restapi.restapiaws.controllers;
import io.fireacademy.restapi.restapiaws.models.Movie;
import io.fireacademy.restapi.restapiaws.services.MovieRecommendationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/movies")
public class RestAPIController
@Autowired
private MovieRecommendationService service;
// When to return a ResponseEntity
// Read https://***.com/questions/49673660/return-responseentity-vs-returning-pojo
@GetMapping
public List<Movie> getMovies()
return service.getMovies();
// Learning: The annotation @PathVariable is needed to inject the value in the URL onto the variable.
@GetMapping(path="/movieId")
public ResponseEntity<Movie> getMovieById(@PathVariable String movieId)
return new ResponseEntity<Movie>(service.getMovie(Integer.parseInt(movieId)), HttpStatus.OK);
// TODO: Why is a List<Movie> failing in POST API and not in GET API
// TODO: What is the use of produces/consumes
// Learning: The client need to set Content-Type HTTP header set so that the server can understand how to process the body data.
@PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE )
public ResponseEntity<Movie> addMovies(@RequestBody Movie movie)
service.addToMovies(movie);
// Return a ResponseEntity instead.
return new ResponseEntity<Movie>(movie, HttpStatus.OK);
@PutMapping(path="/movieId")
public ResponseEntity<Movie> updateMovies(@PathVariable String movieId, @RequestBody Movie movie)
// Return a ResponseEntity instead.
return new ResponseEntity<Movie>(service.updateAMovie(Integer.parseInt(movieId), movie), HttpStatus.OK);
@DeleteMapping(path="/movieId")
public ResponseEntity<Movie> deleteMovies(@PathVariable String movieId)
// Return a ResponseEntity instead.
return new ResponseEntity<Movie>(service.removeAMovie(Integer.parseInt(movieId)), HttpStatus.OK);
// TODO: Integrate this onto a javascript code
我也更新了消费者。还是一样的结果。
@PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE , produces = MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE )
请给我任何线索。
【问题讨论】:
【参考方案1】:-
使用杰克逊
Spring MVC 默认使用 Jackson 库来处理 JSON 响应。当我们将 Jackson 扩展 jackson-dataformat-xml 添加到类路径时,Spring MVC 会自动选择它并用于 XML 响应。
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
-
使用 JAXB
如果 Jackson XML 扩展在类路径中不可用,Spring MVC 将使用 JAXB 进行转换。但是,要使其正常工作,我们必须使用 @XmlRootElement 注释来注释我们的响应对象。
@XmlRootElement
public class CommentDTO
private String id;
返回 JSON 和 XML 有时我们希望在相同的端点和方法实现上支持 JSON 和 XML 响应。为此,我们只需要在产品参数中添加第二个 MediaType,例如:
@RequestMapping(value = "/id", produces = MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE )
public CommentDTO getComment(@PathVariable(value = "id") String commentId) throws IOException
return service.get(commentId);
现在客户端必须在 Accept 标头中发送它想要接收的内容类型。
Accept: application/xml
如果客户端没有发送 Accept 头,Spring MVC 将回退到配置的默认内容类型。你可以改变它:
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer)
configurer.defaultContentType(MediaType.APPLICATION_XML);
【讨论】:
以上是关于Spring Boot REST API 返回 XML 作为响应的主要内容,如果未能解决你的问题,请参考以下文章