@ResponseBody
是SpringMVC
框架中的一个注解,将方法返回值
转换为HTTP响应体内容
当 @ResponseBody
注解应用在一个控制器方法上时,SpringMVC
会将该方法的返回对象(如Java对象、字符串或基本类型)通过MessageConverter
转换为指定的媒体类型(如JSON
、XML
等),然后直接写入HTTP响应体
中,而不是经过视图解析器
查找和渲染视图。
RESTful API
开发:在创建REST服务时,通常需要将业务对象以JSON或其他格式发送给客户端。这时可以使用 @ResponseBody
来直接返回对象,框架会自动进行序列化
。
import org.springframework.web.bind.annotation.*;
@RestController
public class CalculatorController {
@GetMapping("/calculate")
@ResponseBody
public double addNumbers(@RequestParam("num1") double num1, @RequestParam("num2") double num2) {
return num1 + num2;
}
}
import org.springframework.web.bind.annotation.*;
@RestController
public class ProductController {
@GetMapping("/products/{id}")
@ResponseBody
public Product getProduct(@PathVariable Long id) {
// 获取产品逻辑...
Product product = productService.findById(id);
return product; // 返回的对象会被自动序列化为JSON并发送给客户端
}
@PostMapping("/products")
@ResponseBody
public Product createProduct(@RequestBody Product newProduct) {
// 创建产品逻辑...
Product createdProduct = productService.create(newProduct);
return createdProduct; // 同样将返回的对象序列化为JSON响应体
}
}
import org.springframework.web.bind.annotation.*;
@RestController
public class MessageController {
@GetMapping("/message")
@ResponseBody
public String getMessage() {
return "Hello, World!"; // 直接返回一个字符串,它会作为HTTP响应体内容
}
}
// 或者更复杂的动态生成的字符串
@GetMapping("/dynamic-message")
@ResponseBody
public String getDynamicMessage(@RequestParam String name) {
return "Hello, " + name + "!"; // 根据请求参数生成消息,并作为响应体返回
}
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/employees")
public class EmployeeController {
@GetMapping
@ResponseBody
public List<Employee> getAllEmployees() {
// 获取所有员工逻辑...
List<Employee> employees = employeeService.getAll();
return employees; // 返回的员工列表会被转换为JSON并发送给客户端
}
}
// 假设Employee类如下:
public class Employee {
private Long id;
private String name;
private String position;
// 构造函数、getter和setter省略
}
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
public class StatusController {
@GetMapping("/status/{code}")
@ResponseBody
public ResponseEntity<String> getStatus(@PathVariable int code) {
if (HttpStatus.resolve(code) == null) {
return ResponseEntity.badRequest().body("Invalid status code");
}
return ResponseEntity.status(code).body("Requested status code: " + code);
}
}
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/products")
public class ProductController {
private final ProductService productService;
public ProductController(ProductService productService) {
this.productService = productService;
}
@GetMapping(params = {"page", "size"})
@ResponseBody
public Page<Product> getProducts(@RequestParam("page") int page, @RequestParam("size") int size) {
return productService.getProducts(page, size);
}
}
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.*;
import java.util.concurrent.CompletableFuture;
@RestController
public class AsyncController {
@Async
@GetMapping("/async-result")
@ResponseBody
public CompletableFuture<String> getAsyncResult() {
// 模拟耗时操作
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return CompletableFuture.completedFuture("This is the result from an asynchronous operation");
}
}
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class FileDownloadController {
@Async
@GetMapping("/generate-file")
@ResponseBody
public Future<ResponseEntity<String>> generateFileAndReturnLink(@RequestParam("filename") String filename) {
// 模拟文件生成过程
try {
Thread.sleep(5000); // 模拟耗时操作
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
// 假设fileService.generateFile(filename)返回的是文件存储路径
String fileUrl = fileService.generateFile(filename);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.TEXT_PLAIN);
return CompletableFuture.completedFuture(
ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + filename + "\"")
.header(HttpHeaders.LOCATION, fileUrl)
.body("The file has been generated. Download it from: " + fileUrl));
}
}
如果一个控制器类的所有方法都需要返回响应体内容,而不是视图名,那么可以将整个类标记为 @RestController
@RestController
= @Controller
+ @ResponseBody
@RestController
@RequestMapping("/api/users")
public class UserController {
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
// 不需要单独标注@ResponseBody,因为@RestController已经提供了这个功能
return userService.findById(id);
}
}