• OJ项目——统一数据格式返回,我是如何处理的?


    目录

     前言

    OJ项目中是如何处理的

    1、准备一个类,作为统一的数据返回格式 

    2、准备一个类,实现ResponseBodyAdvice接口

    3、我们如何写返回值更好

    4、进一步优化返回值

    小结


     前言

    关于SpringBoot的同一功能处理,本博主在这篇博客已经有介绍过:http://t.csdnimg.cn/pTyFL

    不去看也没关系,本篇博客手把手教会你 ~


    OJ项目中是如何处理的

    1、准备一个类,作为统一的数据返回格式 

            首先,我们准备一个类,这个类就作为所有的返回值,这个类中,设置三个字段:状态码 + 数据 + 错误信息 

    代码示例:

    1. package com.example.demo.common;
    2. import lombok.Data;
    3. /**
    4. * Created with IntelliJ IDEA.
    5. * Description:
    6. * User:龙宝
    7. * Date:2023-10-08
    8. * Time:14:50
    9. * 统一返回
    10. */
    11. @Data
    12. public class AjaxResult {
    13. private Integer code;//状态码
    14. private String msg;//状态码描述
    15. private Object data;//返回数据
    16. /*
    17. 操作成功返回结果
    18. */
    19. public static AjaxResult success(Object data) {
    20. AjaxResult ajaxResult = new AjaxResult();
    21. ajaxResult.setCode(200);
    22. ajaxResult.setMsg("");
    23. ajaxResult.setData(data);
    24. return ajaxResult;
    25. }
    26. public static AjaxResult success(Integer code,Object data) {
    27. AjaxResult ajaxResult = new AjaxResult();
    28. ajaxResult.setCode(code);
    29. ajaxResult.setMsg("");
    30. ajaxResult.setData(data);
    31. return ajaxResult;
    32. }
    33. public static AjaxResult success(Integer code,String msg,Object data) {
    34. AjaxResult ajaxResult = new AjaxResult();
    35. ajaxResult.setCode(code);
    36. ajaxResult.setMsg(msg);
    37. ajaxResult.setData(data);
    38. return ajaxResult;
    39. }
    40. /*
    41. 错误返回结果
    42. */
    43. public static AjaxResult fail(Integer code,String msg) {
    44. AjaxResult ajaxResult = new AjaxResult();
    45. ajaxResult.setCode(code);
    46. ajaxResult.setMsg(msg);
    47. ajaxResult.setData("");
    48. return ajaxResult;
    49. }
    50. public static AjaxResult fail(String msg) {
    51. AjaxResult ajaxResult = new AjaxResult();
    52. ajaxResult.setCode(-1);
    53. ajaxResult.setMsg(msg);
    54. ajaxResult.setData("");
    55. return ajaxResult;
    56. }
    57. }

            上述代码中,我们可以看到,我们还提供了几个静态方法,分为两大类:success 和fail 即后端能够正确处理业务的返回,和后端判断参数有误等其他的业务返回。例如,用户登录:用户密码输入错误为有误返回 ; 正常登录上系统 为 正确返回~

            这样一来,前端只需要接收到一个AjaxResult这样的对象,检查他的状态码code的值,就可以这个返回的是否是正确的值,正确的按AjaxResult的数据data来处理,错误的按msg的值给出对应提示~

    2、准备一个类,实现ResponseBodyAdvice接口

    准备一个类,并添加@ControllerAdvice注解

    例:

    1. @ControllerAdvice
    2. public class ResponseAdvice{
    3. }

    实现ResponseBodyAdvice接口,重写supports和beforeBodyWrite(统一对象就是此方法中实现)

    例:

    1. @ControllerAdvice
    2. public class ResponseAdvice implements ResponseBodyAdvice {
    3. @Override
    4. public boolean supports(MethodParameter returnType, Class converterType) {
    5. return true;
    6. }
    7. @SneakyThrows
    8. @Override
    9. public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
    10. return body;
    11. }
    12. }

    说明:

    • 第一个方法:supports方法中,要把返回值改为true。意思就是开启统一数据格式返回的功能。
    • 第二个方法:开启第一个方法后,返回前,就会执行方法二beforeBodyWrite这个方法,这里解释一下body:这个body就是传给这个方法的返回值,例如我执行登录功能,登录成功,返回给前端,四个大字:return "登录成功~",  返回的这个字符串,就会被传为上述第二个方法作为body的值,我们可以经过一些处理后再返回给前端。例:
    1. @ControllerAdvice
    2. public class ResponseAdvice implements ResponseBodyAdvice {
    3. @Override
    4. public boolean supports(MethodParameter returnType, Class converterType) {
    5. return true;
    6. }
    7. @SneakyThrows
    8. @Override
    9. public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
    10. return AjaxResult.success(body);
    11. }
    12. }

            这样的写法其实并不好,因为我们好像就只是默认返回的值都是AjaxResult的success方法,不能灵活调整~ 使用下面的方式会更好

    3、我们如何写返回值更好

            例如上述举例中,登陆成功后,返回给前端四个字 return "登陆成功~";  

            我们大可以写成这样:

            这种实现,我们不管是返回正确的值还是非正确的值,都是可以的,无非就是调用success还是fail方法~ 

            然后在上述实现ResponseBodyAdvice的接口中的第二个方法,返回值就直接设置为 :

    4、进一步优化返回值

            如果说,在上述实现ResponseBodyAdvice的接口中的第二个方法中,我们直接返回body,会出现两个有误的情况:

    情况一:如果开发人员的返回值,忘记调用AjaxResult的方法了,前端解析数据时,会出现异常

    因此,我们要有一个判断,代码,例:

    1. @SneakyThrows
    2. @Override
    3. public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
    4. if(body instanceof AjaxResult) {
    5. return body;
    6. }
    7. return AjaxResult.success(body);
    8. }

    情况二:如果body是字符串,会出现报错

            为什么呢?String是一个很特殊的类型,既不是基本类型,也不属于对象,并且在重写方法时,除String以外都是使用同一个格式化工具,而String用的是自己的一套格式化工具,因此在转换成HashMap时,还没有被加载好,而其他的转换器都已经加载好了,就会出现异常了。 

            因此当返回类型为String类型时,就要进行特殊处理,使用JSON的writeValueAsString方法将java对象转换成JSON格式再返回~

    代码修改如下:

    代码:

    1. package com.example.demo.config;
    2. import com.example.demo.common.AjaxResult;
    3. import com.fasterxml.jackson.databind.ObjectMapper;
    4. import lombok.SneakyThrows;
    5. import org.springframework.beans.factory.annotation.Autowired;
    6. import org.springframework.core.MethodParameter;
    7. import org.springframework.http.MediaType;
    8. import org.springframework.http.server.ServerHttpRequest;
    9. import org.springframework.http.server.ServerHttpResponse;
    10. import org.springframework.web.bind.annotation.ControllerAdvice;
    11. import org.springframework.web.bind.annotation.ResponseBody;
    12. import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
    13. /**
    14. * Created with IntelliJ IDEA.
    15. * Description:
    16. * User:龙宝
    17. * Date:2023-10-08
    18. * Time:15:11
    19. */
    20. @ControllerAdvice
    21. public class ResponseAdvice implements ResponseBodyAdvice {
    22. @Autowired
    23. private ObjectMapper objectMapper;
    24. @Override
    25. public boolean supports(MethodParameter returnType, Class converterType) {
    26. return true;
    27. }
    28. @SneakyThrows
    29. @Override
    30. public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
    31. if(body instanceof AjaxResult) {
    32. return body;
    33. }
    34. if(body instanceof String) {
    35. return objectMapper.writeValueAsString(body);
    36. }
    37. return AjaxResult.success(body);
    38. }
    39. }

            


    小结

            总的来说就是两个步骤:创建一个AjaxResult类,然后来一个实现ResponseBodyAdvice接口的类,就可以了~ 

            好啦,上述就是我在OJ项目中对返回值的统一处理。希望对你有所帮助~ 

  • 相关阅读:
    Leetcode 891. 子序列宽度之和
    通过解析库探究函数式抽象代价 ( ini 解析示例补充)
    vue样式穿透的几种方式
    [474]. 一和零
    EM算法学习笔记
    Java 线程池之任务拒绝策略
    基于STM32F103的HAL库手动配置FreeRTOS
    线性代数(二)| 行列式性质 求值 特殊行列式 加边法 归纳法等多种方法
    cas:216300-12-8|1-丙基-3-甲基咪唑六氟磷酸盐[C3MIm]PF6离子液体分子量:125
    手撕代码彻底理解Promise
  • 原文地址:https://blog.csdn.net/LYJbao/article/details/133806566