目录
(2)、@ToString :编译时候自动生成toString方法
(3)、@AllArgsConstructor: 自动生成全参构造方法
(4)、@NoArgsConstructor :自动生成无参构造方法
(5)、@EqualsAndHashCode:重写equals和 Hashcode方法
(1)、 @ConditionalOnBean(name = "tocatPet" ) :
(2)、@ConditionalOnMissingBean:如果没有某个容器才注册组件当前bean
(7)、 @Timeout(value = 500,unit= TimeUnit.MILLISECONDS)
一、插件类型
1、lombok插件
作用:简化bean
(1)、@Data:自动生成get、set方法
(2)、@ToString :编译时候自动生成toString方法
(3)、@AllArgsConstructor: 自动生成全参构造方法
(4)、@NoArgsConstructor :自动生成无参构造方法
(5)、@EqualsAndHashCode:重写equals和 Hashcode方法
2、日志
@Slf4j 注解
可以使用
public Person getPersom(){
System.out.println("名字:"+person.getUserName());
// {}符号为后面的value占位
log.info("UserName:{}",person.getUserName());
return person;
}
lon.info("vlaue的值为:{}",value)
{} 符号为后面的value占位
二、SpringBoot底层核心注解
1、@RestController
是 @ResponseBody和 @Controller的组合注解
(1)、@ResponseBody:直接向浏览器传输数据(会转化为json数据)
标识在方法上:表示当前方法是直接向浏览器传输数据
标识在类上:表示当前类中所有方法是直接向浏览器传输数据
(2)、@Controller 把当前类声名为控制层
2、@SpringBootApplication
声名当前类是SpringBoot主配置类,也是表示当前项目的入口
它有scanBasePackages属性,来表示扫描项目中的组件
默认扫描当前类所在的包以及其子包
自定义扫描包需要修改@SpringBootApplication(scanBasePackages = "com.at") com.a为包路径
@SpringBootApplication是三个的结合(了解):
(1) @SpringBootConfiguration:表示这是配置类
(2)@EnableAutoConfiguration :
@AutoConfigurationPackage: 利用Registrar给容器中导入一系列 组 件,将指定的一个包下(默认MainApplication包)的所有组件导入进来
(3)、 @ComponentScan :指定扫描包
配置取值步骤: xxxAutoConfiguration-->组件-->xxxProperties里面拿值-->application.properties(自定义)
3、@Configuration
告诉SpringBoot这是一个配置类(也是一个组件)== 配置文件
它有proxyBeanMethods 属性
@Configuration(proxyBeanMethods = true)代理对象调用方法,方法返回值都是同一个
@Configuration(proxyBeanMethods = false):新的对象方法
它默认是true,即默认是单例,无论外部调用多少次获取的都是之前注册容器中的单例对象
4、@Bean
给容器添加组件,默认以方法名字作为组键的id。返回类型就是组件在容器的实例
常标注在@Configuration 配置类的方法中 来给容器添加bean
@Bean("tom")自定义id为tom
@Configuration(proxyBeanMethods = true) 是默认的,会使添加的bean在创建中是单例
5、@Import
@Import({User.class})
依附,给容器中自动创建出这个类型的组件, 默认组件的名字是全类名(路径包)
6、条件装配有关注解
(1)、 @ConditionalOnBean(name = "tocatPet" ) :
标识在方法前: 如果有某个容器才注册组件当前bean (参数中的限定条件和上下文顺序有关)
标识在配置类前: 如果有某个容器才注册组件类中bean
(2)、@ConditionalOnMissingBean:如果没有某个容器才注册组件当前bean
7、 @ImportResource
@ImportResource("classpath:bean.xml")
导入配置(xml) 文件,(让配置文件中的bean生效)
8、配置绑定
绑定SpringBoot配置文件application.properties 中的对应数据
方法一:绑定application.properties 或application.yml 文件中属性
需要标识@Component注解,即需要注册到容器中
@ConfigurationProperties(prefix = "person")
//或 @ConfigurationProperties("person")
@Component
public class Person {
private String name;
private Integer age;
}
application.properties 文件中
person.name=张三
或yml文件中
person:
name: 张三
方法二: @EnableConfigurationProperties(Person.class)
当前对象未标识@Component即没有注册到IOC容器时
需要在@Configuration配置类中
标注@ConfigurationProperties(prefix = "person") 来把当前类通过装配并且注册到容器中
(默认id为驼峰名)
三、配置文件properties和yaml(yml)
properties和yaml(yml) 优先properties
四、yaml(yml)具体规则
1、基本规则
(1)、大小写敏感
(2)、使用缩进表示层级关系
(3)、缩进不允许使用tab,只允许空格(可以tab)
(4)、缩进的空格数不重要,只要相同层级的元素左对齐
(5)、#表示注解
(6)、“”() ‘’ 单引号和双引号表示字符串,单引号里会转译(单引号内容全部变为字符 串)
(7)、字符串默认不用加引号
2、编写规则:
(1)、基本数据 key: value
(2)、数组和list、set:
数组和list、set: key: [value1,value2] 或者 key: - value1 - value2
(3)、类对象或Map
类对象或Map key: {key1: value1,key2: value2}
或 key: key1: value1 key2: value2
五、web工程
1、静态资源的访问
(1)、静态资源可以存放的位置
静态资源:resources 下的(需要自己创建)
/META-INF/resource /public /resources /static
这些目录可以存放静态资源
(2)、原理:
静态资源:/**
请求进来先去找Controller中的动态请求能不能处理,不能处理再去找静态资源 设置访问静态资源路径(yaml): static-path-pattern: /res/**
(3)、修改网页图标
网页标图:默认静态资源下的favicon.ioc 就是图标,添加favicon.ioc名字文件即可
2、请求访问
(1)、开启Rest请求:
SpringBoot默认是false的,需要手动开启才能使用Rest风格的请求
开启(yml) hiddenmethod: filter: enabled: true
(2)、Rest请求相关注解
@RequestMapping 衍生 @GetMapping、PutMapping、DeleteMapping、@PostMapping
3、传递请求参数
和SpringMVC一致
(1)、路径传输
前: /list/3/pete 后: /list/{id}/{name} 路径变量@PathVariable("id") 单个参数 @PathVariable("id") Integer id 两个都存储到Map中 @PathVariable Map<String,String>
(2)获取请求头信息
@RequestHeader("User-Agent") 获取请求头的某一个信息 @RequestHeader Map<String,Object> qt 获取请求头的所有信息,放入Map中
4、获取请求参数
(1)前端路径中:
单个参数 :使用对应类型
前: /list?id=1 /list传递id=1
后:/list
@RequestParam("id") Integer id
多个参数 :使用&符号
前: /list?id=1&inters=book&inters /list传递id和inters 其中inters的值有多个 接收时候可
以用list接收
后:/list
@RequestParam("inters") List<String> inters
获取全部请求参数:使用Map
前: /list?id=1&inters=book&inters /list传递id和inters 其中inters的值有多个 接收时候可
以用list接收
后:/list
@RequestParam Map<String,Object> pv
5、获取Cookie
@CookieValue("xx") Cookie koo)
6、获取请求体(表单数据)
表单提交:
1、获取全部表单内容 @RequestBody
获取表单全部内容 @RequestBody String bood 表单内容会以字符串形式接收 (id=1&paswoed=2)
2、获取全部表单内容 @RequestParam
获取表单中单个内容:@RequestParam("id") Integer id
获取表单中通名复数内容:@RequestParam("name") List<String> name
获取表单全部内容:@RequestParam Map<String,Object> pv 不能有同名复数内容否则只会存储它们
其中一个
3、用类对象User获取
User对象属性需要和HTML标签中name属性对应,直接接收即可,不需要注解
7、获取request域数据
获取转发域中的数据 1、request.setAttribute("msg","成功了。。。")-->@RequestAttribute("msg") String msg
2、request.setAttribute("msg2","成功了。。。")-->Object msg2=request.getAttribute("msg2");
发送时候可以使用 Map、Model 、HttpServletRequest作用一样 request.setAttribute()可以替换传递方式 发送方式它们可以任意
接收只能@RequestAttribute(xx)绑定对应参数 或者HttpServletRequest接收 request.getAttribute("sa") 接收方式它们两个也能任意
HttpSession会话域 只能HttpSession发送 HttpSession接收
8、获取矩阵变量的值
@MatrixVariable
SpringBoot默认禁用了矩阵变量的功能需要手动开启
单个路径段
前:/cars/sell;low=34;brand=byd,aud,yd
后:/cars/{path}
@MatrixVariable("low") Integer low 获取
@MatrixVariable("brand") List<String> brand 获取同名的多个数据 另一种前:/cars/sell;low=34;brand=byd;brand=aud;brand=yd
@PathVariable("path") String path 获取当前段路径信息(sell)
多个路径段
前:/boos/1;age=20/2;age=10
后:/boos/{boosId}/{empId}
@MatrixVariable(value = "age",pathVar ="boosId" ) Integer boosId 获取boosId路径段的id
@MatrixVariable(value = "age",pathVar ="empId" ) Integer empId 获取empId路径段的id
/**
* @Configuration配置类
* 开启矩阵变量
*/
@Configuration(proxyBeanMethods = false)
public class WebConfig {
//手动开启矩阵变量
@Bean
public WebMvcConfigurer webMvcConfigurer(){
return new WebMvcConfigurer() {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
UrlPathHelper urlPathHelper=new UrlPathHelper();
//不移除后面的内容,矩阵变量就会生效
urlPathHelper.setRemoveSemicolonContent(false);
configurer.setUrlPathHelper(urlPathHelper);
}
};
}
}
六、HTML thymeleaf 导入共同块元素
thymeleaf :
行内放值[[${xx}]] ${key} @{字符串}
共同块元素导入
共同块
相同块引用
footer.html中
目标块需要设置
th:foragment="wer"
其他页面中
th:insert="footer :: wer" : 直接把目标块插入
th:replace="footer :: wer" : 直接把目标对象直接替换为当前目标
th:include="footer :: wer" ;把目标块中的内容赋予给当前块的内容
七、拦截器
类似AOP切面
要继承:HandlerInterceptor preHandle:目标方法指向前执行 postHandle:目标方法执行后执行 afterCompletion:页面渲染后执行
通常用于登录检查,未登录不能访问其他页面、
@Slf4j
public class LoginIntereptro implements HandlerInterceptor {
/**
* 目标方法执行之前,做登录检查
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//获取请求路径URL
String requestURI=request.getRequestURI();
log.info("拦截的请求路径是{}",requestURI);
//获取登录检查的会话域
HttpSession session=request.getSession();
//根据URL路径获取对应的请求
Object loginUser=session.getAttribute("loginUser");
// log.info("接收数据{}",loginUser);
if(loginUser!=null){
//放行
log.info("放行请求:{}",requestURI);
return true;
}
//拦截,
//消息
request.setAttribute("msg","请先登录");
//重定向转发
// response.sendRedirect("/");
//转发request 从而使页面能收到消息
request.getRequestDispatcher("/").forward(request,response);
return false;
}
/**
* 目标方法执行完后
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
/**
* 页面渲染后
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
创建了拦截器类后需要把它添加到配置类中,在配置类中设置拦截与放行的请求
配置web配置类 1、编写拦截器实现HandlerInterceptor接口 2、拦截器注册到容器中(实现WebMvcConfigurer的addInterceptors方法) 3、指定拦截规则[如果拦截所有,静态资源也会被拦截] 添加拦截的请求:addPathPatterns("/**") 拦截全部方法,包括静态请求 添加放行的请求:excludePathPatterns("/","/login"); 放行xxx请求
//@EnableWebMvc
@Configuration
public class AdminWebConfig implements WebMvcConfigurer {
//添加拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
//添加拦截器
/**
* 添加拦截器
* 支持链式调用
*
* 添加拦截的请求:addPathPatterns("/**") 拦截全部方法,包括静态请求
* 添加放行的请求:excludePathPatterns("/","/login"); 放行xxx请求
*/
registry.addInterceptor(new LoginIntereptro())
.addPathPatterns("/**") //所有请求都被拦截,包括静态请求css
.excludePathPatterns("/","/login","/css/**","/js/**","/images/**","/fonts/**","/druid/**"); //放行的请求,部分为静态请求css
;
}
// @EnableWebMvc 配置了 后需要自己定义静态路径
//配置静态路径
// @Override
// public void addResourceHandlers(ResourceHandlerRegistry registry) {
// registry.addResourceHandler("/aa/").addResourceLocations("classpath:/static/");
//
// }
}
八、文件上传
1、@RequestPart("headerImg")
获取表单中传递的文件类型数据
作用和@RequestParam 一致,它用来MultipartFile映射文件类型的。
映射上传文件
MultipartFile数据类型 接收上传过来的文件
它的重要方法
getOriginalFilename() //获取原来文件的名字(包括后缀名字)
transferTo()文件转存到
//文件上传
@PostMapping("/upload")
public String upload(@RequestParam("email") String email,
@RequestParam("username") String username,
@RequestPart("headerImg")MultipartFile headerImg,
@RequestPart("photos") MultipartFile[] photos
) throws IOException {
log.info("上传的信息:email={},username={},headerImg={},photos={}",
email,username,headerImg.getSize(),photos.length
);
if(!headerImg.isEmpty()){
//如果文件不为空,执行操作
headerImg.transferTo(new File("D:\\AEK\\s\\"+headerImg.getOriginalFilename()));
log.info("headerImg传输完成");
}
int i=0;
if(photos.length>0){
for(MultipartFile photo:photos){
if(!photo.isEmpty()){
//如果不为空
log.info(i+",传输完成");
photo.transferTo(new File("D:\\AEK\\s\\"+photo.getOriginalFilename()));
i++;
}
}
}
// @Slf4j
/**
* 注解
* log.info方法打印日志
* (“{}” Object)
* 通过{} 来为要输出的对象占位
*/
return "main";
}
通常默认的上传文件大小都很小,需要在配置文件application.properties中修改
spring.servlet.multipart.max-file-size=10MB #上传请求单文件最大值
spring.servlet.multipart.max-request-size=100MB #上传请求总文件最大值
九、自定义响应错误页面
在resources 目录下的templates 目录或者static目录可以创建error目录
来自定义错误页面
错误页面名字是4xx.html或者5xx.html来表示出现错误的处理5或者4类型的错误请求(比如404和500都会被处理)
错误信息的key:
timestamp: 时间
status: 类型(404)
error : 错误信息(页面不存在)
message:错误消息
path: 请求消息(/xx)
十、注入servlet原生组件
1、使用原生API组件配置
在主配置类中设置 扫描Servlet配置类的位置 @ServletComponentScan(basePackages ="com.example")
@ServletComponentScan(basePackages ="com.example")
@SpringBootApplication
public class Boot4Application {
public static void main(String[] args) {
SpringApplication.run(Boot4Application.class, args);
}
}
2、 配置Servlet 类以及请求
(1)、HttpServlet
@WebServlet(urlPatterns = "/my")
效果:直接响应,没有经过Spring的拦截器
@WebServlet(urlPatterns = "/my")
@Slf4j
public class Myservlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
log.info("工作");
resp.getWriter().write("666");
}
}
(2)、ServletContextListener
Servlet监听器 @WebListener 配置Servlet监听器类 ServletContextListener
@WebListener
public class MyListener implements ServletContextListener {
}
(3)、Filter
@WebServlet(urlPatterns = {"/css/*","/images/*"}) urlPatterns拦截请求 Filter
/**
*Servlet拦截器
*
* @WebServlet(urlPatterns = {"/css/*","/images/*"})
* urlPatterns拦截请求
*
*/
@WebServlet(urlPatterns = {"/css/*","/images/*"})
@Slf4j
public class MyFiler implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("拦截器工作");
Filter.super.init(filterConfig);
}
@Override
public void destroy() {
Filter.super.destroy();
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
}
}
2、使用RegistrationBean类型
通过ioc容器管理bean获取
ServletRegistrationBean
FilterRegistrationBean
ServletListenerRegistrationBean
十一、定制SpringBoot
WebMvcConfigurer 配置类中继承WebMvcConfigurer接口 +@Bean给容器中再扩展一些组件 就可以定制化web功能
@EnableWebMvc @EnableWebMvc:全面接管SpringMVC 1、静态资源 、视图解析器、欢迎页面 全部失效
十二、数据访问
1、SQL
(1)、数据源的自动配置
导入jdbc场景
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
分析自动配置
为什么导入jdbc场景,官方不导入驱动?官方不知道我们要操作扫描数据库
导入数据库驱动版本时要指定版本 官方默认最新版本
配置数据源yml
spring:
datasource:
url: jdbc:mysql://localhost:3306/ipiw
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
2、整合Mybatis
方式一:
* SqlSessionFactory:自动配置好了
* SqlSession:自动配置了SqlSessionTemplate 组合了SqlSession
* Mapper:只要在操作MyBatis的接口标注了@Mapper就会被自动扫描进来
*
* (1)、导入mybatis官方starter 或者直直接在idea创建工程时候勾选Mybatis时候
* (1) 编写映射类
* (2) 编写Mapper接口(需要标识@Mapper注解) 以及Mapper接口配置文件 和以前一致
* (3) 在yml编辑配置(数据源相关 以及Mybatis相关)
* (4)不用再创建主配置类直接配置在configuration: 中
*
*
* #配置Mybatis 规则
mybatis:
#config-location: classpath:Mybatis/mybatis-config.xml #主配置文件
mapper-locations: classpath:Mybatis/mapper/*.xml #接口配置文件路径
configuration: #指定mybatis全局配置文件中的相关配置
map-underscore-to-camel-case: true #设置驼峰命名规则映射数据库字段
* # 可以不创建全局配置文件 configuration: 包含的全局配置文件,可以直接配置
* 需要提前配置数据库信息
*
* spring:
* datasource:
* url: jdbc:mysql://localhost:3306/ipiw
* username: root
* password: 123456
* driver-class-name: com.mysql.jdbc.Driver
*
*
* 方式二:
* 用于编写简单的sql
* 纯注解的配置 不配置Mapper接口的配置文件
* @Select("select *from city where id=#{id}")
* 在接口方法中标识@Select等,方法直接编写sql
*
* @Insert("insert into user2(name,mima) values(#{name},#{mima})")
* @Options(useCache = true,keyProperty = "id")//设置@Insert的更多属性 获取自增id等
*
* 可以在springboot主配置类使用@MapperScan(包路径) 这样就不用再在mapper接口中标识@Mapper
* 可以和方式一混合使用,简单sql用注解,复杂sql用mapper.xml配置文件编写
总结未为:
(1)、导入mybatis官方starter 或者 直直接在idea创建工程时候勾选Mybatis (1) 编写映射类 (2) 编写Mapper接口(需要标识@Mapper注解) 以及Mapper接口配置文件 (简单sql直接在接口方法上使用@Select等注解直接编写sql) (3)不用再创建Mybatis主配置xml,在yml编辑配置(数据源相关 以及Mybatis相关) (4)不用再创建主配置类直接配置在configuration: 中编写相关配置
yml中
mybatis:
#config-location: classpath:Mybatis/mybatis-config.xml #主配置文件
mapper-locations: classpath:Mybatis/mapper/*.xml #接口配置文件路径
configuration: #指定mybatis全局配置文件中的相关配置
map-underscore-to-camel-case: true #设置驼峰命名规则映射数据库字段
spring:
datasource:
url: jdbc:mysql://localhost:3306/ipiw
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
4、整合Mybatis-plus 未学习 5、整合redis 未学习
十三、单元测试
springboot整合了junit5 编写测试方法:@Test(需要使用junit5版本注解) Junit类具有Spring的功能,@Autowired、@Transactional 标注的方法,测试完成后自动回滚
junit5测试
1、常用注解
(1)、@Test
声明为测试方法
(2)、@DisplayName
未测试类或者测试方法设置展示名称
(3)、@BeforeEach
每个测试方法执行前都会运行
(4)、@testBeforeAll
测试前时候都会执行,但只执行一次,需要设置成static方法
(5)、@AfterAll
测试结束后会执行,但只执行一次,需要设置成static方法
(6)、@Disabled
用当前测试方法,集体测试时不会执行当前测试方法
(7)、 @Timeout(value = 500,unit= TimeUnit.MILLISECONDS)
value:(数值) unit (单位) TimeUnit.MILLISECONDS(单位)
(8)、@SpringBootTest
使用springboot的功能需要标识@SpringBootTest注解
(9)、@RepeatedTest(5)
重复执行当前测试方法 测试5次
2、断言 Assertions
检查业务逻辑返回的数据是否合理 所有的测试运行结束以后,会有一个详细的测试报告; 结果与预期不符合会打印信息日志 主要:测试方法中前面断言失败,后面的代码都不会执行
(1)、简单断言
assertEquals(期望值,目标数据) 判断两个值是否相等 ,后面可以自定义错误信息 Assertions.assertEquals(5,cal,"计算失败"); Assertions.assertTrue(true,"结果不为true"), 判断目标结果是否为true
assertSame 判断两个对象的引用是否相等
(2)、组合断言
所有断言全部需要成功才算成功 Assertions.assertAll 组合断言,支持函数式编程 Assertions.assertAll("test", ()-> Assertions.assertTrue(true,"结果不为true"), ()->Assertions.assertEquals(1,1) ); }
(3)、异常断言
断言出现的异常 Assertions.assertThrows(ArithmeticException.class, ()->{int i=10/2;}, "业务逻辑正常");
(4)、快速失败
自定义失败 Assertions.fail("测试失败")
(5)、前置条件
不满足断言会使得测试方法失败 前置条件只会使得测试方法的执行终止 假设 Assumptions.assumeTrue(false,"结果不是true");
(6)、嵌套测试
@Nested 内部嵌套类中声名为嵌套测试 嵌套测试情况下,外层Test不能驱动内层的Before(After)Each/All之类的方法 内层的Test可以驱动外层的Before(After)Each/All方法
(7)、参数化测试
@ParameterizedTest 代替@Test 来表明是一个参数化测试 @ValueSource(ints={1,2,3,4,5}) 设置传入测试的参数 @MethodSource("stringStream") 参数来自stringStream的返回值Stream.of("app","ban","asd"); 可以使用不同的参数多次运行当前测试方法
十四、Profile功能
为了方便多环境适配,Springboot简化了Profile功能 进行环境切换
为了方便多环境适配,Springboot简化了Profile功能
进行环境切换
默认配置文件
application.properties
application.yaml
测试配置和生产配置
application-prod.yaml
application-test.yaml
(1) 在默认配置环境中指定加载的配置文件
spring.profiles.active=prod
(2)分组配置
spring.profiles.group.myprod1[0]=ppd
spring.profiles.group.myprod1[1]=test
spring.profiles.group.myprod2[0]=prod
spring.profiles.active=myprod1
此时分组了myprod1、myprod2; 加载的是myprod1组,ppd和prod配置文件都会被加载
打包成jar包后可以通过命令行方式修改配置
命令行:java -jar xx.jar --spring.profiles.active=test
可以修改配置项的任意值
默认配置文件和指定的配置文件都会被加载
如果在默认配置文件中有和指定配置文件同名的配置项时,优先加载指定的配置项
(3)@Value("${person.nane:李四}")
绑定配置文件中的值,如果获取不到就设置默认值 李四
@ConfigurationProperties(prefix = "person") 或 @ConfigurationProperties("person")
它们的区别是 @ConfigurationProperties可以批量绑定配置项,@Value只能一个一个绑定
(3) @Profile("prod"):激活
标注在类上:表示当前类的配置或内容 在prod情况下才会生效 (标识在beans上:在当前pord配置条件下才会添加到ioc容器中
标注在方法:表示当前方法的配置或内容 在prod情况下才会生效
重要部分为web部分 请求路径获取、文件上传、拦截器、整合Mybatis
仅供学习参考,发现问题请在评论区指出