springboot2 - ResponseBodyAdvice

对于 Controller 返回值,一般需要进行二次打包。

比如:code 是结果码(0 表示成功,其它表示异常...),data 为携带数据

{
    "code": "1",
    "data": {
        "name": "xiaoming",
        "age": "30"
    }
}

下面这种封装方式很常见,但是做得还不够好:

  • 需要手动调用 Result 工具类;
  • 所有的 Controller 都会与 Result 产生强耦合;
  • 代码复用性减弱,如果产生新的想法,不方便调整。
class Controller {

    @ResponseBody
    @RequestMapping("result")
    public Result result() {
        // do sth. 
        // 如果业务成功,手动调用表示成功状态的函数
        return Result.succeed();
    }
}

更优的策略,写一个 AOP 切面统一处理,代码样例如下:

  • 这个类不要手动注册,spring 会自动扫描;
  • ResponseBodyAdvice 只能处理正常业务流,抛出异常的情况,需要在异常切面中处理。
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.util.HashMap;
import java.util.Map;

/**
 * 指定 basePackages,对特定的程序生效
 */
@ControllerAdvice(basePackages = "cn.seaboot")
public class TestResponseAdvice implements ResponseBodyAdvice<Object> {

    /**
     * 设置一个标志位,返回 true 才执行 beforeBodyWrite()
     */
    @Override
    public boolean supports(MethodParameter methodParameter,
                            Class<? extends HttpMessageConverter<?>> aClass) {
        return methodParameter.hasMethodAnnotation(ResponseBody.class);
    }

    /**
     * 数据重新打包
     * 
     * @param o Controller 返回值
     * @return 打包之后的数据
     */
    @Override
    public Object beforeBodyWrite(Object o, MethodParameter methodParameter,
                                  MediaType mediaType,
                                  Class<? extends HttpMessageConverter<?>> aClass,
                                  ServerHttpRequest serverHttpRequest,
                                  ServerHttpResponse serverHttpResponse) {
        Map<String, Object> res = new HashMap<>();
        res.put("code", 0);
        res.put("data", o);
        return res;
    }
}

posted on   疯狂的妞妞  阅读(22509)  评论(1编辑  收藏  举报

(评论功能已被禁用)
编辑推荐:
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
阅读排行:
· Blazor Hybrid适配到HarmonyOS系统
· 万字调研——AI生成内容检测
· 解决跨域问题的这6种方案,真香!
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· 一套基于 Material Design 规范实现的 Blazor 和 Razor 通用组件库
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示