Spring Boot项目结构
一个简单Spring Boot项目的目录结构如下图
Java代码都在src/main/java/
目录下,src/main/resources/
中放置资源文件。
代码结构
common/
: 存放通用类,如工具类和通用返回结果
config/
: 存放配置文件
controller/
: 存放控制器,接收从前端传来的参数,对访问控制进行转发、各类基本参数校验或者不复用的业务简单处理等。
dao/
: 数据访问层,与数据库进行交互,负责数据库操作,在Mybaits框架中存放自定义的Mapper接口
entity/
: 存放实体类
interceptor/
: 拦截器
service/
: 存放服务类,负责业务模块逻辑处理。Service
层中有两种类,一是Service
,用来声明接口;二是ServiceImpl
,作为实现类实现接口中的方法。
utils/
: 存放工具类
NewBeeMallApplication.java
: Spring Boot启动类
非该项目,但可能存在的文件夹:
dto/
: 存放数据传输对象(Data Transfer Object),如请求参数和返回结果
vo/
: 视图对象(View Object)用于封装客户端请求的数据,防止部分数据泄漏,保证数据安全
constant/
: 存放常量
filter/
: 存放过滤器
component/
: 存放组件
资源目录结构
在src/main/resources
下存放资源文件
mapper/
: 存放Mybaits的mapper.xml文件
static/
: 静态资源文件目录(Javascript、CSS、图片等),在这个目录中的所有文件可以被直接访问
templates/
: 存放模版文件
application.properties
: Spring Boot默认配置文件
非该项目,但可能存在的文件:
META-INF/
: 相当于一个信息包,目录中的文件和目录获得Java 2平台的认可与解释,用来配置应用程序、扩展程序、类加载器和服务
i18n/
: 国际化文件的简称,来源是英文单词internationalization的首末字符i和n,18为中间的字符数
其他结构
⚠️ Spring Boot无需配置 web.xml
,但在其他Java项目中,web.xml
是一个非常重要的文件,用来配置Servlet、Filter、Listener等。
pom.xml
: maven的配置文件,记录项目信息、依赖信息、构建配置等
如果使用gradle进行自动化构建,则会存在build.gradle
文件
请求传递流程
Java审计难上手的一大因素是Java一般都是大中型系统,架构相比于PHP开发的小系统会复杂很多,大型系统开发过程中难免出现不规范的编码习惯,再加上函数调用错综复杂,审计代码时光弄明白程序逻辑,理解程序员的编码习惯就要花费大量精力了。
首先弄明白请求流程的处理,知道用户请求内容会经过哪些代码才能理解程序处理逻辑,可以对我们后续的审计提供非常大的帮助。
用户的请求发送给服务器之后,中间件(案例项目使用的是Tomcat)会将请求解析发送给Spring的DispatcherServlet
,DispatcherServlet
的作用是分配请求,详细的过程我们暂时不深入。只需要知道中间件解析请求之后请求会经过Filter和Interceptor。Filter(过滤器)和Interceptor(拦截器)做的事很相似,但他们的触发时机不同,且Interceptor只在Spring中生效,它们可以用来对请求进行过滤字符、拦截、鉴权、日志记录等功能,简单说就是可以在参数进入应用前对其处理,做到全局的处理。
请求经过Filter和Interceptor之后会被DispatcherServlet
分配到对应路径的Controller(控制器),文件名为ExampleController
,Controller负责简单的逻辑处理和参数校验功能,之后调用Service。
Service主要负责业务模块逻辑处理。Service层中有两种类,一是接口类,文件名为ExampleService
,用来声明接口;二是接口实现类,文件名为ExampleServiceImpl
,作为实现类实现接口中的方法。实现的代码都在ExampleServiceImpl
中。当Service涉及到数据库操作时就会调用Dao。
Dao主要负责数据库的操作,由于使用Mybatis作为ORM框架,只做中间传递的作用,所有SQL语句都是写在配置文件中的,配置文件名为ExampleMapper.xml
,存放在src/main/resources/mapper
中。
从用户请求到服务器处理的主要过程如下图所示(省略了DispatcherServlet
):
为了更好理解,以「保存订单」功能为例,主要的请求流程如下图,不了解Spring请求传递的同学可以在代码中跟一遍请求流程,会加深请求传递的印象。