Java SpringBoot框架代码审计二 - Spring Boot项目结构介绍

Spring Boot项目结构

一个简单Spring Boot项目的目录结构如下图

springboot-directory

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的DispatcherServletDispatcherServlet的作用是分配请求,详细的过程我们暂时不深入。只需要知道中间件解析请求之后请求会经过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):

request-path

为了更好理解,以「保存订单」功能为例,主要的请求流程如下图,不了解Spring请求传递的同学可以在代码中跟一遍请求流程,会加深请求传递的印象。

request-example