What is `@ResponseBody` does?

@ResponseBodySpringMVC框架中的一个注解,将方法返回值转换为HTTP响应体内容

@ResponseBody 注解应用在一个控制器方法上时,SpringMVC会将该方法的返回对象(如Java对象、字符串或基本类型)通过MessageConverter转换为指定的媒体类型(如JSONXML等),然后直接写入HTTP响应体中,而不是经过视图解析器查找和渲染视图。

使用样例

RESTful API开发

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;
    }
}

返回JSON格式数据

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省略
}

返回HTTP状态码及响应体

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

@RestController = @Controller + @ResponseBody

@RestController
@RequestMapping("/api/users")
public class UserController {

    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        // 不需要单独标注@ResponseBody,因为@RestController已经提供了这个功能
        return userService.findById(id);
    }
}

你可能感兴趣的:(SpringBoot,注解,SpringMVC,java)