目录
一、SpringBoot快速上手
1、SpringBoot介绍
- SpringBoot是由Pivotal团队提供的基于Spring的全新框架,旨在简化Spring应用的初始搭建和开发过程。
- SpringBoot是所有基于Spring开发项目的起点。
- SpringBoot就是尽可能地简化应用开发的门槛,让应用开发、测试、部署变得更加简单。
2、SpringBoot特点
- 遵循“约定优于配置”的原则,只需要很少的配置或使用默认的配置。
- 能够使用内嵌的Tomcat、Jetty服务器,不需要部署war文件。
- 提供定制化的启动器starter,简化Maven配置,开箱即用。
- 纯Java配置,没有代码生成,也不需要XML配置。
- 提供了生产级的服务监控方案,如安全监控、应用监控、健康检测等。
3、快速创建SpringBoot应用
- 利用IDEA的Spring Initializr创建SpringBoot项目
- 我们开发web项目,所以添加web依赖
- 这样就会自动将web项目所需要的依赖下载并引入
- 点击完成项目就新建成功
- 接下来测试一下项目运行
- 在项目新建一个controller包,里面专门用来存放controller控制器
-
@RestController public class IndexController { @GetMapping("/index") public String index(){ return "欢迎访问首页"; } }
- 接着运行主程序
- 接下来查看控制台
- 这样就运行成功
- 我们在浏览器访问一下http://localhost:8888/index
- 这样就说明项目可以正常访问了
4、SpringBoot开发热部署
- 在实际的项目开发调试过程中会频繁地修改后台类文件,导致需要重新编译、重新启动,整个过程非常麻烦,影响开发效率。
- SpringBoot提供了spring-boot-devtools组件,使得无须手动重启SpringBoot应用即可重新编译、启动项目,大大缩短编译启动的时间。
- devtools会监听classpath下文件的变动,触发Restart类加载器重新加载该类,从而实现类文件和属性文件的热部署。
- 并不是所有的更改都需要重启应用(如静态资源、视图模板),可以通过设置spring.devtools.restart.exclude属性来指定一些文件或目录的修改不用重启应用。
- 实现步骤:
- 在pom.xml配置文件中添加dev-tools依赖。
- 使用optional=true表示依赖不会传递,即该项目依赖devtools;其他项目如果引入此项目生成的jar包,则不会包含devtools。
-
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency>
- 依赖引入后在application.yml中配置devtools
-
spring: devtools: restart: enabled: true #热部署生效 additional-paths: src/main/java #设置重启目录 exclude: static/** #设置classpath目录下的WEB-INF文件夹内容修改不重启
- 配置后还不行,因为IDEA还需要在设置中配置项目自动运行
- 打开Settings页面,在左边的菜单栏依次找到
- Build、Execution、Deployment、Compile,勾选Build project automatically
- 按Ctrl+Shift+Alt+/ 快捷键调出Maintenance页面,单击Registry,勾选
- compiler.automake.allow.when.app.running复选框
- 如果IDEA版本比较搞,可能没有出现这个复选框,那么尝试以下方法
- 在Settings中拉到最下面找到Advanced Settings
- 然后找到Allow auto-make to start even if developed application is currently running
- 然后勾选
- 这样开发热部署就配置完成。
二、Web开发基础
1、Web入门
- SpringBoot将传统Web开发的MVC、JSON、Tomcat等框架整合,提供了spring-boot-starter-web组件,简化了Web应用配置。
- 创建SpringBoot项目勾选SpringWeb选项后,会自动将spring-boot-starter-web组件加入到项目中。
- spring-boot-starter-web启动器主要包括WEB、WebMVC、JSON、Tomcat等基础依赖组件,作用是提供Web开发场景所需要的所有底层依赖。
- WebMVC为Web开发的基础框架,JSON为JSON数据解析组件,Tomcat为自带的容器依赖。
-
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
2、控制器
- SpringBoot提供了@Controller和@RestController两种注解来标识此类负责接收和处理HTTP请求
- 如果请求的是页面和数据,使用@Controller注解即可;如果只是请求数据,则可以使用@RestController注解
- @Controller的用法
- 下面示例中返回了index页面和name的数据,在前端页面中可以通过${name}参数获取后台返回的数据并显示。
- @Controller通常与Thymeleaf模板引擎结合使用
-
@Controller public class IndexController { @GetMapping("/index") public String index(ModelMap map){ map.addAttribute("name","张三"); return "index"; } }
- @RestController的用法
- 默认情况下,@RestController注解会将返回的对象数据转换为JSON格式
-
@RestController public class IndexController { @GetMapping("/user") public User getUser(){ User user = new User(); user.setUsername("张三"); user.setPassword("123"); return user; } }
3、路由映射
- @RequestMapping注解主要负责URL的路由映射。它可以添加在Controller类或者具体的方法上。
- 如果添加在Controller类上,则这个Controller中的所有路由映射都将会加上此映射规则,如果添加在方法上,则只对当前方法生效。
- @RequestMapping注解包含很多属性参数来定义HTTP的请求映射规则。常用的属性参数如下:
- value:请求URL的路径,支持URL模板、正则表达式
- method:HTTP请求方法(POST/GET)
- consumes:请求的媒体类型(Content-Type),如application/json
- produces:响应的媒体类型
- params,headers:请求的参数及请求头的值
- value和method比较常用,其他三个比较少用
- @RequestMapping的value属性用于匹配URL映射,value支持简单表达式
- @RequestMapping("/user")
- @RequestMapping支持使用通配符匹配URL,用于统一映射某些URL规则类似的请求:
- @RequestMapping("/getJson/*.json"),当在浏览器中请求/getJson/a.json或者/getJson/b.json时,都会匹配到后台的json方法。
- @RequestMapping的通配符匹配非常简单实用,支持"*"、"?"、"**"等通配符:
- "*":匹配任意字符;
- "**":匹配任意路径;
- "?":匹配单个字符。
- 有通配符的优先低于没有通配符的,比如/user/add.json比/user/*.json优先匹配。
- 有"**"通配符的优先级低于"*"通配符的。
4、参数传递
- @RequestParam将请求参数绑定到控制器的方法参数上,接收的参数来自HTTP请求体或请求URL的QueryString,当请求的参数名称与Controller的业务方法参数名称一致时,@RequestParam可以省略。
- @RequestParam注解一添加,这个方法就必须加参数,如果URL没有参数则会报错。如果想解除可不添加参数,可以在注解后面加上required=false,如:
- @RequestParam( value = "xxx",required = false)
-
@RestController public class IndexController { // http://localhost:8888/index?nickname=zhangsan @GetMapping("/index") public String index(@RequestParam("nickname") String name){ return "你好"+name; } }
- 上面的代码请求参数和方法参数名称不一致,所以需要使用@RequestParam继续绑定
-
-
@RestController public class IndexController { // http://localhost:8888/index?nickname=zhangsan @GetMapping("/index") public String index(String nickname){ return "你好"+nickname; } }
- 上面的代码请求参数和方法参数名称一致,所以不需要使用@RequestParam进行绑定
-
@RestController public class IndexController { // http://localhost:8888/index?nickname=zhangsan&phone=123 @GetMapping("/index") public String index(String name,String phone){ return "你好"+name+phone; } }
- 上面代码是请求多个参数,URL使用“&”进行拼接,方法上再增加一个参数
- @PathVaraible:用于处理动态的URL,URL的值可以作为控制器中处理方法的参数。
- 如果是Rest风格的URI,比如动态URI,/xxxx/yyyyy,其中yyyy代表一个ID,而这个ID可能是一个数据用用户表的ID,那么就需要用@PathVaraible将该URI的值传给controller方法参数
-
@GetMapping("/getUser/{id}") public String getUser(@PathVariable String id){ System.out.println("id->"+id); return "getUser"; }
- @RequestBody接收的参数是来自requestBody中,即请求体。一般用于处理非Content-Type:application/x-www-form-urlencoded编码格式的数据:
- 比如:application/json、application/xml等类型的数据。
-
// http://localhost:8888/getUser @PostMapping("/getUser") public String getUser(@RequestBody User user){ System.out.println(user); return "getUser"; }
三、Web开发进阶
1、静态资源访问
- 使用IDEA创建SpringBoot项目,会默认创建classpath:/static/目录,静态资源一般放在这个目录下面即可。
- 如果默认的静态资源过滤策略不能满足开发需求,也可以自定义静态资源过滤策略。
- 过滤规则为/static/**,静态资源位置为classpath:/static/
- 在appliction.yml文件中直接定义过滤规则和静态资源位置:
-
spring: mvc: static-path-pattern: /static/** web: resources: static-locations: classpath:/static/ #静态资源
-
2、文件上传原理
- 表单的enctype属性规定在发送到服务器之前应该如何对表单数据进行编码。
- 当表单的enctype="application/x-www-form-urlencoded"(默认)时,form表单中的数据格式为:key=value&key=value
- 当表单的enctype="multipart/form-data"时,其传输数据形式如下:
-
SpringBoot实现文件上传功能
-
Springboot工程嵌入的tomcat限制了请求的文件大小,每个文件的配置最大为1MB,单次请求的文件的总数不能大于10MB。
-
要更改这个默认值需要在配置文件application.yml中加入两个配置:
-
spring: servlet: multipart: max-file-size: 10GB #文化最大10G max-request-size: 10GB #单次请求文件总数不能超过10G
-
-
当表单的enctype="multipart/form-data"时,可以使用MultipartFile获取上传的文件数据,再通过transferTo方法将其写入磁盘中:
-
@RestController public class FileController { /** * 默认定位到的当前用户目录("user.dir")(即工程根目录) * JVM就可以据"user.dir" + "你自己设置的目录" 得到完整的路径(即绝对路径) */ // private static final String UPLOADED_FOLDER = System.getProperty("user.dir")+"/upload/"; @PostMapping("/upload") public String upload(MultipartFile file, HttpServletRequest request)throws Exception{ System.out.println("文件大小:"+file.getSize()); System.out.println("文件的ContentType:"+file.getContentType()); System.out.println("文件的初始名字:"+file.getOriginalFilename()); String path = request.getServletContext().getRealPath("/upload/"); System.out.println("获取web服务器的运行目录:"+path); saveFile(file,path); return "upload success"; } public void saveFile(MultipartFile f,String path)throws IOException{ File upDir = new File(path); if (!upDir.exists()){ upDir.mkdir(); } File file = new File(path+f.getOriginalFilename()); f.transferTo(file); } }
-
3、拦截器
- 拦截器在Web系统中非常常见,对于某些全局统一的操作,我们可以把它提取到拦截器中实现。总结起来,拦截器大致有以下几种使用场景:
- 权限检查:如登录检测,进入处理程序检测是否登录,如果没有,则直接返回登录页面。
- 性能监控:有时系统在某段时间莫名其妙很慢,可以通过拦截器在进入处理程序之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间。
- 通用行为:读取cookies得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有提取Locale、Theme信息等,只要是多个处理程序都需要的,即可使用拦截器实现。
- Springboot定义了HandlerInterceptor接口来实现自定义拦截器的功能
- HandlerInterceptor接口定义了preHandle、postHandle、afterCompletion三种方法,通过重写这三种方法实现请求前、请求后等操作。
- 拦截器定义:
-
public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("LoginInterceptor"); return true; } }
-
- 拦截器注册:
- addPathPatterns方法定义拦截的地址
- excludePathPatterns定义排除某些地址不被拦截
- 添加的一个拦截器没有addPathPattern任何一个url则默认拦截所有请求
- 如果没有excludePathPatterns任何一个请求,则默认不放过如何一个请求。
-
@Configuration // Configuration必须要添加 public class WebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginInterceptor()); // registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/user/**"); // 拦截所有user下面的接口 } }
四、构建RESTful服务
1、RESTful介绍
-
RESTful是目前流行的互联网软件服务架构设计风格。
-
REST(Representational State Transfer,表述性状态转移) 一词是由Roy Thomas Fielding在2000年的博士论文中提出的,它定义了互联网软件服务的架构原则,如果一个架构符合REST原则,则称之为RESTful架构。
-
REST并不是一个标准,它更像一组客户端和服务端交互时的架构理念和设计原则,基于这种架构理念和设计原则的Web API更加简洁、更有层次。
2、RESTful特点
- 每一个URL代表一个资源。
- 客户端使用GET、POST、PUT、DELETE四种表示操作方式的动词对服务端资源进行操作:
- GET用于获取资源
- POST用于新建资源(也可以用于更新资源)
- PUT用于更新资源
- DELETE用于新建资源
- 通过操作资源的表现形式来实现服务端请求操作。
- 资源的表现形式是JSON或HTML。
- 客户端与服务端之间的交互在请求之间是无状态的,从客户端到服务端的每个请求都包含必需的信息。
3、RESTful API
- 符合RESTful规范的Web API需要具备如下两个关键特性:
- 安全性:安全的方法被期望不会产生如何副作用,当我们使用GET操作获取资源时,不会引起资源本身的改变,也不会引起服务器状态的改变。
- 幂等性:幂等的方法保证了重复进行一个请求和一次请求的效果相同(并不是指响应总是相同的,而是指服务器上资源的状态从第一次请求后就不再改变了),在数学上幂等性是指N次变换和一次变换相同。
4、HTTP状态码
- HTTP状态码就是服务器向用户返回的状态码和提示信息,客户端的每一次请求,服务器都必须回应,回应包括HTTP状态码和数据两部分
- HTTP定义了40个标准状态码。可用于传达客户端请求的结果。状态码分为以下五个类别:
- 1xx:信息,通信传输协议级信息
- 2xx:成功,表示客户端的请求已成功接受
- 3xx:重定向,表示客户端必须执行一些其他操作才能完成其请求
- 4xx:客户端错误,此类错误状态码指向客户端
- 5xx:服务器错误,服务器负责这些错误状态码
5、SpringBoot实现RESTful API
- 在RESTful架构中,每个网址代表一种资源,所以URL中建议不要包含动词,只包含名词即可,而且所用的名词往往与数据库的表格名对应
- 用户管理模块API示例:
-
HTTP Method 接口地址 接口描述 POST /user 创建用户 GET /user/id 根据id获取用户信息 PUT /user 更新用户 DELETE /user/id 根据id删除对应用户
-
-
@RestController public class UserController { // @PathVariable:注:路由内属性与形参相同可简写, // 若不相同,则需要加上对应的名称绑定,如:@PathVariable("id") @GetMapping("/user/{id}") public String getUserById(@PathVariable int id){ System.out.println(id); return "根据ID获取用户信息"; } @PostMapping("/user") public String save(User user){ return "添加用户"; } @PutMapping("/user") public String update(User user){ return "更新用户"; } @DeleteMapping("/user/{id}") public String deleteById(@PathVariable int id){ System.out.println(id); return "根据id删除用户"; } }
6、Swagger
- Swagger是一个规范和完整的框架,用于生成、描述、调用和可视化RESTful风格的Web服务,是非常流行的API表达工具。
- Swagger能够自动生成完善的RESTful API文档,同时并根据后台代码的修改同步更新,同时提供完整的测试页面来调试API。
-
使用Swagger生成Web API文档
- 在Springboot项目中集成Swagger很简单,只需要在项目中引入springfox-swagger2和springfox-swagger-ui依赖即可。
-
<!-- swagger --> <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>
-
配置Swagger
- 注意:swagger版本不一样,配置也不一样(本人使用的是2.9.2版本)
-
@Configuration // 告诉spring容器,这个类是一个配置类 @EnableSwagger2 // 启用Swagger2功能 public class Swagger2Config { @Bean public Docket createRestApi(){ return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() // com包下的所有API都交给Swagger2管理 .apis(RequestHandlerSelectors.basePackage("com")) .paths(PathSelectors.any()) .build(); } // API文档页面显示信息 private ApiInfo apiInfo(){ return new ApiInfoBuilder() .title("文件系统项目API") // 标题 .description("学习Springboot+Vue项目") // 描述 .build(); } }
- 如果项目报以下的错误
- 这是因为Springboot2.6.x以后与Swagger有版本冲突问题,所以需要在yml文件或properties文件中添加以下配置
-
# yml文件: mvc: pathmatch: matching-strategy: ant_path_matcher # properties文件: spring.mvc.pathmatch.matching-strategy=ant_path_matcher
-
-
使用Swagger2进行接口测试
- 启动项目访问http://localhost:8888/swagger-ui.html,即可打开自动生成的可视化测试页面。
- 这个页面就是成功打开了。