java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > SpringBoot控制器返回值处理

SpringBoot控制器返回值处理的4个技巧分享

作者:风象南

在SpringBoot应用开发中,控制器(Controller)的返回值处理是一个基础但极其重要的环节,本文将介绍SpringBoot中四种常用的控制器返回值处理技巧,有需要的可以参考下

在SpringBoot应用开发中,控制器(Controller)的返回值处理是一个基础但极其重要的环节。

合理的返回值处理不仅能提高代码的可读性和可维护性,还能优化前后端交互体验。

本文将介绍SpringBoot中四种常用的控制器返回值处理技巧。

1. 返回ResponseEntity对象

ResponseEntity是Spring框架提供的一个用于表示HTTP响应的类,它允许开发者完全控制响应内容,包括状态码、头信息和响应体。

@RestController
@RequestMapping("/api/users")
public class UserController {
    
    @GetMapping("/{id}")
    public ResponseEntity<?> getUser(@PathVariable Long id) {
        try {
            User user = userService.findById(id);
            if (user == null) {
                return ResponseEntity.notFound().build();
            }
            return ResponseEntity.ok(user);
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body("获取用户信息失败:" + e.getMessage());
        }
    }
    
    @PostMapping
    public ResponseEntity<User> createUser(@RequestBody User user) {
        User createdUser = userService.save(user);
        URI location = ServletUriComponentsBuilder
            .fromCurrentRequest()
            .path("/{id}")
            .buildAndExpand(createdUser.getId())
            .toUri();
        
        return ResponseEntity.created(location).body(createdUser);
    }
}

优势

适用场景

2. 使用@ResponseBody注解

使用@ResponseBody注解(或在类上使用@RestController)可以让Spring将返回值直接序列化到HTTP响应体中。这种方式简单直接,特别适合返回JSON或XML数据。

@Controller
@RequestMapping("/api/products")
public class ProductController {
    
    @GetMapping("/{id}")
    @ResponseBody
    public Product getProduct(@PathVariable Long id) {
        return productService.findById(id);
    }
    
    @GetMapping("/count")
    @ResponseBody
    public Integer getProductCount() {
        return productService.count();
    }
    
    @GetMapping("/available")
    @ResponseBody
    public boolean isProductAvailable(@RequestParam String sku) {
        return productService.checkAvailability(sku);
    }
    
    @GetMapping("/message")
    @ResponseBody
    public String getMessage() {
        return "这是一条简单的文本消息";
    }
}

优势

适用场景

3. 返回视图和模型(传统Web应用)

在传统的Web应用中,控制器方法通常返回一个视图名称,并通过Model或ModelAndView传递数据。这种方式适合服务器端渲染的应用。

@Controller
@RequestMapping("/web")
public class WebController {
    
    @GetMapping("/users")
    public String listUsers(Model model) {
        List<User> users = userService.findAll();
        model.addAttribute("users", users);
        model.addAttribute("title", "用户列表");
        return "user/list";  // 返回视图名,对应 templates/user/list.html
    }
    
    @GetMapping("/dashboard")
    public ModelAndView dashboard() {
        ModelAndView mav = new ModelAndView("dashboard");
        mav.addObject("stats", statisticsService.getSummary());
        mav.addObject("lastLogin", new Date());
        return mav;
    }
    
    // 重定向示例
    @PostMapping("/users/save")
    public String saveUser(User user) {
        userService.save(user);
        return "redirect:/web/users";  // 重定向到用户列表
    }
}

优势

适用场景

4. 使用统一响应格式封装

在实际项目中,通常会定义统一的响应格式,包含状态码、消息和数据。这种方式有助于前后端交互的一致性和规范性。

// 统一响应实体类
@Data
public class ApiResponse<T> {
    private Integer code;
    private String message;
    private T data;
    private long timestamp;
    
    public static <T> ApiResponse<T> success(T data) {
        ApiResponse<T> response = new ApiResponse<>();
        response.setCode(200);
        response.setMessage("操作成功");
        response.setData(data);
        response.setTimestamp(System.currentTimeMillis());
        return response;
    }
    
    public static <T> ApiResponse<T> error(Integer code, String message) {
        ApiResponse<T> response = new ApiResponse<>();
        response.setCode(code);
        response.setMessage(message);
        response.setTimestamp(System.currentTimeMillis());
        return response;
    }
}

// 全局响应处理(可选方式)
@RestControllerAdvice
public class GlobalResponseHandler implements ResponseBodyAdvice<Object> {
    
    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        // 决定哪些方法需要处理
        return true;
    }
    
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, 
                                 MediaType selectedContentType, 
                                 Class<? extends HttpMessageConverter<?>> selectedConverterType, 
                                 ServerHttpRequest request, ServerHttpResponse response) {
        // 已经是ApiResponse类型则不再包装
        if (body instanceof ApiResponse) {
            return body;
        }
        // 包装成功响应
        return ApiResponse.success(body);
    }
}

// 控制器使用示例
@RestController
@RequestMapping("/api/v1")
public class ModernApiController {
    
    @GetMapping("/orders")
    public ApiResponse<List<Order>> getOrders() {
        List<Order> orders = orderService.findAll();
        return ApiResponse.success(orders);
    }
    
    @GetMapping("/customers/{id}")
    public ApiResponse<Customer> getCustomer(@PathVariable Long id) {
        try {
            Customer customer = customerService.findById(id);
            if (customer == null) {
                return ApiResponse.error(404, "客户不存在");
            }
            return ApiResponse.success(customer);
        } catch (Exception e) {
            return ApiResponse.error(500, "服务器错误:" + e.getMessage());
        }
    }
}

优势

适用场景

总结

在实际项目中,这些技巧往往会结合使用。

例如,可以在RESTful API中同时使用统一响应格式和ResponseEntity,既提供标准化的响应体,又能灵活控制HTTP状态码。

选择合适的返回值处理方式,不仅能提高代码质量,还能改善前后端协作效率。

到此这篇关于SpringBoot控制器返回值处理的4个技巧分享的文章就介绍到这了,更多相关SpringBoot控制器返回值处理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文