3. Java SpringBoot
Web 技术基础
软件主要分为两种
- BS:(Browser/Server,浏览器/服务器架构模式)。
- CS:(Client/Server,客户端/服务器架构模式)。
C/S架构主要特点是交互性强,具有安全访问模式,网络流量低,响应速度快,因为客户端负责大多数业务逻辑和UI演示,所以也被称为胖客户端,C/S结构的软件需要针对不同的操作系统开发不同版本的软件。
随着互联网的兴起,CS架构不适合Web,最大的原因是Web应用程序的修改和升级非常迅速,而CS架构需要每个客户端逐个升级桌面App,因此,Browser/Server模式开始流行,简称BS架构。
B/S架构的主要特点是分散性高、维护方便、开发简单、共享性高、总拥有成本低。
Maven
Maven是一个项目管理工具,可以对Java项目进行自动化的构建和依赖管理。
Maven的作用可以分成三类。
- 项目构建:提供标准的,跨平台的自动化构建项目的方式
- 依赖管理:方便快捷的管理项目依赖的资源(jar包),避免资源间的版本冲突等问题
- 统一开发结构:提供标准的,统一的项目开发结构,如下图所示
Maven 仓库
运行Maven 的时候,Maven 所需要的任何构件都是直接从本地仓库获取的。
如果本地仓库没有,它会首先尝试从远程仓库下载构件至本地仓库。
本地仓库和远程仓库都可以自己配置 在 Maven 根目录下 conf/settings.xml
依赖排除
<exclusions>
<exclusion>
<groupld>junit</groupld>
<artifactld>junit</artifactld>
</exclusion>
</exclusions>
当前包不会再依赖任何别的依赖
依赖范围
依赖的jar包,默认情况下,可以在任何地方使用。可以通过<scope>..</ scope>
设置其作用范围
- 主程序范围有效(main文件夹范围内)。
- 测试程序范围有效。(test文件夹范围内)
- 是否参与打包运行。(package指令范围内)
生命周期
Maven的生命周期就是为了对所有的maven项目构建过程进行抽象和统一
Maven中有3套相互独立的生命周期:
- clean:清理工作。
- default:核心工作,如:编译、测试、打包、安装、部署等。
- site:生成报告、发布站点等,
运行每个阶段,都会把前面的阶段都做一遍
SpringBoot
介绍
- Spring Boot是由Pivotal团队提供的基于Spring的全新框架,旨在简化Spring应用的初始搭建和开发过程。
- Spring Boot是所有基于Spring开发项目的起点。
- Spring Boot就是尽可能地简化应用开发的门槛,让应用开发、测试、部署变得更加简单。
特点
- 遵循“约定优于配置”的原则,只需要很少的配置或使用默认的配置。
- 能够使用内嵌的Tomcat、Jetty服务器,不需要部署war文件
- 提供定制化的启动器Starters,简化Maven配置,开箱即用。纯Java配置,没有代码生成,也不需要XML配置。
- 提供了生产级的服务监控方案,如安全监控、应用监控、健康检测等。
创建项目
在IDEA中选择 Spring Boot + Maven,一切都好了(是的,没错)
小问题:IDEA2023版本创建Sping项目只能勾选17和21,却无法使用Java8?(已解决)_idea jre是17如何设置8-CSDN博客
开发环境热部署
- 在实际的项目开发调试过程中会频繁地修改后台类文件,导致需要重新编译、重新启动,整个过程非常麻烦,影响开发效率。
- Spring Boot提供了spring-boot-devtools组件,使得无须手动重启Spring Boot应用即可重新编译、启动项目,大大缩短编译启动的时间。
- devtools会监听classpath下的文件变动,触发Restart类加载器重新加载该类,从而实现类文件和属性文件的热部署。
- 并不是所有的更改都需要重启应用(如静态资源、视图模板),可以通过设置spring.devtools.restart.exclude属性来指定一些文件或目录的修改不用重启应用
1.修改pox.xml
在pom.xml配置文件中添加dev-tools依赖。
使用optional=true表示依赖不会传递,即该项目依赖devtools;其他项目如果引入此项目生成的JAR包,则不会包含devtools
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
放完之后,要点及同步
2.在application.properties中配置devtools
#热部署生效
spring.devtools.restart.enabled=true
#设置重启目录
spring.devtools.restart.additional-paths=src/main/java
#设置classpath目录下的WEB一INF文件夹内容修改不重启
spring.devtools.restart.exclude=static/**
3.IDEA 配置
- 打开Settings页面,在左边的菜单栏依次找到Build,Execution,Deployment→Compile,勾选Build project automatically
- 在Settings-Advanced Settings-Compiler里,勾选compiler.automake.allow.when.app.running复选框。
做完这两步配置之后,若开发者再次在lntelliJ IDEA中修改代码则项目会自动重启。
Web 入门
- Spring Boot将传统Web开发的mvc、json、tomcat等框架整合,提供了spring-boot-starter-web组件,简化了Web应用配置。
- 创建SpringBoot项目勾选Spring Web选项后,会自动将spring-boot-starter-web组件加入到项目中。
- spring-boot-starter-web启动器主要包括web、webmvc、json、tomcat等基础依赖组件,作用是提供Web开发场景所需的所有底层依赖。
- webmvc为Web开发的基础框架,json为JSON数据解析组件,tomcat为自带的容器依赖。
BS架构: Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端。
CS架构: Client/Server,客户端/服务器架构模式。
控制器
Spring Boot提供了@Controller和@RestController两种注解来标识此类负责接收和处理HTTP请求。
如果请求的是页面和数据,使用@Controller注解即可;如果只是请求数据,则可以使用@RestController注解。
所以一个前后端分离的项目,后端如果不涉及页面相关的处理,可以只用@RestController
如下图,MVC 的结构设计
@RestController用法
默认情况下,@RestController注解会将返回的对象数据转换为JSON格式:
@RestController
public class Hellocontroller {
@RequestMapping("/user")
public User getUser() {
User user = new User();
user.setUsername("zhangsan");
user.setPassword("123");
return user;
}
}
路由映射
- @RequestMapping注解主要负责URL的路由映射。它可以添加在Controler类或者具体的方法上。
- 如果添加在Controller类上,则这个Controller中的所有路由映射都将会加上此映射规则,如果添加在方法上,则只对当前方法生效。
- @RequestMapping注解包含很多属性参数来定义HTTP的请求映射规则。常用的属性参数如下!
- value: 请求URL的路径,支持URL模板、正则表达式
- method: HTTP请求方法(Content-Type),如application/jsonconsumes: 请求的媒体类型
- produces: 响应的媒体类型
- params,headers:请求的参数及请求头的值
@RequestMapping通配符匹配URL
@RequestMapping
的value属性用于匹配URL映射,value支持简单表达式@RequestMapping("/user")
@RequestMapping
支持使用通配符匹配URL,用于统一映射某些URL规则类似的请求:@RequestMapping("/getJson/*.json")
当在浏览器中请求/getson/a.json
或者/getjson/b.json
时都会匹配到后台的Json方法@RequestMapping
的通配符匹配非常简单实用,支持等通"*","?","**"
配符- 符号
*
匹配任意字符,符号**
匹配任意路径(多级),符号“?”匹配单个字符 - 有通配符的优先级低于没有通配符的,比如
/user/add.json
比/user/*.json
优先匹配。 - 有
“**”
通配符的优先级低于有“*”
Method匹配
HTTP请求Method有GET、POST、PUT、DELETE等方式。HTTP支持的全部Method
@RequestMapping注解提供了method参数指定请求的Method类型,包括RequestMethod.GET、RequestMethod.POST、RequestMethod.DELETE、RequestMethod.PUT等值,分别对应HTTP请求的Method
@RequestMapping(value = "/world",method = RequestMethod.GET)
public String hello() {
return "Hello";
}
Method匹配也可以使用@GetMapping、@PostMapping等注解代替,
参数传递
params需要参数名字和url里对应参数一致
// http://localhost:8080/hello1
// http://localhost:8080/hello1?nickname=cfd&user_id=2
@RequestMapping(value = "/hello1",method = RequestMethod.GET)
public String hello1(String nickname,String user_id) {
return "Hello " + nickname + " user_id " + user_id;
}
参数注解
默认加上注解后就是必须要的参数,可以通过在@RequestParam
里面加上required=false
参数即可
// http://localhost:8080/hello2?nickname=cfd
@RequestMapping(value = "/hello2",method = RequestMethod.GET)
public String hello2(@RequestParam("nickname") String name) {
return "Hello " + name;
}
post请求
同 GET 获得参数方法类似,不过可以把参数放在 body 里面,名称需要保持一致
@RequestMapping(value = "/testPost1",method = RequestMethod.POST)
public String hello3(String name) {
return "Hello " + name;
}
// http://localhost:8080/testPost2
@RequestMapping(value = "/testPost2",method = RequestMethod.POST)
public String hello4(User user) {
System.out.println(user.getName()+" "+user.getAge());
return user.getName();
}
报错405:因为浏览器里面url输入发的都是 GET 请求,所以不能直接访问,可以用apifox来
报错400:路由错了
json格式数据接收 名称需要保持一致,类型也尽量保持一致(json数据是有格式的,不一致也没关系,会自动转化)
// http://localhost:8080/testPost3
@RequestMapping(value = "/testPost3",method = RequestMethod.POST)
public String hello5(@RequestBody User user) {
System.out.println(user.getName()+" "+user.getAge());
return user.getName();
}
通配符请求
*
后面可以跟一级
**
后面可以跟任意级路由
// http://localhost:8080/all/**
@RequestMapping(value = "/testPost3",method = RequestMethod.POST)
public String all() {
return "通配符";
}
静态资源访问
- 使用IDEA创建Spring Boot项目,会默认创建出classpath:/static/目录,静态资源一般放在这个目录下即可。
- 如果默认的静态资源过滤策略不能满足开发需求,也可以自定义静态资源过滤策略。
- 在application.properties中直接定义过滤规则和静态资源位置:
spring.mvc.static-path-pattern=/static/**
spring.web.resources.static-locations=classpath:/static
- 过滤规则为
/static/**
,静态资源位置为classpath:/static/
文件上传
- 表单的enctype 属性规定在发送到服务器之前应该如何对表单数据进行编码。
- 当表单的enctype="application/x-www-form-urlencoded"(默认)时form表单中的数据格式为:key=value&key=value
- 当表单的enctype="multipart/form-data"时,其传输数据形式如下
SpirngBoot实现文件上传功能
Spring Boot工程嵌入的tomcat限制了请求的文件大小,每个文件的配置最大为1Mb,单次请求的文件的总数不能大于10Mb。
要更改这个默认值需要在配置文件(如application.properties)中加入两个配
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB
当表单的enctype="multipart/form-data"时,可以使用MultipartFile获取上传的文件数据,再通过transferTo方法将其写入到磁盘中
代码
@RestController
public class FileUploadController {
@PostMapping("/upload")
public String upload(String nickname, MultipartFile photo, HttpServletRequest request) throws IOException {
System.out.println(nickname);
// 文件名称
System.out.println(photo.getOriginalFilename());
// 文件类型
System.out.println(photo.getContentType());
System.out.println(System.getProperty("user.dir"));
String path = request.getServletContext().getRealPath("/upload/");
// 文件存储路径(会动态变化)
System.out.println(path);
saveFile(photo,path);
return "upload succeed";
}
public void saveFile(MultipartFile photo,String path) throws IOException {
File dir = new File(path);
if (!dir.exists()){
dir.mkdir();
}
File file = new File(path+photo.getOriginalFilename());
// 自动将网络上传输的photo文件对象存储到file路径中
photo.transferTo(file);
}
}
properties文件修改加上下面,访问上传的图片可以通过<路径/static/文件名>访问到
# 逗号后面是服务器上传文件的默认位置,每次都会改变
spring.web.resources.static-locations=classpath:/static,/upload/
拦截器
拦截器在Web系统中非常常见,对于某些全局统一的操作,我们可以把它提取到拦截器中实现。总结起来,拦截器大致有以下几种使用场景:
- 权限检查:如登录检测,进入处理程序检测是否登录,如果没有,则直接返回登录页面
- 性能监控:有时系统在某段时间莫名其妙很慢,可以通过拦截器在进入处理程序之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间
- 通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有提取Locale、Theme信息等,只要是多个处理程序都需要的,即可使用拦截器实现。
拦截器是springboot提供的
拦截器使用
Spring Boot定义了HandlerInterceptor接口来实现自定义拦截器的功能。定义了preHandle、postHandle、afterCompletion三种方法,通过重写这三种方法实现请求前、请求后等操作
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("Login in");
return true;
}
}
拦截器注册
public class WebConfig implements WebMvcConfigurer {
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/user/**");
}
}
过滤器
创建一个过滤器
/*
1. 实现Filter
2. 配置 @WebFilter 和 @ServletComponentScan
*/
@WebFilter(filterName = "/*") // 拦截路径
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// 调用接口前
// 调用接口
filterChain.doFilter(servletRequest,servletResponse);
// 调用接口后
}
@Override
public void destroy() {
Filter.super.destroy();
}
}
过滤器链
可以同时创建多个过滤器,默认调用按照字符串字典序排序运行
如果想要规定过滤器的执行顺序,可以使用@Order()
来规定
@WebFilter(filterName = "/*") // 拦截路径
public class MyFilterFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
filterChain.doFilter(servletRequest,servletResponse);
}
}
拦截器和过滤器的执行顺序
Filter Login in
Interceptor Login in
Filter & Intercepter
接口规范不同: 过滤器需要实现Filter接口,而拦截器需要实现HandlerInterceptor
接口拦截范围不同: 过滤器Filter会拦截所有的资源,而Interceptor只会拦截Spring环境中的资源。
RESTful 服务和 Swagger
Spring Boot提供的spring-boot-starter-web组件完全支持开发RESTful API,提供了与REST操作方式(GET、POST、PUT、DELETE)对应的注解。
- @GetMapping:处理GET请求,获取资源。
- @PostMapping:处理POST请求,新增资源。PutMapping:处理PUT请求,更新资源。
- @DeleteMapping:处理DELETE请求,删除资源。
- @PatchMapping:处理PATCH请求,用于部分更新资源。
路由只包含名词即可
有一种新的路由表达方式,如
http://localhost:8080/user/{id}
Swagger
- 在
pom.xml
文件中添加依赖
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
- 添加SwaggerConfig
@Configuration //告诉Spring容器这是Swagger的配置类
@EnableSwagger2 //启用Swagger2功能
public class SwaggerConfig {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.example")) // 扫描contorller包创建swagger2
.paths(PathSelectors.any())
.build()
.apiInfo(apiInfo());
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("接口文档")
.description("接口文档")
.version("1.0.0")
.build();
}
}
- 启动(可能报错,因为版本不对,稍微修改一下即可)
- 访问后访问
http://localhost:8080/swagger-ui.html
有点小问题:No mapping for GET /swagger-ui.html
小结
转载自:https://juejin.cn/post/7381396879057059881