Spring Boot 框架

​​​​​​​

随着 Java Spring 框架的不断的更新迭代和封装,演变出用最少的代码,干多个功能的 Spring Boot 框架。

今天无脑将介绍 Spring Boot 框架的基本使用,分享给大家,希望帮助大家大幅提高开发能力!

一、SpringBoot介绍


SpringBoot是由Pivotal团队研发的,SpringBoot并不是一门新技术,只是将之前常用的Spring,SpringMVC,data-jpa等常用的框架封装到了一起,帮助你隐藏这些框架的整合细节,实现敏捷开发。

SpringBoot就是一个工具集。

LOGO

1.1 SpringBoot 特点:

  • SpringBoot项目不需要模板化的配置。
  • SpringBoot中整合第三方框架时,只需要导入相应的starter依赖包,就自动整合了。
  • SpringBoot默认只有一个.properties的配置文件,不推荐使用xml,后期会采用.java的文件去编写配置信息。
  • SpringBoot工程在部署时,采用的是jar包的方式,内部自动依赖Tomcat容器,提供了多环境的配置。
  • 后期要学习的微服务框架SpringCloud需要建立在SpringBoot的基础上。

1.2 SpringBoot里的 SpringMVC 执行流程

主要组件:

  • 中央处理器( DispatcherServlet )
  • 处理器映射器(HandlerMapping)
  • 处理器适配器(HandlerAdapter)
  • 视图解析器(ViewResovler)

Spring Boot 中的 Spring MVC(Model-View-Controller)执行流程与传统的 Spring MVC 框架类似,但在 Spring Boot 中进行了一些自动配置,以简化开发和配置。以下是 Spring Boot 中 Spring MVC 的主要执行流程:

  1. 请求到达前端控制器: 请求首先到达前端控制器,通常是DispatcherServlet。Spring Boot 自动配置了这个控制器。
  2. 处理器映射: DispatcherServlet 根据请求的 URL 找到适当的处理器(Controller)来处理请求。这是通过映射器(HandlerMapping)来实现的。
  3. 处理器执行: 一旦找到了合适的处理器,DispatcherServlet 将请求交给该处理器执行。处理器会执行业务逻辑,并生成一个数据模型,通常是一个 Java 对象,用于构建响应。
  4. 模型和视图解析: 处理器执行后,数据模型和视图的名称将返回给 DispatcherServlet。Spring Boot 自动配置了视图解析器,以将视图名称解析为实际的视图模板(如JSP、Thymeleaf、FreeMarker等)。
  5. 视图渲染: DispatcherServlet 将数据模型传递给选定的视图模板引擎,视图模板引擎将数据与视图模板结合,生成HTML响应。
  6. 响应发送: 生成的HTML响应将发送回客户端浏览器。
  7. 中间件拦截: 在请求到达控制器之前和响应返回给客户端之前,可以使用中间件拦截请求和响应。Spring Boot允许您配置和使用拦截器来执行诸如身份验证、日志记录、性能监控等任务。
  8. 异常处理: 如果在执行处理器时发生异常,Spring Boot 可以自动捕获并处理异常。您可以配置全局异常处理器来处理应用程序中的异常情况。
  9. 静态资源处理: Spring Boot 自动配置了对静态资源(如CSS、JavaScript、图像等)的处理,因此可以轻松地为应用程序提供静态资源。

二、搭建环境

这里建议大家,使用 2022 版本以上的 IDAE ,Java 17 以上,本人是使用以上版本的。

2.1 导入依赖

这几个依赖内置了 tomcat、spring、spring MVC 的依赖,简化依赖的冗余。

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>-->

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.26</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

2.2 使用配置文件

/**
 * 权限实体类
 *
 * @author 无戏
 * @date 2023/10/31
 */
@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
public class Permission {
    private Integer id;
    private String name;
    private String type;
    private Integer isDeleted;
}

2.2.1 properties 配置文件

2.2.1.1 实体类
/**
 * 用户实体类
 * @author 无戏
 */
@Component
//Type-Safe(类型安全的),prefix:文件名前缀
@ConfigurationProperties(prefix = "user")
//加载 book.properties 配置文件到 Spring 容器中,这个相当于 XML 中的 placeholder 配置
@PropertySource("classpath:user.properties")

@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
public class User {
    /**
     * 直接获取 properties 配置文件的对应键的值
     * @Value("${user.id}")
     */
    private Integer id;
    /**
     * @Value("${user.password}")
     */
    private String password;
    //@Value("${user.imgUrl}")
    private String imgUrl;
    //@Value("${user.rId}")
    private Integer rId;
    //@Value("${user.isDeleted}")
    private Integer isDeleted;

    private Permission permission;
    private Permission[] permission2;
    private List<String> permission3;
    private Map<String,Object> permission4;
}

2.2.1.2 properties 配置文件

user.permission.name=1
user.permission.type=ss
user.permission.isDeleted=1
user.permission2[0].id=2
user.permission2[0].name=3
user.permission2[0].type=ss1
user.permission2[0].isDeleted=0
user.permission3[0]=2
user.permission3[1]=3
user.permission3[2]=ss1
user.permission4.id=2

2.2.2 yaml 或 yml 文件

2.2.2.1 实体类

/**
 * 用户实体类
 * @author 无戏
 */
@Component
@ConfigurationProperties(prefix = "user")

@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
public class User {
    /**
     * @Value("${user.id}")
     */
    private Integer id;
    /**
     * @Value("${user.password}")
     */
    private String password;
    //@Value("${user.imgUrl}")
    private String imgUrl;
    //@Value("${user.rId}")
    private Integer rId;
    //@Value("${user.isDeleted}")
    private Integer isDeleted;

    private Permission permission;
    private Permission[] permission2;
    private List<String> permission3;
    private Map<String,Object> permission4;
}

2.2.2.2 yaml 和 yml 配置文件

配置文件名以 appliaction 开头

user:
  id: 1110
  password: 123456
  imgUrl: null
  rId: 10
  isDeleted: 1
  permission:
    id: 999
    name: 超级管理员
    type:  1
    isDeleted: 1
  permission2:
    - id: 9992
      name: 超级管理员
      type: 1
      isDeleted: 1
    - id: 9993
      name: 超级管理员
      type: 1
      isDeleted: 1
  permission3:
    - 4
    - 5
    - 6
  permission4:
    a: b
    b: c

2.3 properties 和 yml 格式文件的优缺点

SpringBoot的配置文件支持 properties 和 yml ,甚至他还支持 json。

更推荐使用 yml 文件格式:

  1. yml 文件,会根据换行和缩进帮助咱们管理配置文件所在位置。
  2. yml文件,相比 properties 更轻量级一些。

yml文件的劣势:

  1. 严格遵循换行和缩进。
  2. 在填写 value 时,一定要在: 后面跟上空格。

三、application.properties 配置使用

3.1 修改 Tomcat 服务器信息

# 获取 java 版本号
myjava=@java.version@ # 17
# 修改 Tomcat 端口号
server.port=8081
server.servlet.context-path=/d
# 配置 URL 编码格式,这个默认就是 UTF-8
server.tomcat.uri-encoding=UTF-8

3.2 配置不同环境

# 配置执行的环境,如生产环境(prod)、测试环境(test)、开发环境(dev)
spring.profiles.active=test

生产环境:

server.port=8090

开发环境:

server.port=8090

测试环境:

server.port=99

3.3 配置自定义静态资源位置

# 自定义静态资源访问规则
spring.mvc.static-path-pattern=/qf/**
# 自定义静态资源路径
spring.web.resources.static-locations=classpath:qf/

3.4 配置 JDBC 连接信息

# JDBC 驱动
spring.datasource.url=jdbc:mysql://localhost:3306/xmbg?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=false
# mysql 用户名
spring.datasource.username=root
# 密码
spring.datasource.password=1234

3.5 Mybatis-plus配置

mybatis-plus.configuration.map-underscore-to-camel-case=false

四、配置响应到前端的 JSON 格式

控制层:

/**
 * @author 无戏
 * @projectName 控制层
 * @date 2023/11/1 9:58
 */
@RestController
public class UserController {
    @GetMapping("/hello")
    public User hello(){
        return User.builder().id(5555).password(new Date()).build();
    }
}

实体类;

/**
 * 用户实体类
 * @author 无戏
 */
@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
public class User {
    private Integer id;
    private Date password;
}

4.1 jackson 配置

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

配置类:

/**
 * @author 无戏
 * @projectName 格式化时间
 * @date 2023/11/1 15:14
 */
@Configuration
public class WebConfig {
    @Bean
    ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));
        return objectMapper;
    }
}

4.2 谷歌的 gson 转 JSON

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
</dependency>

/**
 * @author 无戏
 * @projectName 格式化时间
 * @date 2023/11/1 15:14
 */
@Configuration
public class WebConfig {
    @Bean
    GsonBuilder gsonBuilder() {
        return new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss");
    }
}

4.3 阿里巴巴

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.70</version>
</dependency>

/**
 * @author 无戏
 * @projectName 格式化时间
 * @date 2023/11/1 15:14
 */
@Configuration
public class WebConfig {
    @Bean
    HttpMessageConverter httpMessageConverter() {
        FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
        FastJsonConfig config = new FastJsonConfig();
        config.setDateFormat("yyyy-MM-dd HH:mm:ss");
        converter.setFastJsonConfig(config);
        converter.setDefaultCharset(Charset.forName("UTF-8"));
        return converter;
    }
}

五、文件上传和下载

# 文件保存目录
savePath=E:\\Datas\\file

5.1 文件上传

/**
 * @author 无戏
 * @projectName
 * @date 2023/11/1 9:58
 */
@RestController
public class UserController {
    private DateTimeFormatter dtf = DateTimeFormatter.ofPattern("/yyyy/MM/dd/");
    @Value("${savePath}")
    private String savePath;

    @GetMapping("/hello")
    public User2 hello(){
        return User2.builder().id(5555).password(new Date()).build();
    }

    @PostMapping("/upload")
    public String upload(MultipartFile file, HttpServletRequest request){
        LocalDateTime now = LocalDateTime.now();
        String format = now.format(dtf);
        String path = savePath + format;
        File file1 = new File(path);
        if (!file1.exists()) {
            file1.mkdirs();
        }
        String filename = file.getOriginalFilename();
        String newFileName = UUID.randomUUID().toString() + filename.substring(filename.indexOf("."));
        try {
            file.transferTo(new File(path, newFileName));
            return request.getScheme()
                    + "://"
                    + request.getServerName()
                    + ":"
                    + request.getServerPort()
                    + request.getContextPath()
                    + "/upload"
                    + format + newFileName;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }
}

5.2 原始文件下载方式

/**
 * @author 无戏
 * @projectName
 * @date 2023/11/1 9:58
 */
@RestController
public class UserController {
    private DateTimeFormatter dtf = DateTimeFormatter.ofPattern("/yyyy/MM/dd/");
    @Value("${savePath}")
    private String savePath;

    @GetMapping("/upload/{year}/{month}/{day}/{filename}")
    public void download(@PathVariable String year, @PathVariable  String month,
                                           @PathVariable String day, @PathVariable String filename,
                                           HttpServletResponse response) throws IOException {
        File file = new File(savePath + File.separator + year + File.separator + month + File.separator + day
                + File.separator + filename);
        //有这个响应头,就是文件下载,没有这个响应头,就是访问
        response.setHeader("content-disposition", "attachment;filename="
                + new String(filename.getBytes("UTF-8"), "ISO-8859-1"));

        ServletOutputStream os = response.getOutputStream();
        FileInputStream fs = new FileInputStream(file);
        int len = 0;
        byte[] bytes = new byte[1024];
        while ((len = fs.read(bytes)) != -1) {
            os.write(bytes, 0, len);
        }
        os.flush();
        fs.close();
    }
}

5.3 Spring Boot 方法文件下载

/**
 * @author 无戏
 * @projectName
 * @date 2023/11/1 9:58
 */
@RestController
public class UserController {
    @GetMapping("/upload2/{year}/{month}/{day}/{filename}")
    public ResponseEntity<byte[]> download2(@PathVariable String year, @PathVariable  String month,
            @PathVariable String day, @PathVariable String filename, HttpServletResponse response) throws IOException {
        File file = new File(savePath + File.separator + year + File.separator + month + File.separator + day
                + File.separator + filename);

        FileInputStream fs = new FileInputStream(file);
        ByteArrayOutputStream aos = new ByteArrayOutputStream();
        int len = 0;
        byte[] bytes = new byte[1024];
        while ((len = fs.read(bytes)) != -1) {
            aos.write(bytes, 0, len);
        }
        HttpHeaders headers = new HttpHeaders();
        headers.setContentDispositionFormData("filename", new String(filename.getBytes("UTF-8"), "ISO-8859-1"));
        //第一个参数是文件本身
        //第二个是响应头
        //第三个是 HTTP 状态码
        return new ResponseEntity<>(aos.toByteArray(), headers, HttpStatus.OK);
    }
}

六、静态资源

6.1 默认的静态资源位置

Spring Boot 中默认提供了五个静态资源存储路径:

  • classpath:/META-INF/resources/
  • classpath:/resources/
  • classpath:/static/
  • classpath:/public/
  • /(webapp)

五个位置,优先级依次降低。

6.2 自定义静态资源位置

如果需要自定义静态资源位置,有两种方式:

  • 自定义的静态资源路径需要在加上自定义的位置,默认的不需要
  1. application.properties 中进行配置
# 自定义静态资源访问规则
spring.mvc.static-path-pattern=/qf/**
# 自定义静态资源路径
spring.web.resources.static-locations=classpath:qf/
  1. 写 JAVA 代码配置
/**
 * @author 无戏
 * @projectName 自定义静态资源位置
 * @date 2023/11/1 15:14
 */
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/qf/**")
                .addResourceLocations("classpath:qf/");
    }
}

七、模板引擎

Spring MVC 的数据模型通常是通过控制器传递给视图的数据对象,用于呈现给用户界面。数据模型的主要目的是在控制器和视图之间传递数据。

7.1 Freemarker

7.1.1 Freemarker 简介

这是一个相当老牌的开源的免费的模版引擎,基于Apache许可证2.0版本发布。 通过 Freemarker 模版,我们可以将数据渲染成 HTML 网页、电子邮件、配置文件以及源代码等。

Freemarker 不是面向最终用户的,而是一个 Java 类库,我们可以将之作为一个普通的组件嵌入到我们 的产品中。

可以看到,Freemarker 可以将模版和数据渲染成 HTML 。 Freemarker 模版后缀为 .ftlh (FreeMarker Template Language)。FTL 是一种简单的、专用的语言, 它不是像 Java 那样成熟的编程语言。在模板中,你可以专注于如何展现数据, 而在模板之外可以专注 于要展示什么数据。

7.1.2 项目结构

导入依赖 :

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>

7.1.3 Freemarker 代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<#if users?? && (users?size>0)>
    <table border="1">
        <tr>
            <td>用户名</td>
            <td>用户地址</td>
            <td>用户爱好</td>
            <td>用户生日</td>
        </tr>
        <#list users as user>
            <tr>
                <td>${user.username}</td>
                <td>${user.address}</td>
                <td>
                    <#list user.favorites as f>
                        ${f};
                    </#list>
                </td>
                <td>${user.birthday?string('yyyy-MM-dd')}</td>
            </tr>
        </#list>
    </table>
<#else>
    暂无数据
</#if>
</body>
</html>

7.1.4 控制层代码

  • 注意传入视图名称要与 .flth 文件名一致。

第一种写法:

  • ModelAndView 类是一个将模型数据和视图名称组合在一起的容器。控制器可以创建一个 ModelAndView 对象并设置模型数据以及要呈现的视图名称。
/**
 * @author 无戏
 */
@Controller
public class UserController {

    @GetMapping("/hello")
    public ModelAndView hello() {
        //传入视图名称
        ModelAndView mv = new ModelAndView("hello");
        List<User> users = new ArrayList<>();
        User u1 = new User();
        u1.setUsername("张三");
        u1.setAddress("广州");
        u1.setBirthday(new Date());
        List<String> f1 = new ArrayList<>();
        f1.add("足球");
        f1.add("篮球");
        u1.setFavorites(f1);
        users.add(u1);
        User u2 = new User();
        u2.setUsername("里斯");
        u2.setAddress("深圳");
        u2.setBirthday(new Date());
        List<String> f2 = new ArrayList<>();
        f2.add("乒乓球");
        f2.add("篮球");
        u2.setFavorites(f2);
        users.add(u2);
        mv.addObject("users", users);
        return mv;
    }
}

第二种写法:

  • 您可以使用java.util.Map或org.springframework.ui.Model接口作为数据模型。这些对象允许您以键值对的形式存储数据,然后在视图中使用这些键来检索数据。
/**
 * @author 无戏
 */
@Controller
public class UserController {

    @GetMapping("/hello")
    public String hello(Model model) {
        //传入视图名称
        //ModelAndView mv = new ModelAndView("hello");
        List<User> users = new ArrayList<>();
        User u1 = new User();
        u1.setUsername("张三");
        u1.setAddress("广州");
        u1.setBirthday(new Date());
        List<String> f1 = new ArrayList<>();
        f1.add("足球");
        f1.add("篮球");
        u1.setFavorites(f1);
        users.add(u1);
        User u2 = new User();
        u2.setUsername("里斯");
        u2.setAddress("深圳");
        u2.setBirthday(new Date());
        List<String> f2 = new ArrayList<>();
        f2.add("乒乓球");
        f2.add("篮球");
        u2.setFavorites(f2);
        users.add(u2);
        model.addAttribute("users", users);
        return "hello";
    }
}

7.2 Thymeleaf

7.2.2 Thymeleaf 简介

Thymeleaf 是新一代 Java 模板引擎,它类似于 Velocity、FreeMarker 等传统 Java 模板引擎,但是与传统 Java 模板引擎不同的是,Thymeleaf 支持 HTML 原型。

它既可以让前端工程师在浏览器中直接打开查看样式,也可以让后端工程师结合真实数据查看显示效果,同时,SpringBoot 提供了 Thymeleaf 自动化配置解决方案,因此在 SpringBoot 中使用Thymeleaf 非常方便。

事实上, Thymeleaf 除了展示基本的 HTML ,进行页面渲染之外,也可以作为一个 HTML 片段进行渲染,例如我们在做邮件发送时,可以使用 Thymeleaf 作为邮件发送模板。另外,由于 Thymeleaf 模板后缀为.html ,可以直接被浏览器打开,因此,预览时非常方便。

7.2.2 导入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

7.2.3 Thymeleaf 代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<a th:each="link : ${links}" th:href="${link.url}" th:text="${link.name}"></a>


<table border="1">
    <tr>
        <td>用户名</td>
        <td>用户地址</td>
        <td>用户生日</td>
        <td>用户爱好</td>
    </tr>
    <tr th:each="u : ${users}">
        <td th:text="${u.username}"></td>
        <td th:text="${u.address}"></td>
        <td th:text="${u.birthday}"></td>
        <td>
            <div th:each="f : ${u.favorites}">
                <div th:text="${f}"></div>
                ;
            </div>
        </td>
    </tr>
</table>
</body>
</html>

7.2.4 控制层代码

  • 注意返回的字符串即为视图名称要与 .html 文件名一致。
/**
 * @author 无戏
 */
@Controller
public class UserController {
    @GetMapping("/hello")
    public String hello(Model model) {
        //传入视图名称
        List<User> users = new ArrayList<>();
        User u1 = new User();
        u1.setUsername("张三");
        u1.setAddress("广州");
        u1.setBirthday(new Date());
        List<String> f1 = new ArrayList<>();
        f1.add("足球");
        f1.add("篮球");
        u1.setFavorites(f1);
        users.add(u1);
        User u2 = new User();
        u2.setUsername("里斯");
        u2.setAddress("深圳");
        u2.setBirthday(new Date());
        List<String> f2 = new ArrayList<>();
        f2.add("乒乓球");
        f2.add("篮球");
        u2.setFavorites(f2);
        users.add(u2);
        model.addAttribute("users", users);
        List<Link> links = new ArrayList<>();
        Link l1 = new Link();
        l1.setName("百度一下");
        l1.setUrl("http://www.baidu.com");
        links.add(l1);
        Link l2 = new Link();
        l2.setName("Google");
        l2.setUrl("http://www.google.com");
        links.add(l2);
        model.addAttribute("links", links);
        return "hello";
    }
}

7.3 JSP

项目结构:必须在 web 模块的 web 或 webapp 目录下。

7.3.1 导入依赖

<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
</dependency>

7.3.2 JSP 代码

<%--
  Created by IntelliJ IDEA.
  User: 无戏
  Date: 2023/11/2
  Time: 12:03
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    ${hello}
</body>
</html>

7.3.3 控制层 代码

/**
 * @author 无戏
 */
@Controller
public class UserController {
    @GetMapping("/hello")
    public String hello2(Model model) {
        // 
        model.addAttribute("hello", "hello jsp");
        return "hello";
    }
}

八、异常处理

整体来说两种方式:

  1. 静态页面展示异常
    • 明确展示(推荐)
    • 模糊展示
  1. 动态页面展示异常
    • 明确展示
    • 模糊展示(推荐)

具体查找方式:

  1. 先找明确的,再找模糊的
  2. 先找动态的,再找静态的

# 表示是否展示异常类名
server.error.include-exception=true
# always(一直展示)或 never(不展示)
# 表示是否展示错误堆栈信息
server.error.include-stacktrace=always
# 表示是否展示错误信息
server.error.include-message=always

报错页面展示效果:

模板页面代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>error</title>
</head>
<body>
<h1>01.ftlh(动态)</h1>
<table border="1">
    <tr>
        <td>error</td>
        <td>${error!}</td>
    </tr>
    <tr>
        <td>message</td>
        <td>${message!}</td>
    </tr>
    <tr>
        <td>timestamp</td>
        <td>${timestamp?string('yyyy-MM-dd HH:mm:ss')}</td>
    </tr>
    <tr>
        <td>status</td>
        <td>${status!}</td>
    </tr>
    <tr>
        <td>path</td>
        <td>${path!}</td>
    </tr>
    <tr>
        <td>exception</td>
        <td>${exception!}</td>
    </tr>
    <tr>
        <td>e</td>
        <td>${e!}</td>
    </tr>
    <tr>
        <td>trace</td>
        <td>${trace!}</td>
    </tr>
</table>
</body>
</html>

8.1 异常出现时默认展示的页面

如下图:

  • 默认情况下,出现报错先去 templates.error 目录下找 FreeMarker 或 Thymeleaf 的模板文件,然后再到 static.error 目录下找 静态页面。
  • 注意:5xx 或 4xx 表示是模糊的,500 或 404 表示是具体的状态码;使用模板都需要导入模板依赖。

8.2 自定义异常访问的位置

自定义异常信息:

/**
 * @author 无戏
 * @projectName 自定义异常信息
 * @date 2023/11/2 19:15
 */
@Component
public class MyErrorAttributes extends DefaultErrorAttributes {
    @Override
    public Map<String, Object> getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions options) {
        Map<String, Object> errorAttributes = super.getErrorAttributes(webRequest, options);
        errorAttributes.put("e", "出错了");
        return errorAttributes;
    }
}

自定义异常访问的位置:

/**
 * @author 无戏
 * @projectName 自定义异常访问的位置
 * @date 2023/11/2 19:19
 */
@Component
public class MyErrorViewResolver extends DefaultErrorViewResolver {
    /**
     * 我错误视图解析器
     *
     * @param applicationContext 应用程序上下文
     * @param webProperties      web属性
     */
    public MyErrorViewResolver(ApplicationContext applicationContext, WebProperties webProperties) {
        super(applicationContext, webProperties.getResources());
    }

    /**
     * 解析错误视图
     *
     * @param request 要求
     * @param status  地位
     * @param model   模型
     * @return {@link ModelAndView}
     */
    @Override
    public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
        //model.put("e", "出错啦");
        return new ModelAndView("qf/01", model);
    }
}

九、Spring Boot 和 Mybatis 框架整合

9.1 导入相关依赖

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- Mybatis 依赖  -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>3.0.2</version>
        </dependency>

        <!-- Mysql JDBC 数据库依赖 -->
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!-- 优化实体依赖 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- Tomcat 服务器依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <!-- Spring Boot 测试依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter-test</artifactId>
            <version>3.0.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

9.2 配置映射文件

spring.datasource.url=jdbc:mysql://localhost:3306/xmbg?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=false
spring.datasource.username=root
spring.datasource.password=1234
# 映射文件的路径,第二种方法使用
# mybatis.mapper-locations=classpath*:mapper/*.xml

9.2.1 第一种

如UserMapper.xml 位置为 UserMapper接口的全路径:

9.2.2 第二种

推荐使用:

只需在 application.properties 文件里加映射文件资源位置就行,如下所示:

spring.datasource.url=jdbc:mysql://localhost:3306/xmbg?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=false
spring.datasource.username=root
spring.datasource.password=1234
# 映射文件的路径,第二种方法使用
mybatis.mapper-locations=classpath*:mapper/*.xml

9.3 配置接口扫描进 Spring 容器

9.3.1 第一种

  • 接口直接加 @Mapper 注解
/**
 * @author 无戏
 * @projectName
 * @date 2023/11/2 20:38
 */
@Mapper
public interface UserMapper {
    /**
     * 全选
     *
     * @return {@link List}<{@link User}>
     */
    List<User> selectAll();
}

9.3.2 第二种

  • 直接在 Spring Boot 的启动类里加 @MapperScan 注解

@MapperScan 是使用 MyBatis 框架时用于指定扫描 Mapper 接口的包或类路径的注解。该注解可以用于在 Spring Boot 环境中自动将 Mapper 接口注册为 Spring Bean。

@MapperScan 注解有三个重要的属性:

  1. value:指定需要扫描的 Mapper 接口所在的包或类路径,支持使用数组的形式指定多个路径。例如:
@MapperScan("com.example.mapper")

  1. basePackages:与 value 属性的作用相同,都是用于指定包或类路径,支持多个路径的指定,例如:
@MapperScan(basePackages = {"com.example.mapper1", "com.example.mapper2"})

  1. basePackageClasses:用于指定需要扫描的 Mapper 接口类,可以扫描指定类所在的包路径下的所有 Mapper 接口。例如:
@MapperScan(basePackageClasses = UserMapper.class)


在这个例子中,UserMapper 是一个 Mapper 接口类,@MapperScan 注解会自动扫描该接口所在的包路径下的所有 Mapper 接口。

使用 @MapperScan 注解可以快速设置所有 Mapper 接口。如果您要扫描多个包或类路径,可以使用数组的形式,或者使用多个 value 属性。在您指定了需要扫描的 Mapper 接口所在的类或类路径后,MyBatis 框架就会自动查找 Mapper 接口,并将其注册为 Spring Bean。

/**
 * @author 无戏
 * @projectName
 * @date 2023/11/2 20:38
 */
public interface UserMapper {
    /**
     * 全选
     *
     * @return {@link List}<{@link User}>
     */
    List<User> selectAll();
}

注解说明

1.Spring Boot 的注解

@SpringBootApplication:是一个组合注解,包含以下注解。

  1. @SpringBootConfiguration就是@Configuration注解,代表启动类就是一个配置类。
  2. @EnableAutoConfiguration帮你实现自动装配的,SpringBoot工程启动时,运行一个SpringFactoriesLoader的类,加载META-INF/spring.factories配置类(已经开启的),通过SpringFactoriesLoader中的load方法,以for循环的方式,一个一个加载。
    • 好处:无需编写大量的整合配置信息,只需要按照SpringBoot提供好了约定去整合即可。
    • 坏处:如果说你导入了一个starter依赖,那么你就需要填写他必要的配置信息。
    • 手动关闭自动装配指定内容:@SpringBootApplication(exclude = QuartzAutoConfiguration.class)
  1. @ComponentScan就相当于<context:component-scan basePackage=“包名” />,帮助扫描注解的。

@EnableAutoConfiguration:启用Spring Boot的自动配置机制,根据应用程序的类路径和依赖自动配置Spring应用。

ConfigurationProperties:是 Spring Boot 中一个重要的注解,用于绑定配置属性到一个 Java 类。这允许您将应用程序的配置属性加载到一个 POJO(Plain Old Java Object)中,以便更方便地使用和管理这些属性。

2.Spring 注解

  • @PropertySource:

@PathVariable:用于从URL中提取路径变量,通常用于RESTful风格的URL。

@RequestParam:用于从HTTP请求中获取请求参数的值。

@Configuration:用于定义配置类,可以包含@Bean注解的方法,以配置应用程序中的bean。

@DateTimeFormat:用于指定日期字段的格式化方式,以将字符串表示的日期转换为Java日期对象。

@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date date;

@JsonFormat:用于指定日期字段在JSON序列化和反序列化时的格式。

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date date;

@Value:用于注入配置属性值,例如从application.properties文件中获取值。

@Value("${user.password}")
private String password;

@EnableScheduling:用于启用Spring定时任务(Scheduled Task),允许在指定的时间间隔内执行方法。用于启用 Spring 的计划任务(Scheduling)支持,允许您在应用程序中使用 @Scheduled 注解来定义定时任务。

@Scheduled:注解允许您将方法标记为定时任务,您可以使用不同的参数来配置任务的执行方式。以下是 @Scheduled 注解的主要参数说明:

  1. fixedRate:定义了方法的执行周期,以毫秒为单位。指定了方法执行的固定时间间隔。例如,@Scheduled(fixedRate = 5000) 表示每隔5秒执行一次方法。
  2. fixedDelay:与 fixedRate 类似,但是是上一次任务完成后的延迟时间,而不是上一次任务开始后的延迟时间。例如,@Scheduled(fixedDelay = 5000) 表示每个任务之间有5秒的延迟。
  3. initialDelay:定义了首次执行任务的延迟时间,以毫秒为单位。它指定了从应用程序启动开始到第一次执行任务之间的时间。例如,@Scheduled(initialDelay = 10000, fixedRate = 5000) 表示在启动后10秒开始执行任务,然后每隔5秒执行一次。
  4. cron:使用 Cron 表达式来定义任务的执行时间。Cron 表达式提供了更灵活的定时任务调度方式,允许您定义精确的执行时间。例如,@Scheduled(cron = "0 0 9 * * ?") 表示每天早上9点执行任务。

@Configuration
@EnableScheduling
public class ScheduledTasks {
    @Scheduled(fixedRate = 5000) // 每5秒执行一次
    public void doTask() {
        // ...
    }
}

@ComponentScan 注解用于告诉 Spring Boot 在哪里查找 Spring 组件(bean),并注册它们到应用程序上下文中。通常,您将在配置类上使用 @ComponentScan 来指定一个或多个包,Spring Boot 将扫描这些包以查找带有 @Component 或其他特定注解的类,并将它们自动注册为 Spring 组件。

以下是 @ComponentScan 的基本用法示例:

@Configuration
@ComponentScan(basePackages = "com.example.myapp")
public class AppConfig {
    // 配置类的其他内容
}

以上就是本期分享,希望对大家有帮助吧~

走过路过关注一波儿吧,感谢!

三连 的给个 三连 ,没三连的 给个点赞 也是美滋滋的,谢谢各位大佬。

我是无脑,点赞 + 在看 还是想求一下的,祝大家都能心想事成、发大财、行大运。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值