[SpringBoot]Service与Controller层

news2025/1/12 18:17:52

目录

关于Service

关于Controller

关于各组件的处理流程

补充:

Service保证数据完整性是怎么体现的?

 以下代表复制属性,把来源adminAddNewParam复制到目标 admin里面


关于Service

Service的核心价值在于:组织业务流程,处理业务逻辑,以保证数据的完整性、有效性、安全性。

在编写代码时,强烈建议先定义Service的接口,然后,自定义编写其实现类。  

关于“新增相册”,先自定义POJO类,用于封装相关参数!在项目的根包下创建pojo.param.AlbumAddNewParam类:

@Data
public class AlbumAddNewParam implements Serializable {
    private String name;
    private String description;
    private Integer sort;
}

然后,在项目的根包下创建service.IAlbumService,并在接口中添加“新增相册”的抽象方法:

public interface IAlbumService {
    void addNew(AlbumAddNewParam albumAddNewParam);
}

然后,在项目的根包下创建service.impl.AlbumServiceImpl类,实现以上接口:

public class AlbumServiceImpl implements IAlbumService {}

关于Service方法的声明:

  • 返回值类型:仅以操作成功为前提来设计返回值

    • 操作失败全部通过抛出异常来表示

  • 方法名称:自定义

  • 参数列表:如果参数数量较多,且具有相关性,可以封装,如果参数数量较少,或不具备相关性,则逐一声明

  • 抛出异常:抛出所有遇到的异常,如果只会出现RuntimeException,并不需要使用throws关键字显式的声明 

在具体实现之前,为了明确的表示出错的原因是因为所设计的规则,应该先自定义异常类型,并且,在规则验证不通过时,抛出自定义异常类型,后续,在调用此方法时,根据是否抛出了自定义异常类型来判断是否符合所设计的规则。

在项目的根包下创建ex.ServiceException类,继承自RuntimeException类,并添加基于父级异常的、带String message参数的构造方法:

public class ServiceException extends RuntimeException {

    public ServiceException(String message) {
        super(message);
    }
    
}

关于自定义异常需要继承自RuntimeException,原因主要有2点:

  • 如果继承的不是RuntimeException,抛出异常的方法必须显式的使用throws声明抛出,并且,Service方法的调用者(Controller)也必须在代码中明确的try...catchthrows,而开发实践中,会使用Spring MVC框架的全局异常处理机制来统一处理异常,则Service、Controller等组件都必须将异常抛出,这是固定的做法,所以,没有必要继承自非RuntimeException并反复声明抛出异常

  • 基于Spring JDBC的事务管理将根据RuntimeException进行回滚

然后,在AlbumServiceImpl类上添加@Service注解,在类中自动装配AlbumMapper类型的属性,并实现接口中定义的抽象方法,在实现过程中,如果判断违背了所设计的规则,应该抛出自定义的ServiceException类型的异常对象:  

@Service
public class AlbumServiceImpl implements IAlbumService {

    @Autowired
    private AlbumMapper albumMapper;

    @Override
    public void addNew(AlbumAddNewParam albumAddNewParam) {
        // 检查相册名称是否被占用,如果被占用,则抛出异常
        QueryWrapper<Album> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", albumAddNewParam.getName()); // name='参数中的相册名称'
        int countByName = albumMapper.selectCount(queryWrapper);
        if (countByName > 0) {
            String message = "添加相册失败,相册名称已经被占用!";
            // System.out.println(message);
            throw new ServiceException(message);
        }

        // 将相册数据写入到数据库中
        Album album = new Album();
        BeanUtils.copyProperties(albumAddNewParam, album);
        album.setGmtCreate(LocalDateTime.now());
        album.setGmtModified(LocalDateTime.now());
        albumMapper.insert(album);
    }

}

完成后,应该在src/test/java下的根包下创建service.AlbumServiceTests测试类,测试以上方法:

@SpringBootTest
public class AlbumServiceTests {

    @Autowired
    IAlbumService service;

    @Test
    void addNew() {
        AlbumAddNewParam albumAddNewParam = new AlbumAddNewParam();
        albumAddNewParam.setName("测试数据-00003");
        albumAddNewParam.setDescription("测试数据简介-00003");
        albumAddNewParam.setSort(99);

        try {
            service.addNew(albumAddNewParam);
            System.out.println("添加成功!");
        } catch (ServiceException e) {
            System.out.println(e.getMessage());
        } catch (Throwable e) {
            System.out.println("添加失败!出现了某种异常!");
            e.printStackTrace();
        }
    }

}

关于Controller

通过控制器接收并处理请求

在通过控制器处理请求之前,需要添加对应的依赖项:spring-boot-starter-web。  

提示:所有Spring提供的以spring-boot-starter作为名称前缀的依赖项(例如spring-boot-starter-web),都包含了Spring Boot的基础依赖项(spring-boot-starter)。

则将项目中原本依赖的spring-boot-starter改为spring-boot-starter-web

在项目的根包下创建cn.tedu.csmall.product.controller.AlbumController,在类中添加方法处理“添加相册”的请求:

@RestController
@RequestMapping("/album")
public class AlbumController {

    @Autowired
    private IAlbumService albumService;

    // http://localhost:8080/album/add-new?name=TestName001&description=TestDescription001&sort=99
    @RequestMapping("/add-new")
    public String addNew(AlbumAddNewParam albumAddNewParam) {
        try {
            albumService.addNew(albumAddNewParam);
            return "添加成功!";
        } catch (ServiceException e) {
            return e.getMessage();
        } catch (Throwable e) {
           return "添加失败!出现了某种异常!";
        }
    }

}

完成后,启动项目,在浏览器的地址栏中使用 http://localhost:8080/album/add-new?name=TestName001&description=TestDescription001&sort=99 即可测试访问。

 


关于各组件的处理流程


补充:

Service保证数据完整性是怎么体现的?

用户提交的数据不够表中的字段时,就需要我们在Service层进行补全,普通用户操作界面提交的数据就是不完整的,因为有一部分数据我们不放心他去提交,比如时间。但是他不提提交,数据库里面又有,我们就去补全。

 以下代表复制属性,把来源adminAddNewParam复制到目标 admin里面

BeanUtils.copyProperties(adminAddNewParam, admin);

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

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

相关文章

gaussDB的schema创建查询,及其查询下面的表列,修改列类型

修改列类型与众不同 alter table adqm_safe_data_encrypt_job_instance alter COLUMN state TYPE INT4 alter COLUMN state TYPE INT4 pg_catalog.pg_namespace来查看当前数据库中全部的Schema select oid,* from pg_catalog.pg_namespace; 创建schema create schema gs_d…

vscode 配置rust、golang代码格式化方法

一共分三步&#xff1a; 点击左下角齿轮按钮&#xff0c;点击Settings&#xff0c;如下图&#xff1a;点击右上角切换到Settings.json文件。如下图增加rust、golang 配置如下&#xff0c;假如存在默认格式化配置请注释或删除。重启vscode ide&#xff0c;​尝试编写rust、gola…

HTML5+CSS3+JS小实例:简约的垂直选项卡

实例:简约的垂直选项卡 技术栈:HTML+CSS+JS 字体图标库:font-awesome 效果: 源码: 【html】 <!DOCTYPE html> <html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta name="v…

【LED子系统深度剖析】八、小试牛刀

个人主页:董哥聊技术 我是董哥,高级嵌入式软件开发工程师,从事嵌入式Linux驱动开发和系统开发,曾就职于世界500强公司! 创作理念:专注分享高质量嵌入式文章,让大家读有所得! 文章目录 1、硬件管脚确定2、设备树配置3、子系统配置4、编译烧录5、验证5.1 设备树验证5.2 驱…

MySQL — 主从复制介绍

文章目录 主从复制一、概述二、原理三、 搭建主从复制结构3.1 服务器准备3.2 主库配置3.3 从库配置 主从复制 一、概述 ​ 主从复制是指将主数据库的DDL和DML操作通过二进制日志传到从库服务器中&#xff0c;然后在从库上对这些日志重新执行&#xff08;也叫重做&#xff09;…

16-Vue3中常用的 Composition API

目录 1、什么是组合式 API&#xff1f;2、拉开序幕的setup3、ref函数4、reactive函数5、Vue3.0中的响应式原理5.1 vue2.x的响应式5.2 Vue3.0的响应式 6、reactive对比ref7、setup的两个注意点8、计算属性与监视8.1 computed函数8.2 watch函数8.3 watchEffect函数 9、 生命周期1…

chatgpt赋能python:用Python编写AI:从入门到精通

用Python编写AI&#xff1a;从入门到精通 人工智能&#xff08;AI&#xff09;一直是计算机科学领域的热门话题。随着AI技术的成熟&#xff0c;越来越多的公司开始在其业务中应用AI。Python是机器学习和人工智能领域最流行的编程语言之一&#xff0c;Python提供了众多强大的库…

探索C++与Live555实现RTSP服务器的艺术

探索C与Live555实现RTSP服务器的艺术 一、引言&#xff08;Introduction&#xff09;1.1 RTSP服务器的重要性&#xff08;Importance of RTSP Server&#xff09;1.2 C与Live555库的优势&#xff08;Advantages of C and Live555&#xff09;1.3 可能用到的类和接口介绍 二、C与…

LLM时代,探索式数据分析的升级之路有哪些新助攻?

在这个信息爆炸的时代&#xff0c;数据已经成为我们生活、工作中不可或缺的重要资源。大量的数据犹如一座座金矿&#xff0c;蕴藏着无尽的价值。然而&#xff0c;如果无法从数据中提取出知识和信息并加以有效利用&#xff0c;那么数据本身并不能驱动和引领技术应用取得成功。如…

Java程序设计入门教程 -- 一维数组

目录 一维数组创建 1.声明数组 2.分配数组内存空间 3.数组元素访问 数组初始化 1.静态初始化 2.动态初始化 一维数组的拷贝 1.数组元素的拷贝 2.数组名的拷贝 一维数组创建 1.声明数组 声明一个一维数组的方法很简单&#xff0c;格式如下&#xff1a; 数据类型名[ ] …

解决使用json配置文件删除k8s中namespace解析json报错的问题

报错提示如下&#xff1a; C:\Users\jiangcheng>curl -k -H "Content-Type: application/json" -X PUT --data-binary dev.json http://127.0.0.1:8081/api/v1/namespaces/dev/finalize { "kind": "Status", "apiVersion": "…

Unity2D骨骼动画制作之单张图片编辑

1、打开骨骼制作面板 在Sprite Editor左侧选项&#xff0c;选择Skinning Editor 2、 &#xff08;1&#xff09;骨骼制作 Preview Pose 预览模式&#xff0c;可以预览动作并不会真正的改变设置 Reset Pose 将角色骨骼和关节恢复到原始位置 Edit Bone 编辑骨骼&#xff0c;…

bert中文文本摘要代码(3)

bert中文文本摘要代码 写在最前面关于BERT使用transformers库进行微调 train.py自定义参数迭代训练验证评估更新损失绘图主函数 test.pytop_k或top_p采样sample_generate函数generate_file函数主函数 写在最前面 熟悉bert&#xff0b;文本摘要的下游任务微调的代码&#xff0c…

网络安全合规-数据出境安全评估

&#xff08;一&#xff09;数据出境安全评估的适用范围为&#xff1a; 数据处理者向境外提供重要数据&#xff1b; 关键信息基础设施运营者和处理100万人以上个人信息的数据处理者向境外提供个人信息&#xff1b;自上年1月1日起累计向境外提供10万人个人信息或者1万人敏感个…

浮点数在内存中的存储

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:C语言学习分享⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习更多C语言知识   &#x1f51d;&#x1f51d; 浮点数在内存的存储 1. 前言&#…

vue3+WebRTC拉流(正确姿势)

vue3WebRTC拉流&#xff08;正确姿势&#xff09; 文章目录 vue3WebRTC拉流&#xff08;正确姿势&#xff09;缘由一、webRtc拉流是什么&#xff1f;1.实时通信&#xff1a;2.网络穿越&#xff1a;3.媒体处理&#xff1a;4.数据通道&#xff1a;5.使用场景: 二、使用webRtc引用…

《priority_queue的模拟实现》

本文主要介绍 文章目录 一、仿函数1.1 仿函数的定义1.2 普通仿函数1.3 需要自己实现仿函数 二、priority_queue的模拟实现 一、仿函数 1.1 仿函数的定义 所谓的仿函数(functor)&#xff0c;是通过重载()运算符模拟函数形为的类。 因此&#xff0c;这里需要明确两点&#xff1…

纯干货:数据库连接耗时慢原因排查

背景 最近公司的社区相关的服务需要优化&#xff0c;由于对业务不熟悉&#xff0c;只能借助监控从一些慢接口开始尝试探索慢的原因。由于社区相关的功能务是公司小程序流量入口&#xff0c;所以相应的服务访问量还是比较高的。针对这类高访问的项目&#xff0c;任何不留神的地…

中睿天下参编的《中国网信产业桔皮书-数据安全》正式发布

5月28日&#xff0c;2023中关村论坛中关村国际技术交易大会第七届中国网信产业前锋汇成功举办&#xff0c;本次会议以“全球数字经济发展与数据安全关键技术”为主题&#xff0c;会议由中国&#xff08;中关村&#xff09;网络安全与信息化产业联盟主办&#xff08;以下简称联盟…

芯片的XIP与BootRom启动方式

XIP&#xff1a;execute in place&#xff0c;就地执行&#xff0c;即芯片内执行&#xff0c;指应用程序可以直接在flash闪存中取指然后译码、执行&#xff0c;不必再把代码读到系统RAM中&#xff0c;flash内执行时指Nor flash不需要初始化&#xff0c;可以直接在flash内执行代…