Spring RestController完全指南:构建高效RESTful API的最佳实践

Spring RestController 注解是一个方便的注解,它本身带有 @Controller 和 @ResponseBody 的注解。该注解应用于类上,将其标记为请求处理程序。Spring RestController 注解用于使用 Spring MVC 创建 RESTful Web 服务。Spring RestController 负责将请求数据映射到定义的请求处理程序方法。一旦从处理程序方法生成响应体,它将将其转换为 JSON 或 XML 响应。

Spring RestController 示例

Spring RestController Example Project

Spring RestController Maven依赖

让我们来看一下创建Spring RestController示例项目所需的依赖项。

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-webmvc</artifactId>
	<version>5.0.7.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-web</artifactId>
	<version>5.0.7.RELEASE</version>
</dependency>

<!-- Jackson for REST JSON Support -->
<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-databind</artifactId>
	<version>2.9.6</version>
</dependency>
<!-- JAXB for XML Response, needed to explicitly define from Java 9 onwards -->
<dependency>
	<groupId>javax.xml.bind</groupId>
	<artifactId>jaxb-api</artifactId>
	<version>2.3.0</version>
</dependency>
<dependency>
	<groupId>org.glassfish.jaxb</groupId>
	<artifactId>jaxb-runtime</artifactId>
	<version>2.3.0</version>
	<scope>runtime</scope>
</dependency>
<dependency>
	<groupId>javax.activation</groupId>
	<artifactId>javax.activation-api</artifactId>
	<version>1.2.0</version>
</dependency>

我们需要Spring MVC、Jackson和JAXB库来支持我们的REST Web服务对XML和JSON请求和响应的处理。我们使用web.xml文件来配置Spring MVC的DispatcherServlet作为前端控制器。现在让我们来看一下Spring上下文文件。

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans
	xmlns="https://www.springframework.org/schema/mvc"
	xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
	xmlns:beans="https://www.springframework.org/schema/beans"
	xmlns:context="https://www.springframework.org/schema/context"
	xsi:schemaLocation="https://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
		https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		https://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

	<!-- Enables the Spring MVC @Controller programming model -->
	<annotation-driven />

	<context:component-scan
		base-package="com.Olivia.spring" />

	<beans:bean id="jsonMessageConverter"
		class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
	<beans:bean id="xmlMessageConverter"
		class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter" />

	<beans:bean
		class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
		<beans:property name="messageConverters">
			<beans:list>
				<beans:ref bean="jsonMessageConverter" />
				<beans:ref bean="xmlMessageConverter" />
			</beans:list>
		</beans:property>
	</beans:bean>

</beans:beans>

最重要的部分是在RequestMappingHandlerAdapter中定义和设置的jsonMessageConverter和xmlMessageConverter beans,通过messageConverters属性告诉Spring我们希望应用程序支持JSON和XML,并使用这些beans进行转换。

春季的RestController类

这是我们的Spring RestController类的实现。

package com.Olivia.spring.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.Olivia.spring.model.Employee;
import com.Olivia.spring.repository.EmployeeRepository;

@RestController
public class EmployeeRestController {

	@Autowired
	private EmployeeRepository repository;
	
	@GetMapping("/rest/employee/get/{id}")
	public Employee getEmployeeByID(@PathVariable("id") int id) {
		return repository.retrieve(id);
	}
	
	@GetMapping("/rest/employee/getAll")
	//Returning is List is supported with JSON response only
	//If you want XML, then add a wrapper class as Root XML element, for example EmployeeList
	public List<Employee> getAllEmployees() {
		return repository.getAll();
	}

	@PostMapping("/rest/employee/create")
	public Employee createEmployee(@RequestBody Employee emp) {
		repository.store(emp);
		return emp;
	}
	
	@GetMapping("/rest/employee/search/{name}")
	public Employee getEmployeeByName(@PathVariable("name") String name) {
		return repository.search(name);
	}
	
	@DeleteMapping("/rest/employee/delete/{id}")
	public Employee deleteEmployeeByID(@PathVariable("id") int id) {
		return repository.delete(id);
	}
}

请注意,我们这里只定义了我们的REST API,所有的业务逻辑都是Repository类的一部分。如果我们的方法返回一个列表或数组,那么Spring只支持JSON响应,因为XML的根元素不能是匿名的,但JSON可以。如果你想支持将列表作为XML返回,那么你需要创建一个包装类来容纳这个列表并返回它。在某些方法中,我们期望请求的是员工对象,Spring会负责解析请求体并将其转换为员工对象。同样地,我们将员工对象作为响应体返回,Spring会负责将其转换为JSON/XML响应。

接受和内容类型的请求头

我们已经配置了我们的REST应用程序,使其能够与XML和JSON一起工作。那么它将如何知道请求是XML还是JSON呢?如果响应应以JSON或XML格式发送。这就是使用Accept和Content-Type请求头的地方。Content-Type:定义了请求体中的内容类型,如果值为“application/xml”,则Spring将将请求体视为XML文档。如果它的值是“application/json”,则请求体将被视为JSON。Accept:定义了客户端期望的响应内容类型。如果值为“application/xml”,则将发送XML响应。如果其值为“application/json”,则将发送JSON响应。

Spring RestController 测试

我们的应用程序已经准备好进行测试了,我已经部署在Tomcat-9上并且正在使用Postman进行测试。以下是测试结果及解释。

使用Spring的RestController返回JSON响应

Spring RestController GET JSON Response

Spring的RestController使用GET方式返回XML响应

Spring REST XML Response Accept header

春天 RestController GET 列表

Spring REST GET List XML

春季 RestController 的 POST 方法

Spring RestController POST JSON Request and XML Response

春天的RestController 删除

Spring RestController DELETE XML Response

Summary (Chinese): 概括

Spring RestController通过处理所有繁琐的工作来帮助我们专注于业务逻辑,以便创建REST Web服务APIs。

您可以从我们的 GitHub 存储库下载完整的项目。

bannerAds