谈谈对spring boot分层中各层的理解
1 Dao层:持久层,主要是和数据库进行交互
dao层首先胡创建dao接口,接着就可以在配置文件中定义该接口的实现类;接着就可以在模块中调用dao的接口进行数据业务的处理,而不用关注此接口的具体实现是哪一个类,dao层的数据源和数据库实在配置文件中进行配置的。
2 Entity层:实体层,数据库在项目中的类
主要用于定义与数据库对象的属性,提供get/set方法,带参和无参的构造方法。
3 Service层:业务层控制业务
业务模块的逻辑应用设计,和DAO层一样都是先设计接口,再创建要实现的类,然后在配置文件中进行配置其实现的关联。接下来就可以在service层调用接口进行业务逻辑应用的处理。
好处:封装Service层的业务逻辑有利于业务逻辑的独立性和重复利用性。
4.Controller层:控制层 控制业务逻辑
具体的业务模块流程的控制,controller层主要调用Service层里面的接口控制具体的业务流程,控制的配置也要在配置文件中进行。
Controller和Service的区别是:Controller负责具体的业务模块流程的控制;Service层负责业务模块的逻辑应用设计
总结:具体的一个项目中有:controller层调用了Service层的方法,Service层调用Dao层的方法,其中调用的参数是使用Entity层进行传递的。
补充:5、View层 此层与控制层结合比较紧密,需要二者结合起来协同工发。View层主要负责前台jsp页面的表示
Spring Boot 业务逻辑层
关于业务逻辑层(Service层)
业务逻辑层是被Controller直接调用的层(Controller不允许直接调用持久层),通常,在业务逻辑层中编写的代码是为了 保证数据的完整性和安全性 ,使得数据是随着我们设定的规则而产生或发生变化。
通常,在业务逻辑层的代码会由接口和实现类组件,其中, 接口被视为是必须的
关于抛出的异常,通常是自定义的异常,并且, 自定义异常 通常是`RuntimeException`的子类,主要原因:
所以,在实际编写业务逻辑层之前,应该先规划异常,例如先创建` ServiceException `类:
接下来,再创建具体的对应某种“失败”的异常,例如,在添加管理员时,可能因为“用户名已经存在”而失败,则创建对应的 `UsernameDuplicateException`异常 :
另外,当插入数据时,如果返回的受影响行数不是1时,必然是某种错误,则 创建对应的插入数据异常 :
关于抽象方法的参数,应该设计为客户端提交的数据类型或对应的封装类型,不可以是数据表对应的实体类型!如果使用封装的类型,这种类型在类名上应该添加某种后缀,例如` DTO`或其它后缀 ,例如:
并在以上`service`包下创建`impl`子包,再创建`AdminServiceImpl`类:
以上代码未实现对密码的加密处理! 关于密码加密 ,相关的代码应该定义在别的某个类中,不应该直接将加密过程编写在以上代码中,因为加密的代码需要在多处应用(添加用户、用户登录、修改密码等),并且,从分工的角度上来看,也不应该是业务逻辑层的任务!所以,在`cn.celinf.boot.demo.util`(包不存在,则创建)下创建`PasswordEncoder`类,用于处理密码加密:
完成后,需要在`AdminServiceImpl`中自动装配以上`PasswordEncoder`,并在需要加密时调用`PasswordEncoder`对象的`encode()`方法。
控制器层开发
Spring MVC是用于处理控制器层开发的,在使用Spring Boot时,在`pom.xml`中添加`spring-boot-starter-web`即可整合Spring MVC框架及相关的常用依赖项(包含`jackson-databind`),可以将已存在的`spring-boot-starter`直接改为`spring-boot-starter-web`,因为在`spring-boot-starter-web`中已经包含了`spring-boot-starter`。
先在项目的根包下创建`controller`子包,并在此子包下创建`AdminController`,此类应该添加 `@RestController` 和` @RequestMapping (value = "/admins", produces = "application/json; charset=utf-8")`注解,例如:
由于已经决定了服务器端响应时,将响应JSON格式的字符串,为保证能够响应JSON格式的结果,处理请求的方法返回值应该是自定义的数据类型,则从此前学习的`spring-mvc`项目中找到`JsonResult`类及相关类型,复制到当前项目中来。
完成后,运行启动类,即可启动整个项目,在`spring-boot-starter-web`中,包含了Tomcat的依赖项,在启动时,会自动将当前项目打包并部署到此Tomcat上,所以,执行启动类时,会执行此Tomcat,同时,因为是内置的Tomcat,只为当前项目服务,所以,在将项目部署到Tomcat时,默认已经将Context Path(例如spring_mvc_war_exploded)配置为空字符串,所以,在启动项目后,访问的URL中并没有此前遇到的Context Path值。
当项目启动成功后,即可在浏览器的地址栏中输入网址进行测试访问!
【注意】 :如果是未添加的管理员账号,可以成功执行结束,如果管理员账号已经存在,由于尚未处理异常,会提示500错误。
然后,在`cn.celinf.boot.demo.controller`下创建`handler.GlobalExceptionHandler`类,用于统一处理异常,例如:
完成后,重新启动项目,当添加管理员时的用户名没有被占用时,将正常添加,当用户名已经被占用时,会根据处理异常的结果进行响应!
由于在 统一处理异常的机制下 ,同一种异常,无论是在哪种业务中出现,处理异常时的描述信息都是完全相同的,也无法精准的表达错误信息,这是不合适的!另外,基于面向对象的“分工”思想,关于错误信息(异常对应的描述信息),应该是由Service来描述,即“谁抛出谁描述”,因为抛出异常的代码片段是最了解、最明确出现异常的原因的!
为了更好的描述异常的原因,应该在自定义的`ServiceException`和其子孙类异常中添加基于父类的全部构造方法(5个),然后,在`AdminServiceImpl`中,当抛出异常时,可以在异常的构造方法中添加`String`类型的参数,对异常发生的原因进行描述,例如:
最后,在处理异常时,可以 调用异常对象的`getMessage()`方法获取抛出时封装的描述信息 ,例如:
完成后,再次重启项目,当用户名已经存在时,可以显示在Service中描述的错误信息!
可以看到,无论是成功还是失败, 响应的JSON中都包含了不必要的数据 (为`null`的数据),这些数据属性是没有必要响应到客户端的,如果需要去除这些不必要的值,可以在对应的属性上使用注解进行配置,例如:
此注解还可以添加在类上,则作用于当前类中所有的属性,例如:
即使添加在类上,也只对当前类的3个属性有效,后续,当响应某些数据时,`data`属性可能是用户、商品、订单等类型,这些类型的 数据中为`null`的部分依然会被响应到客户端 去,所以,还需要对这些类型也添加相同的注解配置!
以上做法相对比较繁琐,可以在`application.properties` / `application.yml`中添加全局配置,则作用于当前项目中所有响应时涉及的类,例如在`properties`中配置为:
注意:当你需要在`yml`中添加以上配置时,前缀属性名可能已经存在,则不允许出现重复的前缀属性名的:
最后,以上配置只是“默认”配置,如果在某些类型中还有不同的配置需求,仍可以在类或属性上通过 `@JsonInclude`进行配置 。
15. 解决跨域问题
在使用前后端分离的开发模式下,前端项目和后端项目可能是2个完全不同的项目,并且,各自己独立开发,独立部署,在这种做法中,如果前端直接向后端发送异步请求,默认情况下,在前端会出现类似以下错误:
以上错误信息的关键字是`CORS`,通常称之为 “跨域问题” 。
在基于Spring MVC框架的项目中,当需要解决跨域问题时,需要一个Spring MVC的配置类(实现了`WebMvcConfigurer`接口的类),并重写其中的方法,以允许指定条件的跨域访问,例如:
16. 关于客户端提交请求参数的格式
通常,客户端向服务器端发送请求时,请求参数可以有2种形式,第1种是直接通过``拼接各参数与值,例如:
具体使用哪种做法,取决于服务器端的设计:
- 如果服务器端处理请求的方法中,在参数前添加了`@RequestBody`,则允许使用以上第2种做法(JSON数据)提交请求参数,不允许使用以上第1种做法(使用``拼接)
- 如果没有使用 `@RequestBody`,则只能使用以上第1种做法
springboot vue后端有几层
有4层。
控制层_调用业务层方法来控制业务逻辑,controller层的功能为请求和响应控制,controller层负责前后端交互,接受前端请求,调用service层,接收service层返回的数据,最后返回具体的页面和数据到客户端。
Spring Boot项目目录结构
根目录: com.example.demo
1)启动类( gApplication.java )
推荐放在根目录com.example.demo包下
2)实体类( domain )
3)数据接口访问层( Dao )
4)数据服务接口层( Service )推荐:com.example.demo.service
5)数据服务实现层( Service Implements )推荐:com.example.demo.service.impl
使用idea的同学推荐使用com.example.demo.serviceImpl目录
6)前端控制器层( Controller )推荐:com.example.demo.controller
7)工具类库( utils )推荐:com.example.demo.utils
8)配置类( config )推荐:com.example.demo.config
9)数据传输对象( dto )推荐:com.example.demo.dto
10)视图包装对象( vo )推荐:com.example.demo.vo
根目录: resources
1) 项目配置文件 :resources/application.yml
2) 静态资源目录 :resources/static/
用于存放html、css、js、图片等资源
3) 视图模板目录 :resources/templates/
用于存放jsp、thymeleaf等模板文件
4) mybatis映射文件 :resources/mapper/(mybatis项目)
5) mybatis配置文件 :resources/mapper/config/(mybatis项目)