当前位置: 首页 > news >正文

【SpringBoot】_统一功能处理:统一数据返回格式

目录

1. 对所有返回类型方法进行统一数据返回类型处理

2. 部分返回类型方法存在的问题

3. 对两种有误的方法进行处理


仍以图书管理系统为例。

创建Result对后端返回给前端的数据进行封装,增加业务状态码与错误信息,将原本的数据作为data部分:

package com.example.bookmanagementsystem.model;

import com.example.bookmanagementsystem.enums.ResultCode;
import lombok.Data;

@Data
public class Result<T> {
//    业务状态码:0-成功, -1-失败, -2未登录;
    private ResultCode code;
//    错误信息;
    private String errMsg;
//    数据
    private Object data;

    public static <T> Result<T> success(T data){
        Result result=new Result();
        result.setCode(ResultCode.SUCCESS);
        result.setErrMsg("");
        result.setData(data);
        return result;
    }
    public static  <T> Result<T> fail(String errMsg,Object data){
        Result result=new Result();
        result.setCode(ResultCode.FAIL);
        result.setErrMsg(errMsg);
        result.setData(data);
        return result;
    }
    public static  <T> Result<T> fail(String errMsg){
        Result result=new Result();
        result.setCode(ResultCode.FAIL);
        result.setErrMsg(errMsg);
        result.setData(null);
        return result;
    }
    public static  <T> Result<T> unlogin(){
        Result result=new Result();
        result.setCode(ResultCode.UNLOGIN);
        result.setErrMsg("用户未登录");
        result.setData(null);
        return result;
    }
}

将getBookListByPage方法的返回值修改为Result:

@RequestMapping("/getBookListByPage")
    public Result getBookListByPage(PageRequest pageRequest, HttpSession session){
        log.info("接收到查询翻页信息:pageRequest:{}",pageRequest);
        // 校验成功
        if(pageRequest.getPageSize()<0 || pageRequest.getCurrentPage()<1) {
            return Result.fail("参数校验失败");
        }
        PageResult<BookInfo> bookInfoPageResult=null;
        try{
            bookInfoPageResult = bookService.selectBookInfoByPage(pageRequest);
            return Result.success(bookInfoPageResult);
        }catch (Exception e){
            log.error("查询翻页信息错误:e{}",e);
            return Result.fail(e.getMessage());
        }
    }

 为了实现后端方法返回给前端的数据都被封装为Result类型,若逐个修改封装会非常麻烦,接下来采用统一数据返回对现有方法进行处理。

1. 对所有返回类型方法进行统一数据返回类型处理

在config包下创建一个ResponseAdvice类,表示控制器通知类:

package com.example.bookmanagementsystem.config;

import com.example.bookmanagementsystem.model.Result;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {
    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
//        返回前需要执行的操作:封装
        return Result.success(body);
    }
}

1、控制器通知类需要使用@ControllerAdvice注解,并实现ResponseBodyAdvice接口;

2、控制器通知类需要重写supports方法和beforeBodyWrite方法:

(1)supports方法:返回值为布尔类型,表示是否执行beforeBodyWrite方法

若返回值为true表示执行,false表示不执行;

(2)beforeBodyWrite方法:对response方法进行具体操作

2. 部分返回类型方法存在的问题

1、当返回类型为Result时:(Result类型已进行返回类型的封装)

登录后,测试getBookListByPage方法:

body就是返回的结果,但success方法已经进行了封装,故而导致两遍封装:

2、当返回类型为String时:

登录后,对updateBook方法进行测试:

可见HTTP状态码为500,表示服务器内部执行有误。但此时采用的统一数据返回形式却将业务状态码置为SUCCESS,出现错误;

综上:

当前统一数据返回格式处理对于两种返回类型的方法存在错误:
(1)返回类型为Result时出现嵌套封装;

(2)返回类型为String时无法正确处理;

3. 对两种有误的方法进行处理

修改ResponseAdvice类:

package com.example.bookmanagementsystem.config;

import com.example.bookmanagementsystem.model.Result;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {
    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return true;
    }

    @SneakyThrows    // lombok提供的处理异常的注解:编译后处理为try catch;
    @Override
    public Object beforeBodyWrite(Object body,
                                  MethodParameter returnType,
                                  MediaType selectedContentType,
                                  Class selectedConverterType,
                                  ServerHttpRequest request,
                                  ServerHttpResponse response) {
//        返回前需要执行的操作:封装
        if(body instanceof Result){
            return body;
        }
        if(body instanceof String){
            return objectMapper.writeValueAsString(Result.success(body));
        }
        return Result.success(body);
    }
}

(1)对于返回类型为Result的方法进行处理,当body为Result时直接返回body即可,无需进行统一数据返回;

(2)对于返回类型为String类型的方法进行处理,此时需使用jackson的ObjectMapper类,实例化对象后调用writeValueAsString方法进行处理;

使用postman进行测试:

1、使用getBookListByPage方法(返回值为Result类型)进行测试:

2、使用updateBook方法(返回值为String类型)进行测试:

相关文章:

  • npm包无法识别命令
  • Redis高级篇之布隆过滤器
  • 使用 DistilBERT 进行资源高效的自然语言处理
  • 蓝桥杯备考:搜索算法之枚举子集
  • 【UCB CS 61B SP24】Lecture 7 - Lists 4: Arrays and Lists学习笔记
  • 制造业生产大数据解决方案
  • 复刻Dummy机械臂保姆教程
  • 爬虫基础之爬取某站视频
  • WPS接入私有化DeepSeek大语言模型
  • CSS基础(盒子模型的组成、内容溢出、隐藏元素的方式、样式的继承、元素的默认样式、布局技巧、元素之间的空白问题、行内块元素的幽灵空白问题)
  • Rust~二刷异步逻辑
  • 一周学会Flask3 Python Web开发-flask3上下文全局变量session,g和current_app
  • 系统讨论Qt的并发编程——逻辑上下文的分类
  • 最新版本Exoplayer(MediaX)实现K歌原伴唱包括单音轨和双音轨
  • Python逻辑回归小案例教程
  • 黑客疑入侵OmniGPT:3400万用户数据遭泄露
  • Infuse Pro for Mac v8.1 全能视频播放器 支持M、Intel芯片
  • 一周掌握Flutter开发--1、Widget 系统
  • ubuntu安装docker docker/DockerHub 国内镜像源/加速列表【持续更新】
  • 代码随想录刷题day29|(栈与队列篇:队列)225.用队列实现栈
  • 海外seo网站建设/百度如何发布作品
  • 那些网站是用python做的/seo营销推广平台
  • c 网站开发实战/柳州网站建设哪里有
  • 阳春网站开发/湖南seo网站多少钱
  • 手机网站 ui/珠海网站建设制作
  • 怎么让网站绑定域名访问/互联网舆情监测系统