【代码规范】统一参数校验、结果返回

news2024/11/24 12:08:06

统一参数校验:

        在编写Controller层的代码时,时常会有这种情况出现

@RestController
@RequestMapping("/user")
public class UserController {

    
    @Resource
    private UserService userService;


    @PostMapping("register")
    public String register(@RequestBody UserDto userDto){
        if (StringUtils.isEmpty(userDto.getName())) {
            return "用户名不能为空";
        }

        if(StringUtils.isEmpty(userDto.getPhone())){
            return "手机号不能为空";
        }

        if(userDto.getPhone().length() != 11){
            return "手机号格式不正确";
        }

        if(StringUtils.isEmpty(userDto.getEmail())){
            return "邮箱不能为空";
        }

        userService.register();
        
        return "注册成功";
    }


    @PutMapping("update")
    public String updateInfo(@RequestBody UserDto userDto){
        if (StringUtils.isEmpty(userDto.getName())) {
            return "用户名不能为空";
        }

        if(StringUtils.isEmpty(userDto.getPhone())){
            return "手机号不能为空";
        }

        if(userDto.getPhone().length() != 11){
            return "手机号格式不正确";
        }


        if(StringUtils.isEmpty(userDto.getEmail())){
            return "邮箱不能为空";
        }

        userService.updateInfo();
        
        return "修改成功";
    }
}

       在编写业务层组件实现真正的业务处理逻辑前,需要编写一大堆的参数校验逻辑。controller层可能有多个接口都需要进行参数校验,这样使得开发工作量加大、代码也不简洁。

解决方案: 

        (1)pom文件中引入spring-boot-starter-validation依赖

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

        (2)给实体类字段加上@NotNull注解

@AllArgsConstructor
@NoArgsConstructor
@Data
public class UserDto {

    @NotNull(message = "用户名不能为空")
    private String name;

    @NotNull(message = "手机号不能为空")
    @Pattern(regexp = "^[1][3,4,5,6,7,8,9][0-9]{9}$", message = "手机号格式不正确")
    private String phone;


    @NotNull(message = "邮箱不能为空")
    private String email;

    private Integer id;

    private Integer role;
    
}

        @NotNull字段不能为null,但可以是空(如"")。
        @Pattern^表示字符串的开头,1表示手机号码的开头数字是1,[3-9]表示第二位数字是3到9之间的数字,\d表示匹配一个数字,{9}表示匹配9个数字,$表示字符串的结尾。不符合正则表达式的手机号都会被视为格式不正确。

        (3)在controller层给数据传输对象(xxxDto)加上@Validated注解

@Resource
    private UserService userService;


@PostMapping("register")
    public String register(@RequestBody @Validated UserDto userDto,
                           BindingResult result){
        //如果校验不通过,则error对象不为空
        //返回错误信息即可
        for (ObjectError error : result.getAllErrors()) {
            return error.getDefaultMessage();
        }

        userService.add();

        return "注册成功";
    }

        当客户端调用此接口时,Validator会自动校验数据传输对象UserDto的参数,并将错误信息封装到BingdingResult对象中。getAllErrors()方法会返回一个元素是ObjectError的List集合,如果List集合不为空,说明有参数没有通过校验,返回错误信息即可。

        测试

        1、email为空

        我们可以发现,返回的错误信息其实就是我们在使用@NotNull注解时配置的message属性。

        2、手机号格式错误

        这里手机号是以数字2开头,而正则表达式规定了手机号只能以数字1开头。

统一结果返回:

        controller层返回请求处理结果时,会出现如下场景

@GetMapping("getString")
    public String getString(){
        
        return "hello world";
    }

    @GetMapping("getInfo")
    public UserDto getUserInfo(){
        UserDto response = new UserDto(3, "zhangsan", "15798403197", "hutu@163.com", 0);
        return response;
    }

        可以看到有些接口返回String字符串,有些接口返回数据传输对象(xxxDto),接口返回给前端的结果不统一,导致前端不能高效的处理响应数据。

解决方案

        标准的响应对象中应该包含响应状态码(code)处理结果描述(message)响应数据(data)等信息。

        (1)定义一个ProcessResult枚举类

public enum ProcessResult {

    SUCCESS("3333","操作成功"),

    FAIL("9999","操作失败"),

    SYSTEM_ERROR("6666","服务正忙,请稍后访问");


    private String code;

    private String message;


    ProcessResult(String code, String message) {
        this.code = code;
        this.message = message;
    }

    public String getCode() {
        return code;
    }

    public String getMessage() {
        return message;
    }
}

        (2)定义响应类BaseResponseVO

@Data
public class BaseResponseVO<T> {

    /**
     * 响应状态码
     * 3333:操作成功
     * 6666:系统错误
     * 9999:操作失败
     */
    private String code;


    /**
     * 处理结果描述
     */
    private String message;


    /**
     * 响应数据
     */
    private T data;


    /**
     * 成功返回
     * @param data:接口需要响应给前端的数据
     * @param <T>
     * @return
     */
    public static <T> BaseResponseVO<T> success(T data){
        BaseResponseVO<T> resp = success();
        resp.setData(data);
        return resp;
    }

    /**
     * 成功返回,但没有返回数据
     * @param <T>
     * @return
     */
    public static <T> BaseResponseVO<T> success(){
        BaseResponseVO resp = new BaseResponseVO();

        resp.setCode(ProcessResult.SUCCESS.getCode());
        resp.setMessage(ProcessResult.SUCCESS.getMessage());

        return resp;
    }

    /**
     * 失败返回
     * @param code:失败状态码
     * @param message:处理结果描述
     * @param <T>
     * @return
     */
    public static <T> BaseResponseVO<T> fail(String code,String message){
        BaseResponseVO resp = new BaseResponseVO();

        resp.setCode(code);
        resp.setMessage(message);

        return resp;
    }
}

        1、枚举类ProcessResult包含了响应状态码、处理结果描述等信息,我们如果需要多个不同的响应码及响应信息,可直接在枚举类中扩展。

        2、我们不能确定返回数据的类型,因此使用泛型来声明返回数据。

       3、 响应类BaseResponseVO提供了多个静态方法,我们可以根据处理结果调用相应的方法进行返回(成功且有返回数据:success(T data);成功但无返回数据:success();失败:fail(String code,String message))。

        (3)修改controller层代码

@GetMapping("getString")
    public BaseResponseVO<String> getString(){
        return BaseResponseVO.success("hello world");
    }

    @GetMapping("getInfo")
    public BaseResponseVO<UserDto> getUserInfo(){
        UserDto response = new UserDto(3, "zhangsan", "15798403197", "hutu@163.com", 0);
        return BaseResponseVO.success(response);
    }

        测试

        (1)getString接口

        (2)getInfo接口

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1327078.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【基础知识】大数据组件YARN简述

YARN是一个分布式的资源管理系统。 YARN是Hadoop系统的核心组件&#xff0c;主要功能包括负责在Hadoop集群中的资源管理&#xff0c;负责对作业进行调度运行以及监控。 ResourceManager 负责集群的资源管理与调度&#xff0c;为运行在YARN上的各种类型作业分配资源。 非HA集…

设计模式03结构型模式

结构型模式 参考网课:黑马程序员Java设计模式详解 博客笔记 https://zgtsky.top/ 结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式&#xff0c;前者采用继承机制来组织接口和类&#xff0c;后者釆用组合或聚合来组合对象。 由于…

通过讯飞 API 接口用 Vue 实现实时语音转写

通过讯飞 API 接口用 Vue 实现实时语音转写 项目地址 前言 本项目中实时语音能够转写的最大时间为 60 s&#xff0c; 这个数据也是由 API 提供方给限制掉的 为什么我会需要这个点击按钮以后能够实现实时语音的转写呢&#xff0c;因为被课程所迫&#xff0c;选了这个方向就必…

linux 性能优化-内存优化

CPU 管理一样&#xff0c;内存管理也是操作系统最核心的功能之一。内存主要用来存储系统和应 用程序的指令、数据、缓存等。 1.内存原理 1.1.内存映射 1.1.1.日常生活常说的内存是什么? 我的笔记本电脑内存就是 8GB 的这个内存其实是物理内存物理内存也称为主存&#xff0…

Java最全面试题专题---5、Spring面试题(1)

Spring概述&#xff08;10&#xff09; 什么是spring? Spring是一个轻量级Java开发框架&#xff0c;最早有Rod Johnson创建&#xff0c;目的是为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题。它是一个分层的JavaSE/JavaEE full-stack&#xff08;一站式&#xff…

联合体(C语言)

小伙伴们又来学习知识啦~&#xff0c;今天我要给大家介绍一下联合体的使用&#xff0c;话不多说&#xff0c;我们开始今天的正题吧&#xff01; 联合体的介绍 C语言的联合体&#xff08;union&#xff09;是一种特殊的数据类型&#xff0c;它可以在同一内存空间中存储不同的数…

龙迅LT86102UXE HDMI一分二HDMI,支持音频剥离,支持4K60HZ

描述&#xff1a; 龙迅 LT86102UXE HDMI2.0 分路器具有符合 HDMI2.0/1.4 规范的 1&#xff1a;2 分路器、最大 6Gbps 高速数据速率、自适应均衡 RX 输入和预加重 TX 输出&#xff08;用于支持长电缆应用&#xff09;、内部 TX 通道交换以实现灵活的 PCB 布线。 LT86102UXE HDM…

机器学习之线性回归(Linear Regression)附代码

概念 线性回归(Linear Regression)是机器学习中的一种基本的监督学习算法,用于建立输入变量(特征)与输出变量(目标)之间的线性关系。它假设输入变量与输出变量之间存在线性关系,并试图找到最佳拟合线来描述这种关系。 在简单线性回归中,只涉及两个变量:一个是自变量…

Ubuntu 常用命令之 passwd 命令用法介绍

&#x1f4d1;Linux/Ubuntu 常用命令归类整理 在Ubuntu系统中&#xff0c;passwd命令用于更改用户的密码。系统管理员可以使用此命令更改任何用户的密码&#xff0c;而普通用户只能更改自己的密码。 passwd命令的参数如下 -l, --lock&#xff1a;锁定密码&#xff0c;使账户…

Apache+PHP环境配置 手动配置

准备工作&#xff0c;在G盘新建一个WAMP目录 1.获取Apache 打开下载地址Apache VS17 binaries and modules download&#xff0c;下载 httpd-2.4.58-win64-VS17.zip 将下载好的httpd-2.4.58-win64-VS17.zip拷贝到G:\WAMP目录下并解压到当前目录&#xff0c;得到Apache24目录 …

石墨匣钵,预计到2025年将达到3.973亿美元

石墨匣钵是陶瓷和耐火材料工业用于烧制和烧结各种材料的高温容器。在陶瓷产品需求增加和耐火材料行业增长的推动下&#xff0c;全球石墨匣钵市场在过去几年出现了显着增长。2020 年全球石墨匣钵市场价值为 3.039 亿美元&#xff0c;预计到 2025 年将达到 3.973 亿美元&#xff…

找不到x3daudio1_7.dll文件的解决方法分享

今天我想和大家分享的是关于“找不到X3DAudio1_7.dll无法继续执行代码问题”的解决方法&#xff0c;以及X3DAudio1_7.dll丢失是什么意思&#xff0c;它的作用是什么&#xff0c;以及丢失对计算机有什么影响。 首先&#xff0c;我们来解释一下X3DAudio1_7.dll是什么。X3DAudio1…

Python Hook钩子函数详解

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 在Python编程中&#xff0c;Hook钩子函数是一种重要的编程机制&#xff0c;允许程序在运行时的特定点执行自定义代码&#xff0c;以修改或扩展程序的行为。本文将深入介绍Python中Hook钩子函数的基本概念、使用场…

Axure RP 8 for Mac/win中文版:打造完美交互式原型设计体验

Axure RP 8&#xff0c;一款引领潮流的交互式原型设计工具&#xff0c;为设计师提供了无限的可能性&#xff0c;让他们能够创造出逼真的原型&#xff0c;从而更好地展示和测试他们的设计。 Axure RP 8拥有丰富的功能和工具&#xff0c;让设计师可以轻松地创建出复杂的交互式原…

程序员的50大JVM面试问题及答案

文章目录 1.JDK、JRE、JVM关系&#xff1f;2.启动程序如何查看加载了哪些类&#xff0c;以及加载顺序&#xff1f;3. class字节码文件10个主要组成部分?4.画一下jvm内存结构图&#xff1f;5.程序计数器6.Java虚拟机栈7.本地方法栈8.Java堆9.方法区10.运行时常量池&#xff1f;…

DDPM推导笔记

各位佬看文章之前&#xff0c;可以先去看看这个视频&#xff0c;并给这位up主点赞投币&#xff0c;这位佬讲解的太好了&#xff1a;大白话AI 1.前置知识的学习 1.1 正态分布特性 ​ &#xff08;1&#xff09;正态分布的概率密度函数 f ( x ) 1 2 π σ e − ( x − μ ) …

day38 1220

作业1&#xff1a;select客户端 1 #include <myhead.h>2 #define SERPORT 88883 #define SERIP "192.168.125.159"4 5 #define CLIPORT 66666 #define CLIIP "192.168.125.159"7 8 int main(int argc, const char *argv[])9 {10 int ret -1;11 …

uni-app的初使用(附源码学习)

uni-app代码编写&#xff0c;基本语言包括js、vue、css。以及ts、scss等css预编译器。 新建项目等基础指路&#xff1a; 关于uni-app的下载及使用-CSDN博客 1.vue文件 由三个一级节点组成&#xff0c;分别是template、script、style <template> </template><…

机器学习 | 密度聚类和层次聚类

密度聚类和层次聚类 密度聚类 背景知识 如果 S 中任两点的连线内的点都在集合 S 内&#xff0c;那么集合 S称为凸集。反之&#xff0c;为非凸集。 DBSCAN 算法介绍 与划分和层次聚类方法不同&#xff0c;DBSCAN(Density-Based Spatial Clustering of Applications with Noi…

Jmeter插件技术:性能测试中服务端资源监控

过程中我们需要不断的监测服务端资源的使用情况&#xff0c;例如CPU、内存、I/O等。 Jmeter的插件技术可以很好的实时监控到服务器资源的运行情况&#xff0c;并以图形化的方式展示出来&#xff0c;非常方便我们性能测试分析。 操作步骤&#xff1a; 1、安装插件管理器 插件…