ToB企服应用市场:ToB评测及商务社交产业平台

标题: 【禁止血压飙升】阿里大佬写的 Controller 太优雅了! [打印本页]

作者: 汕尾海湾    时间: 2024-8-5 13:23
标题: 【禁止血压飙升】阿里大佬写的 Controller 太优雅了!
作者:小塵
链接:https://juejin.cn/post/7357172505961578511
前言

见过几千行代码的 controller吗?我见过。
见过全是 try catch 的 controller 吗,我见过。
见过全是字段校验的 controller 吗,我见过。
见过全是业务代码的 controller 吗?欠好意思,我们公司很多业务写在 controller 的。
看见这些我真的血压高。
正文

不优雅的 controller
  1. @RestController
  2. @RequestMapping("/user/test")
  3. public class UserController {
  4.     private static Logger logger = LoggerFactory.getLogger(UserController.class);
  5.     @Autowired
  6.     private UserService userService;
  7.     @Autowired
  8.     private AuthService authService;
  9.     @PostMapping
  10.     public CommonResult userRegistration(@RequestBody UserVo userVo) {
  11.         if (StringUtils.isBlank(userVo.getUsername())){
  12.             return CommonResult.error("用户名不能为空");
  13.         }
  14.         if (StringUtils.isBlank(userVo.getPassword())){
  15.             return CommonResult.error("密码不能为空");
  16.         }
  17.         logger.info("注册用户:{}" , userVo.getUsername());
  18.         try {
  19.             userService.registerUser(userVo.getUsername());
  20.             return CommonResult.ok();
  21.         }catch (Exception e){
  22.             logger.error("注册用户失败:{}", userVo.getUsername(), e);
  23.             return CommonResult.error("注册失败");
  24.         }
  25.     }
  26.     @PostMapping("/login")
  27.     @PermitAll
  28.     @ApiOperation("使用账号密码登录")
  29.     public CommonResult<AuthLoginRespVO> login(@RequestBody AuthLoginReqVO reqVO) {
  30.         if (StringUtils.isBlank(reqVO.getUsername())){
  31.             return CommonResult.error("用户名不能为空");
  32.         }
  33.         if (StringUtils.isBlank(reqVO.getPassword())){
  34.             return CommonResult.error("密码不能为空");
  35.         }
  36.         try {
  37.             return success(authService.login(reqVO));
  38.         }catch (Exception e){
  39.             logger.error("注册用户失败:{}", reqVO.getUsername(), e);
  40.             return CommonResult.error("注册失败");
  41.         }
  42.     }
  43. }
复制代码
Spring Boot 底子就不先容了,推荐看这个实战项目:
https://github.com/javastacks/spring-boot-best-practice
优雅的controller
  1. @RestController
  2. @RequestMapping("/user/test")
  3. public class UserController1 {
  4.     private static Logger logger = LoggerFactory.getLogger(UserController1.class);
  5.     @Autowired
  6.     private UserService userService;
  7.     @Autowired
  8.     private AuthService authService;
  9.     @PostMapping("/userRegistration")
  10.     public CommonResult userRegistration(@RequestBody @Valid UserVo userVo) {
  11.         userService.registerUser(userVo.getUsername());
  12.         return CommonResult.ok();
  13.     }
  14.     @PostMapping("/login")
  15.     @PermitAll
  16.     @ApiOperation("使用账号密码登录")
  17.     public CommonResult<AuthLoginRespVO> login(@RequestBody @Valid AuthLoginReqVO reqVO) {
  18.         return success(authService.login(reqVO));
  19.     }
  20. }
复制代码
代码量直接减一半呀,这还不算上有些直接把业务逻辑写在 controller 的,看到这些我真的直接吐血
改造流程

校验方式

这个 if 校验看得我哪哪都不爽。好歹给我写一个断言吧。Assert.notNull(userVo.getUsername(), "用户名不能为空");
这不香吗?确实不香。
使用 spring 提供的@Valid
在入参时使用@Valid注解,而且在 vo 中使用校验注解,如AuthLoginReqVO
  1. @ApiModel(value = "管理后台 - 账号密码登录 Request VO")
  2. @Data
  3. @NoArgsConstructor
  4. @AllArgsConstructor
  5. @Builder
  6. public class AuthLoginReqVO {
  7.     @ApiModelProperty(value = "账号", required = true, example = "user")
  8.     @NotEmpty(message = "登录账号不能为空")
  9.     @Length(min = 4, max = 16, message = "账号长度为 4-16 位")
  10.     @Pattern(regexp = "^[A-Za-z0-9]+$", message = "账号格式为数字以及字母")
  11.     private String username;
  12.     @ApiModelProperty(value = "密码", required = true, example = "password")
  13.     @NotEmpty(message = "密码不能为空")
  14.     @Length(min = 4, max = 16, message = "密码长度为 4-16 位")
  15.     private String password;
  16. }
复制代码
@Valid

在SpringBoot中,@Valid是一个非常有用的注解,紧张用于数据校验。以下是关于@Valid的一些详细信息:
全局异常处理

这个全局异常处理,可以根据本身的异常,自定义异常处理,并设置一个兜底的异常处理
  1. @ResponseBody
  2. @RestControllerAdvice
  3. public class ExceptionHandlerAdvice {
  4.     protected Logger logger = LoggerFactory.getLogger(getClass());
  5.     @ExceptionHandler(MethodArgumentNotValidException.class)
  6.     public CommonResult<Object> handleValidationExceptions(MethodArgumentNotValidException ex) {
  7.         logger.error("[handleValidationExceptions]", ex);
  8.         StringBuilder sb = new StringBuilder();
  9.         ex.getBindingResult().getAllErrors().forEach(error -> {
  10.             String fieldName = ((org.springframework.validation.FieldError) error).getField();
  11.             String errorMessage = error.getDefaultMessage();
  12.             sb.append(fieldName).append(":").append(errorMessage).append(";");
  13.         });
  14.         return CommonResult.error(sb.toString());
  15.     }
  16.     /**
  17.      * 处理系统异常,兜底处理所有的一切
  18.      */
  19.     @ExceptionHandler(value = Exception.class)
  20.     public CommonResult<?> defaultExceptionHandler(Throwable ex) {
  21.         logger.error("[defaultExceptionHandler]", ex);
  22.         // 返回 ERROR CommonResult
  23.         return CommonResult.error(INTERNAL_SERVER_ERROR.getCode(), INTERNAL_SERVER_ERROR.getMsg());
  24.     }
  25. }
复制代码
就这么多,搞定,这样就拥有了漂流优雅的 controller 了
在一样平常开发中,另有那些血压飙升瞬间

我拿出下图阁下如何面对

这个阁下又如何面对,我不说,你能知道这个什么吗【狗头】

总结

更多文章推荐:
1.Spring Boot 3.x 教程,太全了!
2.2,000+ 道 Java面试题及答案整理(2024最新版)
3.免费获取 IDEA 激活码的 7 种方式(2024最新版)
以为不错,别忘了顺手点赞+转发哦!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4