Redian新闻
>
生产大文件下载导致 OOM,顺藤摸瓜拿下

生产大文件下载导致 OOM,顺藤摸瓜拿下

公众号新闻

👉 这是一个或许对你有用的社群

🐱 一对一交流/面试小册/简历优化/求职解惑,欢迎加入芋道快速开发平台知识星球。下面是星球提供的部分资料: 

👉这是一个或许对你有用的开源项目

国产 Star 破 10w+ 的开源项目,前端包括管理后台 + 微信小程序,后端支持单体和微服务架构。

功能涵盖 RBAC 权限、SaaS 多租户、数据权限、商城、支付、工作流、大屏报表、微信公众号、CRM 等等功能:

  • Boot 仓库:https://gitee.com/zhijiantianya/ruoyi-vue-pro
  • Cloud 仓库:https://gitee.com/zhijiantianya/yudao-cloud
  • 视频教程:https://doc.iocoder.cn
【国内首批】支持 JDK 21 + SpringBoot 3.2.2、JDK 8 + Spring Boot 2.7.18 双版本 

来源:飞天小牛肉


1 简介

Graceful Response是一个Spring Boot技术栈下的优雅响应处理器,提供一站式统一返回值封装、全局异常处理、自定义异常错误码 等功能,使用Graceful Response进行web接口开发不仅可以节省大量的时间,还可以提高代码质量,使代码逻辑更清晰。

强烈推荐你花3分钟学会它!

本项目案例工程代码:https://github.com/feiniaojin/graceful-response-example.git ,注意选择最新版本的分支。

Spring Boot版本Graceful Response版本graceful-response-example分支
2.x3.2.1-boot23.2.0-boot2
3.x3.2.1-boot33.2.0-boot3

注意,3.2.1-boot2版本的Graceful Response源码由单独的仓库进行维护,地址为:https://github.com/feiniaojin/graceful-response-boot2

3.2.1-boot2和3.2.1-boot3除了支持的SpringBoot版本不一样,其他实现完全一致,Maven引用时只需要根据对应的SpringBoot版本选择Graceful Response的version即可,两者的groupId、artifactId是一致的。

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/ruoyi-vue-pro
  • 视频教程:https://doc.iocoder.cn/video/

2 快速入门

2.1 Spring Boot接口开发现状

目前,业界使用Spring Boot进行接口开发时,往往存在效率底下、重复劳动、可读性差等问题。以下伪代码相信大家非常熟悉,我们大部分项目的Controller接口都是这样的。

@Controller
public class Controller {

  @GetMapping("/query")
  @ResponseBody
  public Response query(Map<String, Object> paramMap) {
    Response res = new Response();
    try {
      //1.校验params参数合法性,包括非空校验、长度校验等
      if (illegal(paramMap)) {
        res.setCode(1);
        res.setMsg("error");
        return res;
      }
      //2.调用Service的一系列操作,得到查询结果
      Object data = service.query(params);
      //3.将操作结果设置到res对象中
      res.setData(data);
      res.setCode(0);
      res.setMsg("ok");
      return res;
    } catch (Exception e) {
      //4.异常处理:一堆丑陋的try...catch,如果有错误码的,还需要手工填充错误码
      res.setCode(1);
      res.setMsg("error");
      return res;
    }
  }
}

这段伪代码存在什么样的问题呢?

第一个问题,效率低下。 Controller层的代码应该尽量简洁,上面的伪代码其实只是为了将数据查询的结果进行封装,使其以统一的格式进行返回。例如以下格式的响应体:

{
  "code"0,
  "msg""ok",
  "data": {
    "id"1,
    "name""username"
  }
}

查询过程中如果发生异常,需要在Controller进行手工捕获,根据捕获的异常人工地设置错误码,当然,也用同样的格式封装错误码进行返回。

可以看到,除了调用service层的query方法这一行,其他大部分的代码都执行进行结果的封装,大量的冗余、低价值的代码导致我们的开发活动效率很低。

第二个问题,重复劳动。 以上捕获异常、封装执行结果的操作,每个接口都会进行一次,因此造成大量重复劳动。

第三个问题,可读性低。 上面的核心代码被淹没在许多冗余代码中,很难阅读,如同大海捞针。

我们可以通过Graceful Response这个组件解决这样的问题。

2.2. 快速入门

2.2.1 引入Graceful Response组件

Graceful Response已发布至maven中央仓库,我们可以直接引入到项目中。

maven依赖如下:

<dependency>
  <groupId>com.feiniaojin</groupId>
  <artifactId>graceful-response</artifactId>
  <version>{latest.version}</version>
</dependency>
Spring Boot版本Graceful Response最新版本
2.x3.2.1-boot2
3.x3.2.1-boot3
2.2.2 启用Graceful Response

在启动类中引入@EnableGracefulResponse注解,即可启用Graceful Response组件。

@EnableGracefulResponse
@SpringBootApplication
public class ExampleApplication {
  public static void main(String[] args) {
    SpringApplication.run(ExampleApplication.classargs);
  }
}
2.2.3 Controller层

引入Graceful Response后,我们不需要再手工进行查询结果的封装,直接返回实际结果即可,Graceful Response会自动完成封装的操作。

Controller层示例如下。

@Controller
public class Controller {
  @RequestMapping("/get")
  @ResponseBody
  public UserInfoView get(Long id) {
    log.info("id={}", id);
    return UserInfoView.builder().id(id).name("name" + id).build();
  }
}

在示例代码中,Controller层的方法直接返回了UserInfoView对象,没有进行封装的操作,但经过Graceful Response处理后,我们还是得到了以下的响应结果。

{
  "status": {
    "code""0",
    "msg""ok"
  },
  "payload": {
    "id"1,
    "name""name1"
  }
}

而对于命令操作(Command)尽量不返回数据,因此command操作的方法的返回值应该是void,Graceful Response对于对于返回值类型void的方法,也会自动进行封装。

public class Controller {
  @RequestMapping("/command")
  @ResponseBody
  public void command() {
    //业务操作
  }
}

成功调用该接口,将得到:

{
  "status": {
    "code""200",
    "msg""success"
  },
  "payload": {}
}
2.2.4 Service层

在引入Graceful Response前,有的开发者在定义Service层的方法时,为了在接口中返回异常码,干脆直接将Service层方法定义为Response,淹没了方法的正常返回值。

Response的代码如下。

//lombok注解
@Data
public class Response {
  private String code;
  private String msg;
  private Object data;
}

直接返回Response的Service层方法:

/**
 * 直接返回Reponse的Service
 * 不规范
 */

public interface Service {
  public Reponse commandMethod(Command command);
}

Graceful Response引入@ExceptionMapper注解,通过该注解将异常和错误码关联起来,这样Service方法就不需要再维护Response的响应码了,直接抛出业务异常,由Graceful Response进行异常和响应码的关联。

@ExceptionMapper的用法如下。

/**
 * NotFoundException的定义,使用@ExceptionMapper注解修饰
 * code:代表接口的异常码
 * msg:代表接口的异常提示
 */

@ExceptionMapper(code = "1404", msg = "找不到对象")
public class NotFoundException extends RuntimeException {

}

Service接口定义:

public interface QueryService {
  UserInfoView queryOne(Query query);
}

Service接口实现:

public class QueryServiceImpl implements QueryService {
  @Resource
  private UserInfoMapper mapper;

  public UserInfoView queryOne(Query query) {
    UserInfo userInfo = mapper.findOne(query.getId());
    if (Objects.isNull(userInfo)) {
      //这里直接抛自定义异常
      throw new NotFoundException();
    }
    //……后续业务操作
  }
}

当Service层的queryOne方法抛出NotFoundException时,Graceful Response会进行异常捕获,并将NotFoundException对应的异常码和异常信息封装到统一的响应对象中,最终接口返回以下JSON。

{
        "status": {
        "code""1404",
        "msg""找不到对象"
        },
        "payload": {}
        }
2.2.5 参数校验

Graceful Response对JSR-303数据校验规范和Hibernate Validator进行了增强,Graceful Response自身不提供参数校验的功能,但是用户使用了Hibernate Validator后,Graceful Response可以通过@ValidationStatusCode注解为参数校验结果提供响应码,并将其统一封装返回。

例如以下的UserInfoQuery。

@Data
public class UserInfoQuery {
  @NotNull(message = "userName is null !")
  @Length(min = 6, max = 12)
  @ValidationStatusCode(code = "520")
  private String userName;
}

UserInfoQuery对象中定义了@NotNull和@Length两个校验规则,在未引入Graceful Response的情况下,会直接抛出异常;

在引入Graceful Response但是没有加入@ValidationStatusCode注解的情况下,会以默认的错误码进行返回;

在上面的UserInfoQuery中由于使用了@ValidationStatusCode注解,并指定异常码为520,则当userName字段任意校验不通过时,都会使用异常码520进行返回,如下。

{
  "status": {
    "code""520",
    "msg""userName is null !"
  },
  "payload": {}
}

而对于Controller层直接校验方法入参的场景,Graceful Response也进行了增强,如以下Controller。

public class Controller {

  @RequestMapping("/validateMethodParam")
  @ResponseBody
  @ValidationStatusCode(code = "1314")
  public void validateMethodParam(
          @NotNull(message = "userId不能为空")
 Long userId,
          @NotNull(message = "userName不能为空") Long userName) 
{
    //省略业务逻辑
  }
}

如果该方法入参校验触发了userId和userName的校验异常,将以错误码1314进行返回,如下。

{
  "status": {
    "code""1314",
    "msg""userId不能为空"
  },
  "payload": {}
}
2.2.6 自定义Response格式

Graceful Response内置了两种风格的响应格式,并通过graceful-response.response-style进行配置。

graceful-response.response-style=0,或者不配置(默认情况),将以以下的格式进行返回:

{
  "status": {
    "code"1007,
    "msg""有内鬼,终止交易"
  },
  "payload": {
  }
}

graceful-response.response-style=1,将以以下的格式进行返回:

{
        "code""1404",
        "msg""not found",
        "data": {
        }
        }

如果这两种格式均不满足业务需要,Graceful Response也支持用户自定义响应体,关于自定义响应体的技术实现,请到自定义Response格式进行了解。

本项目提供的进阶功能,包括

  • 第三方组件汽车(Swagger、执行器等)
  • 自定义响应
  • 异常请求放行
  • 异常别名
  • 常用配置项

目前该组件在GitHub上已经有两百多Star,很多朋友已经开始用了,大家可以通过下方链接了解下:

  • https://github.com/feiniaojin/graceful-response


欢迎加入我的知识星球,全面提升技术能力。

👉 加入方式,长按”或“扫描”下方二维码噢

星球的内容包括:项目实战、面试招聘、源码解析、学习路线。

文章有帮助的话,在看,转发吧。

谢谢支持哟 (*^__^*)

微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
【旅游】蓝色海洋梦境:穿越地中海的美丽航程,戛纳始发,顺便体验电影节!马斯克:8月初开始第五次星间试飞:上海发布开放签署式人形机器人治理规则文件;米哈游《绝区零》下载量破5000万 | 极客早知道5大维度21项细分能力拿下国产大模型首位,文心一言还是那个老大SpringBoot + Minio 实现文件切片极速上传技术家里凌乱的注意啦!公开招200人学整理收纳!让家干净又宽敞,顺便get一门副业!《飞驰人生》影剧联动,阿里大文娱一盘“好棋”雷军:小米昌平手机工厂落成启用,生产即将发布的折叠机;苹果被曝在印度生产iPad丨智能制造日报气炸!多伦多男子车辆被偷,顺藤摸瓜找到贼窝!警方竟不理不睬...浦发银行陪伴科技企业成长 用心书写“科技金融”大文章澳大利亚悉尼“考10门AP5分根本没用!”泄题事件下AP出分,WLSA学姐分享选课&备考经验北雁南飞入悉尼(5)长八改又一大型地面试验,顺利完成!新进展!这条高铁隧道,顺利贯通俄罗斯首台光刻机问世,可生产350纳米芯片;Omdia:人工智能将加速RISC-V的应用丨智能制造日报推进“一三五”改革,中信股份着力金融五篇大文章、新质生产力AI早知道|抖音治理AI虚拟人;vivo开放蓝心大模型应用下载;百度推出Comate 2.0宏碁推出 Chromebook Plus Spin 714 与 516 GE 笔记本:为生产力与游戏打造等鱼Moomoo/富途牛牛投资账户【更新:1.5%转仓奖励 or 7股碎股赠股】大型银行 VS 中小银行:从不同视角解读“五篇大文章” | 直播预告周处除三害,胡因梦,灵修(3)战略领导力:领导者如何在既定条件下求解?极冷条件下,新的物质量子态是如何出现的?连续5年拿下藤校+Top10!第8年拿下康奈尔!这所广州老牌校的秘密是什么?AI早知道|首款AI智能环保管家“清云”;阿里大文娱推出智能创作分发平台宝马将向沈阳生产基地再投资200亿元,实现“新世代”车型的本土化生产探索新质生产力 | 王振耀: 从救灾帐篷功能定位看生产性和生活性服务业的升级路径蓝色海洋梦境:穿越地中海的美丽航程,戛纳始发,顺便体验电影节!GPT-4 Turbo首次被击败!国产大模型拿下总分第一17、长篇家庭伦理小说《嫁接 下》第五章 志同道合(2)钱要慢慢挣!法拉盛华男在便利店鬼鬼祟祟 警方顺藤摸瓜逮捕3人拿下!买大牌护肤品,洛杉矶奥莱直接2折起拿下,Lamer,兰蔻都有国家药监局关于优化已在境内上市的境外生产药品转移至境内生产的药品上市注册申请相关事项的公告金融行业 | 银行保险机构支持“五篇大文章”的路线图——金融监管总局2024年11号文解读
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。