Spring Boot

一、springBoot入门

1.springboot简介

简化spring的框架

整个spring技术栈的大集合

J2EE开发一站式解决方案

2.微服务

微服务:架构风格

一个应用应该是一组小型服务:通过http的方式进行沟通

每一个功能元素最终都是一个可独立替换或独立升级的软件单元

单体应用:All In One

3.HelloWorld

一个功能:浏览器发送hello请求 服务器接收请求并处理 ,响应helloworld字符串;

1)、创建maven项目

使用maven3.3.6版本 3.6.2会报错

2)、导包

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

3)、编写主程序启动springboot

package com.atguigu;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/*
@SpringBootApplication 标注一个主程序类 说明他是一个Spring Boot应用
 */
@SpringBootApplication
public class HelloWorldMainApplication {
    public  static void main(String[] args){
        //Spring应用启动起来
        SpringApplication.run(HelloWorldMainApplication.class,args);
    }
}

4 )、编写相关Controller和Service

package com.atguigu.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class HelloController {
    @ResponseBody
    @RequestMapping("/hello")
    public String hello(){
        return "hello world";
    }
}
 

5)、直接运行可以出结果

6)、简化部署

1简化部署必须导入springboot 插件

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

2导入插件之后 点击打包

在这里插入图片描述

3将应用直接打成jar包 在控制台可以java -jar jar路径 的命令直接运行

不必配置tomcat springboot运行或打包都会自带tomcat环境

4.HelloWorld探究

1)、POM文件

2)、父项目
<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
</parent>
他的父项目是
<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-dependencies</artifactId>
		<version>1.5.9.RELEASE</version>
		<relativePath>../../spring-boot-dependencies</relativePath>
	</parent>
他是真正管理springboot应用里的所有依赖

以后我们导入的依赖是不需要写版本号的(不在这里的才需要写)

3)、导入的依赖
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
</dependency>

spring-boot-starter-web:web启动器

spring-boot-starter:各种启动器场景启动器 :我们导入了web模块需要的组件

spring-boot将所有功能场景抽取出来 做成一个个启动器 ,只需要导入要用的启动器,她所依赖的会自动导入,要用什么功能就导入什么

2)、主程序类

package com.atguigu;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/*
@SpringBootApplication 标注一个主程序类 说明他是一个Spring Boot应用
 */
@SpringBootApplication
public class HelloWorldMainApplication {
    public  static void main(String[] args){
        //Spring应用启动起来
        SpringApplication.run(HelloWorldMainApplication.class,args);
    }
}

@SpringBootApplication:标注的类说明是spring boot的主配置类 spring boot就应该运行这个类的main方法来运行spring boot应用

点进注解看一下

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
		@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {。。。}

@SpringBootConfiguration:springboot配置类;

​ 标注在某个类上表示这是springboot的配置类,这个注解在点下去是@Configuration 也就是spring的注解 在点下去是一个@componment组件

@EnableAutoConfiguration;开启自动配置功能

​ 以前spring配置的东西springboot帮我们配置 ,EnableAutoConfiguration告诉springboot打开自动配置 这样配置才能生效

@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

​ @AutoConfigurationPackage:自动配置包

​ @Import(AutoConfigurationPackages.Registrar.class);

​ spring的底层注解,作用是给容器导入指定组件

将主配置类(@springbootapplication标注的类)所在包及下面所有组件扫 描到spring容器中 这就是为什么controller能被扫进来的原因

​ @Import(EnableAutoConfigurationImportSelector.class);

​ 给容器中导入组件??

​ EnableAutoConfigurationImportSelector;导入哪些组建的选择器

​ 将需要导入的组件以全类名的方式返回,然后添加到容器中

​ 会给容器添加非常多的自动配置类(xxxAutoConfiguratiion)

​ 有个这些自动配置 免去了我们手动编写配置注入功能组件的工作

这个类包含了j2EE所有功能都被配置好了

在这里插入图片描述

5.使用spring initializer 快速创建Spring Boot

在这里插入图片描述

创建号springboot:

主程序已经被创建好,我们只需要写业务

resources文件夹中目录结构

​ static :js css img

​ tamplates:保存所有模板页面(springboot默认jar包使用内嵌tomcat,默认不支持jsp页面)可以使用模板引擎(thymeleaf)

​ application。properties:springboot应用的配置文件 可以修改默认设置

@RestController 相当于 @Controller和@ResponseBody的合体

二 配置文件

1.配置文件

SpringBoot有一个全局配置文件

*application.propertier 优先级最高 如果不指定 都读取这里的内容

*application.yml

配置文件作用就是修改默认配置 比如修改端口号

YAML语言:

​ 以前的配置文件 XXX.xml

​ YAML以数据为中心 比json和xml更适合做配置文件

YAML:语法

server:
  port: 8090

XML

<server>
	<port>8090</port>
</server>

2.yaml语法

1)、基本语法

k:空格v(表示键值对 空格必须有)不能用tab

以空格控制层级关系 对齐的就是同一级

2)、 值的写法

字面量:(数字,字符串,布尔值)

k: v

字符串不用加上单引号或者双引号

​ “ ”:表示会转义字符串中的特殊字符

​ ‘ ’ :不会转义字符串中的特殊字符

对象

friends:
	name: lisi
	age: 18

行内写法

friends: {name: lisi,age: 18}

数组

animal:
 - cat
 - pig
 - dog

行内写法

animal: [cat,pig,dog]

3.yaml给bean赋值

导包 yaml为bean赋值的依赖包而且yaml为bean属性赋值就会有提示

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
</dependency>

写bean 此处不带要写getset和tostring

public class Person {
    private String name;
    private Integer age;
    private boolean flag;
    private Date date;

    private Map<String,Object> map ;
    private List<Object> list;
    private Dog dog;
    }

写yaml

server:
 port: 8090

person:
  name: 张三
  age: 18
  flag: true
  date: 2020/2/2
  map: {k1: v1,k2: v2}
  list:
    - lisi
    - zhaoliu
  dog:
    name: huanggou
    age: 18

测试

package com.example.springboot02;

import com.example.springboot02.bean.Person;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
/*
    @RunWith带表使用springboot的测试类 不用junit的
 */
@RunWith(SpringRunner.class)
@SpringBootTest
class Springboot02ApplicationTests {
    @Autowired
    Person person;
    @Test
    void contextLoads() {
        System.out.println(person);
    }

}

4.properties给bean赋值

person.age=18
person.date=2017/18/18
person.flag=false
person.name=李嘉伟
person.map.k1=v1
person.list=1,2,3
person.dog.name=sad
person.dog.age=15

1在properties中配置这些属性之后输出出来可能出现乱码

2如果yaml也存在会优先使用 properties的内容 因为paoperties是全局配置文件

是因为idea 编码是utf-8 而文件编码是另一种 在设置中更改编码即可 如果还是乱码 删了文件重建

在这里插入图片描述

5.@Value

@value(“李嘉伟”)在spring中已经使用过 单独给某个属性赋值

@Value("${person.name}") 从properties文件中拿到值在赋值给属性 或者拿文件的值 跟mybatis获取jdbc连接那个一样 如果用这个语法写 没找到就报错

@Value(#{2*6}) 也能写spel表达式 会自动计算在赋值

@Value 不支持赋值对象类型 就算从配置文件拿到了对象类型也不能赋值

6.@value和@ConfigurationProperties(prefix = “”)的区别

在这里插入图片描述
松散绑定:如果属性名是name 配置文件写个Name=李四 这样也能识别 @value 必须写配置文件一样的属性

spel:@Value(#{2*6})@value 支持 配置文件里不能这么写

数据校验:@Validated 说明一个类下的字段要校验 @Email 校验 字段是不是邮件格式 如果用@value赋值 不会校验

复杂类型:@Value 不支持赋值对象类型 就算从配置文件拿到了对象类型也不能赋值

如果只是获取配置文件的基本类型就用@Value

7.@PropertySource

@PropertySource(value = {"classpath:Person.properties"})

加载指定的配置文件 @ConfigurationProperties默认从全局配置文件中获取内容 如果所有的东西都放到全局配置文件就有点乱 所以我们把一些和全局不相关的配置放到别的配置文件 @PropertySource 就是用来读取指定配置文件的

注意:@ConfigurationProperties 还得加上 不能省略 而且全局配置文件不能写关于该类的赋值 否则还是会读全局配置 因为全局配置优先

8.@ImportSource

我们自己写了一个spring的配置文件 springboot无法识别 我们需要在springboot应用类类上加一个注解

@ImportSource(value={" classpath:bean.xml"})

9.配置文件的优先级

在这里插入图片描述

在这里插入图片描述

这四个位置处都配置了不同的端口号 按照优先级覆盖 不相同的属性都会都加入 相同的属性按优先级覆盖

10.外部配置加载顺序

springboot也可以从以下位置加载配置文件 高优先级会覆盖低优先级 所有配置互补

1)、命令工行参数

java -jar spring-config-0.0.1-SNAPSHOT.jar --server.port=8090

2)、jar包外部

在这里插入图片描述

命令执行jar包 会自动执行 jar包外部的配置文件

11.自动配置原理

在这里插入图片描述

三 日志

1.日志框架

我们选用 日志接口是SLF4J

日志的实现类是 Logback

springboot底层是spring框架 spring默认的日志是JClspringboot

​ springboot变成了 SLEF4j和Logback

2.SELF4J使用

1如何在系统中使用SELF4J

​ 以后再开发的时候 日志记录方法的调用 ,不应该调用实现类的方法 ,而是调用日志抽象层的方法

导入SELF4J的jar包

3.SpringBoot使用日志

springboot项目默认导入了loging包

依赖关系:

在这里插入图片描述

使用到其他框架 其他框架使用的日志不一样 一定要把其他框架的默认日志依赖移除掉

使用

package com.lijiawei.log;

import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;


@SpringBootTest
class SpringbootLogApplicationTests {
    //获取日志
    Logger logger = LoggerFactory.getLogger(getClass());
    @Test
    void contextLoads() {
        //日志的级别 由低到高  调整日志级别 以后就只输出设置的级别以上的
        logger.trace(" 这是trace日志");
        logger.debug("这是debug日志");
        logger.info("这是info信息");
        logger.warn("这是warn日志");
        logger.error("这是error日志");
    }

}

设置一些属性在全局配置中

#更改日志级别 指定那个包下
logging.level.com.lijiawei=trace
#当前项目下生成文件保存日志
logging.file=spring.log

或者创建一个文件 以后写logback-spring.xml 这样可以使用高级功能

在这里插入图片描述

四springboot与web开发

1.springboot静态资源的映射规则

1)、webjars

所有/webjars/** 都去classpath:/META-INF/resources/webjars/找资源

webjars:以jar包的方式引入资源

要引入JQuery或BootStrao去https://www.webjars.org/ 找对应的jar包

jquery的

<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>jquery</artifactId>
    <version>3.3.1</version>
</dependency>

我们引入了JQuery的jar包 会自动形成springboot能识别的目录结构

在这里插入图片描述

访问路径 localhost:8080/webjars/jquery/3.3.1/jquery.js

2)、/**访问任何资源

自己写的静态文件去哪里找呢?

"classpath:/META-INF/resources/"
"classpath:resources/"
"classpath:static/"
"classpath:public/"
"/"根路径

3)、欢迎页

默认寻找静态资源下(上面的几个路径)的所有index.html页面 优先级由高到低 找到就显示

4)、网页图标

直接把图片放到静态资源路径下 按优先级寻找 找到就显示

2.模板引擎thymeleaf

导包 在springboot2.2.4以上默认用的thymeleaf版本是3.0.11

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

thymeleaf语法

thymeleaf顶替了一个视图解析器 前缀 ”classpath:/templates“ 后缀.html

thymeleaf第一次使用

在这里插入图片描述

package com.example.demo01.contaoller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class HelloController {
    
     //现在我们不用写视图解析只需要直接返回文件名 在templates写html文件 springboot自动试图解析
    @RequestMapping("demo")
    public String show1(){
        return "success";
    }
}

1)、thymeleaf获取值

在控制器设置的值 html不是jsp不能用内置对象获取设置的值 在html中使用thymeleaf获取值

1导入thymeleaf的名称空间、

<html lang="en" xmlns:th="http://www.thymeleaf.org">

2使用thymeleaf

controller

package com.example.demo01.contaoller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.Map;

@Controller

public class HelloController {
    @RequestMapping("demo")
    public String show1(Map<String,Object> map){
        map.put("age",1);//设置一个值 一会在html中获取
        return "success";
    }
}

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>成功</h1>
<!--th:text="" 将div里的文本内容设置为指定的值-->
<div th:text="${age}"></div>
</body>
</html>

2)、语法规则

th:text="" 改变当前元素的文本内容

在这里插入图片描述

th:each 会把当前所在标签创建n个

th:text给给这个标签的内容赋值
<h1 th:text="${ag}" th:each="ag:${age}"></h1>
//行内赋值语法 俩个中括号 或者【()】 这代表转义
<h2 th:each="ag:${age}">[[${ag}]]</h2>

表达式:

${…}获取变量值

​ 1 对象的属性 调用方法

​ 2使用内置的基本对象

​ 3内置的工具对象

*{} 选择表达式

​ 和${…}一样 但有个补充功能 可以先获取对象 之后调用属性值的时候写*{属性值} ${…}得对象名。属性名这么写

#{} 获取国际化内容 或者获取thymeleaf内置对象

@{} 定义url链接 写在a标签一般

3.spring MVC自动配置

1自动配置了springmvc的视图解析器

​ -ContentNegotiatingViewResolver 组合所有视图解析器 通过它 我们写一个视图解析器 这个类就会自动 组合 进去 这就达到了定制视图解析器的效果

2静态资源文件夹路径

3首页

4Convert 转换器 作用是 将提交的int类型转换成Integer 把true转换成boolean类型 等等

5formatter 格式化器 2017-2-2装成date类型

6HttpMessageConvert 将User----json

定制所有自动配置的东西 只需要注册到容器 springboot在检查所有组件的时候 如果有用户写的就会使用用户写的

4.定制

package com.example.demo01.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
//不想用springboot自动配置好的 想自己定制 就要把这个类注册到容器 并继承WebMvcConfigurationSupport
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    //WebMvcConfigurationSupport类下全是自动配置好的 要定制哪一个就重写哪一个方法
    @Override
    //比如重写视图转发
    public void addViewControllers(ViewControllerRegistry registry) {
        //浏览器发送aaaa请求 跳转到success页面
        registry.addViewController("/aaaa").setViewName("success");
    }
}

定制的配置 会覆盖springboot的自动配置 但是 没有覆盖的还会生效 如果加了@EnableWebMvc 相当于全面接管springboot 所有自动配置不生效 回到ssm最原始的地方 所有配置都自己配

五CRUD案例

1.导入文件

在把资源导入之后会遇到几个问题

1 访问8080地址 无法跳转到首页 解决:不屑controller 我们自己接管写一个类 哪些个请求跳转到哪个页面

package com.lijiawei.demo.MyConfig;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MyConifg implements WebMvcConfigurer {
    @Override
    //比如重写视图转发
    public void addViewControllers(ViewControllerRegistry registry) {
        //浏览器发送aaaa请求 跳转到success页面
        registry.addViewController("/index.html").setViewName("index");
        registry.addViewController("/").setViewName("index");
    }
}

2发现还是无法打开网页 是因为没有导入thymeleafjar包

2 打开主页 无css样式 是因为没访问到静态资源 在主页 获取地址用 @{}把html引用的css连接引用过来 用thymeleaf语法 就要导入名称空间

在这里插入图片描述

3如果还是没有样式 可能是模板引擎缓存的问题 在配置文件中关闭缓存 在springboot2.2.4 之后不用关这个

spring.thymeleaf.cache=false

4首页没有图片还是 用thymeleaf 语法 把图片链接 引用即可 到此 主页显示正常 其他页面同理全部thymeleaf

2.国际化

注意 国际化之前 把propertier的编码设置成utf-8

1)、创建文件

在这里插入图片描述

login.btn=登录
login.password=密码
login.remember=记住我
login.tip=请登录
login.username=用户名

2)、引入文件

在全局配置文件 配置 国际化文件 文件名去掉 语言和国家代码

spring.messages.basename=i18n.login

3)、写入文件

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
		<meta name="description" content="">
		<meta name="author" content="">
		<title>Signin Template for Bootstrap</title>
		<!-- Bootstrap core CSS -->
		<link th:href="@{css/bootstrap.min.css}" rel="stylesheet">
		<!-- Custom styles for this template -->
		<link th:href="@{/css/signin.css}" rel="stylesheet">
	</head>

	<body class="text-center">
		<form class="form-signin" action="dashboard.html">
			<img class="mb-4" th:src="@{/img/bootstrap-solid.svg}" alt="" width="72" height="72">
			<h1 class="h3 mb-3 font-weight-normal"th:text="#{login.tip}">Please sign in</h1>
			<label class="sr-only">Username</label>
			<input type="text" class="form-control" th:placeholder="#{login.username}" required="" autofocus="">
			<label class="sr-only" >Password</label>
			<input type="password" class="form-control" th:placeholder="#{login.password}" required="">
			<div class="checkbox mb-3">
				<label>
          <input type="checkbox" value="remember-me" > [[#{login.remember}]]
        </label>
			</div>
			<button class="btn btn-lg btn-primary btn-block" type="submit" th:text="#{login.btn}">Sign in</button>
			<p class="mt-5 mb-3 text-muted">© 2017-2018</p>
			<a class="btn btn-sm">中文</a>
			<a class="btn btn-sm">English</a>
		</form>

	</body>

</html>

4)、点击按钮实现国际化

国际化原理 springboot有个类 LocaleResolver (获取区域信息对象) 该类默认会根据请求头获取区域信息

我们自己写一个LocaleResolver 改变他的默认行为

在html页面给 按钮添加一些信息

<a class="btn btn-sm" th:href="@{/index.html(l=zh_CN)}">中文</a>
<a class="btn btn-sm" th:href="@{/index.html(l=en_US)}">English</a>

重写国际化方法

package com.lijiawei.demo.compoment;

import org.springframework.util.StringUtils;
import org.springframework.web.servlet.LocaleResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;
//重写 必须实现LocaleResolver接口
public class MyLocaleResolver implements LocaleResolver {
    //重写解析区域信息的方法
    @Override
    public Locale resolveLocale(HttpServletRequest httpServletRequest) {
        //获取按钮带来的参数
        String s = httpServletRequest.getParameter("l");
        //如果有参数 返回新的Locale 如果没有参数 返回人家自己的 以免空指针
        Locale locale =Locale.getDefault();
        //判断参数是否为空
        if(!StringUtils.isEmpty(s)){
            //传过来的参数以下划线分割 语言代码和国家代码 我们分别保存
            String [] split = s.split("_");
            locale = new Locale(split[0],split[1]);
        }
        return locale;
    }
}

将重写的类注册到组件中 使用@bean 必须在配置类

  @Bean
    public LocaleResolver localeResolver(){
        return new MyLocaleResolver();
    }

3.登录

接下来做登录 登录成功跳转 使用servlet拦截

登录页面 提交数据 在表单action 写一个servlet 在去controller判断请求带来的数据 做出跳转行为

1)、注意

如果登陆失败 重新加载页面时 样式会改变 因为在html中样式没有加绝对路径/

在servlet设置了一个值 如果登陆失败 就显示内容 否则不显示

 <p style="color: red" th:text="${log_status}" th:if="${not #strings.isEmpty(log_status)}" ></p>
2)、注意

登录成功之后 如果在刷新页面会出现405错误 是因为登陆的时候 表单时post方式提交的 ,登录之后如果再刷新页面就是以get方式重复提交了表单 为防止表单重复提交 我们使用重定向的方式跳转到成功页面

4.拦截

如果直接访问 主页面 会跳过登录页面 所以做一个拦截器进行登陆检查

我们写一个拦截器

package com.lijiawei.demo.compoment;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LoginHandlerinterceptor implements HandlerInterceptor {
    @Override
    //目标方法执行之前
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Object o =request.getSession().getAttribute("LoginUser");
        if(o==null){
            //说明未登录 未登录就要跳转到主页面
            request.setAttribute("message","请先登录");
            request.getRequestDispatcher("/index.html").forward(request,response);
            return false;
        }else {
            //以登录 直接放行
            return true;
        }

    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

在配置类重写拦截器

@Override
public void addInterceptors(InterceptorRegistry registry){
    //制定拦截那个请求 写的是拦截任意请求  在排除首页 和登陆请求 和样式 要不然就废了
registry.addInterceptor(new LoginHandlerinterceptor()).addPathPatterns("/**")
.excludePathPatterns("/index.html","/user/login","/static");
}

5.Restful风格crud员工列表

要是用restful必须手动开启 自动配置

spring.mvc.hiddenmethod.filter.enabled=true
普通url地址restful风格url地址
查询getEmpemp -----GET
添加getEmp?XXXXXXemp ------POST
修改updataEmp?id=XXXemp/id- ------PUT
删除deleteemp/id --------DELETE

1 thymeleaf抽取公共片段

我们要将顶部导航和 左侧导航抽取

<div th:fragment="片段名"></div

2引用 将标签 和内容全部替换:

引用有三种方式

replace 将要引用的标签和内容全部替换 并删除当前自己的变迁

insert 将要引入的内容和标签加入到当前标签下

include 将要引用的内容包含进来 除去标签

<div th:replace"~{模板名::片段名}"></div>

1 上面写了抽取公共页面片段 我们继续优化 把 每个页面的公共部分抽取到另一个页面 在引入即可

显示员工列表 在list页面

  <tbody>
   <tr th:each="emp:${emps}">
      <td th:text="${emp.id}"></td>
      <td th:text="${emp.last_name}"></td>
      <td th:text="${emp.email}"></td>
      //使用内置对象 将事件贬称
      <td th:text="${#dates.format(emp.brithday)}"></td>
      <td th:text="${emp.department.departmentName}"></td>
  </tr>
</tbody>

员工添加

在这里插入图片描述

日期列 值支持2019/5/5 以/分割的 传- . 什么的都错

在配置文件自己定义格式

spring.mvc.date-format=yyyy-MM-dd HH:mm

6错误处理机制

1)springboot默认错误处理机制

​ 1访问一个不存在的也面时 返回一个默认错误页面
在这里插入图片描述

1)、原理:

可以参照rMvcAutoConfiguration类 错误处理的自动配置

给容器中添加了以下组件

1DefaultErrorAttributes

这个类帮我们在页面共享信息

2ErrorPageCustomizer

@Value("{error.path:/error}")
private String path = 'error'; 系统出现错误以后来到error请求 进行处理

3BasicErrorController

一旦系统出现4XX 5XX ErrorPageCustomizer就会生效 他会定制错误的响应规则 来到/error请求 BasicErrorController 处理该请求 根据浏览器头部信息 又俩个处理方式 一个返回错误页面一个 返回josn数据

在这里插入图片描述
4 DefaultErrorViewResolver

错误之后这个类决定的那个去那个页面

在这里插入图片描述

2)、定制错误响应页面

1)在有模板引擎的情况下 :error/状态码 会自动寻找到这里
在这里插入图片描述

错误的状态码非常多 每个状态吗写一个页面很麻烦 那么如何做呢?

DefaultErrorViewResolver 类定义了 4xx 和5xx 以4或5开头的错误 会进入4xx.html或5xx.html 我们直接写一个文件4xx.html 这样只要是4开头的错误状态吗都会来到这个页面

在这里插入图片描述

如果精确到就是404错误 就会去404.html 如果是其他4开头的就去4xx.html 比如生日类型提交了个asd 就会4xx

如何拿到具体的错误信息呢?

DefaultErrorAttributes 这个类记录着错误信息

​ 1 timestamp 时间戳

​ 2 status 状态码

​ 3 error 错误提示

​ 4exception 异常对象

​ 5message 异常消息

​ 5erros JSR0303校验的错误

有了这些数据 我们在在4xx页面中 拿到具体内容
在这里插入图片描述

在这里插入图片描述

2) 没有模板引擎 也可以放在静态在原文件夹下

3)上面提到了 处理错误页面you俩个方式

当客户端访问网站出现错误的时候 返回的不是 错误页面 而是JSON 格式的错误信息
在这里插入图片描述

六 嵌入式servlet容器

springboot默认使用tomcat 作为嵌入式的servlet容器

在这里插入图片描述

1.如何定制和修改tomcat

​ 1)修改server有关的配置 比如端口号 去properties文件设置

#通用的设置
server.XXX=XXX
#修改tomcat的设置
server.tomcat.XXX=XXX

​ 2) 编写一个类修改配置

  @Bean
    public WebServerFactoryCustomizer<ConfigurableWebServerFactory> MyServletConfig () {
        WebServerFactoryCustomizer<ConfigurableWebServerFactory> c =(a)->a.setPort(8011);
        return c;
    }

2.如何注册servlet三大组件【Servlet,Filter,Lisenter】

由于springboot默认以jar包方式启动嵌入式的servlet容器来启东springboot的web应用 没有web.xml 文件

ServletRegistrationBean

1)、注册servlet

package com.lijiawei.demo.servlet;

import org.springframework.context.annotation.Configuration;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Configuration
public class MyServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        resp.getWriter().write("你好");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
    }
}

加入容器

  //注册一个自己的servlet 指定拦截的请求
    @Bean
    public ServletRegistrationBean myservlet(){
        return new ServletRegistrationBean(new MyServlet(),"/hello");
    }

2)、注册Filter

自己写的拦截器必须继承Filter

@Bean
public FilterRegistrationBean myfilter(){
	FilterRegistrationBean filterRegistrationBean  new FilterRegistrationBean();
    //注册自己的拦截器
	filterRegistrationBean.setFilter(new MyFilter);
    //设置拦截多个请求
	filterRegistrationBean.set设置拦截多个请求UrlPatterns(Arrays.asList("hello","world")) ;
    return filterRegistrationBean;
}

3)、注册Filter

自己写的监听器 实现 ServletContextListener

@Bean
public ServletListenerRegistroationBean myfilter(){
//构造器 直接初测自己的监听器
	ServletListenerRegistroationBean servletListenerRegistroationBean = new ServletListenerRegistroationBean(new MyListener);
    return servletListenerRegistroationBean;
}

七 Docker

1、简介

Docker是一个开源的应用容器引擎

Docker支持将软件编异成一个镜像:然后在镜像中配置好软件,将镜像发布出去,其他使用者可以直接使用这个镜像

运行中的这个镜像成为容器 容器启动非常快速的

2、核心概念

docker主机:安装了docker的程序就叫docker主机(docker直接安装在操作系统上)

docker客户端:连接docker进行操作

docker仓库:保存打包好的软件镜像

docker容器:镜像启动后的实例成为容器

使用docker步骤

1)、安装docker

2)、去docker仓库找到这个软件的镜像

3)、使用docker运行这个镜像,这个镜像就会产生一个docker容器

4)、对容器的停止就是对这个软件的停止

3、安装centos7

阿里云镜像地址:http://mirrors.aliyun.com/centos/7/isos/x86_64/CentOS-7-x86_64-DVD-1908.iso

选择 CentOS-7-x86_64-DVD-1908.iso 这个版本下载

1)、网络配置

5、安装docker

Linux 安装Docker 需要内核3.10版本以上(centos就是3.10以上)

查看当前内核版本 uname -r

升级内核 yum update

安装docker yum install docker

启动docker systemctl start docker

开机自启动docker systemctl enable docker

关闭docker: systemctl stop docker

6、常见操作

1)、镜像操作

搜索 :仓库的mysql docker search mysql(名字)

下载 :docker pull mysql(名字) 默认下载最新版本

​ docker pull mysql:版本号 (下载指定版本)

查看下载的镜像:docker images

删除指定镜像:docker rmi id(查看下载的镜像的时候有id信息)

2)、容器操作

软件镜像(qq的安装程序)运行镜像----产生一个容器(运行的qq)

镜像启动运行:docker run --name mytomcat -d tomcat

在这里插入图片描述

查看正在运行的容器 :docker ps

停止正在运行的容器:docker stop ID(名字也行)

查看运行和退出的所有容器:docker ps -a

容器启动 docker start 容器id

删除容器 docker rm 容器id

3)、端口映射

当运行tomcat的时候 在window下访问8080是失败的 因为没有做端口映射

在启动容器的时候要端口映射 docker run -d p 8888:8080 tomcat

-d代表后台运行

-p主机端口映射到容器端口 在window下访问8888即可访问到容器的8080端口

7、启动mysql

上面说过这么启动 docker run --name mytomcat -d mysql 但是如果这么启动mysql就会启动失败

因为没有指定mysql密码 正确命令

docker run --name mysql01 -e MYSQL_ROOT_PASSWORD=123456 -d mysql

你以为这就可以访问了么? 错 没有做端口映射 weindow无法访问 所以还要写端口映射

docker run -p 3306:3306 --name mysql01 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.5

使用mysql5.5 新版的会出错 最后使用navcat链接

在这里插入图片描述

八 数据访问

1.原生jdbc

1)、JDBC

1)springboot访问数据源

spring:
 datasource:
  username: root
  password: 123456
  url: jdbc:mysql://192.168.75.129/test?serverTimezone=UTC
  driver-class-name: com.mysql.jdbc.Driver
  1. 测试
package com.lijiawei.demo1;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

@SpringBootTest
class Demo1ApplicationTests {
    @Autowired
    DataSource dataSource;
    @Test
    void contextLoads() throws SQLException {
        System.out.println(dataSource.getClass());
        Connection connection = dataSource.getConnection();
        System.out.println(connection);
        connection.close();

    }

}

输出

class com.zaxxer.hikari.HikariDataSource

HikariProxyConnection@1294058862 wrapping com.mysql.cj.jdbc.ConnectionImpl@726aa968

可能会出现时区错误 在url后加 serverTimezone=UTC

默认以class com.zaxxer.hikari.HikariDataSource 作为数据源

2)、操作数据库

springboot自动配置了jdbctamplate操作数据库

package com.lijiawei.demo1.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class JDBCController {
    @Autowired
    JdbcTemplate jdbcTemplate;
    @RequestMapping("/hello")
    @ResponseBody
    public  String  method(){
        String sql = "create table student(id int(10))";
        jdbcTemplate.execute(sql);
        return "success";
    }
}

上面代码的@Autowired将yam文件属性自动注入 JdbcTemplate 这个类直接操作数据库

2.整合Druid数据源

1)、介绍

druid和HikariDataSource 数据源是现在最快的俩个数据源 druid是阿里巴巴旗下开源项目 druid有强大的监控功能 记录了执行过那些sql操作 效果 和 时间等各种详细信息

2)、使用

导包

 <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.12</version>
        </dependency>

创建druid配置类

package com.lijiawei.demo1.Config;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.util.HashMap;

@Configuration
public class DruidConfig {
    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean
    public DataSource druidDataSource(){
        return new DruidDataSource();
    }
    @Bean
    //后台监控
    public ServletRegistrationBean statViewServlet(){
        ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
    //后台有人登陆 设置一个账号密码
        HashMap<String,String> initParameters =new HashMap<>();
        initParameters.put("loginUsername","admin");//key不能写别的
        initParameters.put("loginPassword","123456");//key不能写别的
        //允许谁可以访问 空代表任何人  也可以写具体的
        initParameters.put("allow","");
        bean.setInitParameters(initParameters);
        return bean;

    }
}

覆盖springboot默认的数据源 并赋值

spring:
 datasource:
  username: root
  password: 123456
  url: jdbc:mysql://192.168.75.129/test?serverTimezone=UTC
  driver-class-name: com.mysql.jdbc.Driver
  #引入druid数据源 覆盖掉默认的HikariDataSource 数据源
  type: com.alibaba.druid.pool.DruidDataSource
  #配置druid数据源
  initialSize: 5
  minIdle: 5
  maxActive: 20
  maxWait: 6000
  timeBetweenEvictionRunsMillis: 30000

  #配置监控统计拦截的filters stat :监控统计 log4j :日志记录 wall:防御sql注入
  filters: stat,wall,log4j
  maxPoolpreparedStatmentPerConnectionSize: 20
  useGlobalDataSourceStat: true
  connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500

全部完成之后 配置 直接访问 http://localhost:8080/druid 会跳出登录界面 登陆之后

在这里插入图片描述

3.整合mybatis

导包

<dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
           <version>2.1.2</version>
</dependency>

pojo层和 mapper接口

package com.example.demo.mapper;

import com.example.demo.pojo.Book;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

import java.util.List;

//这个注解表示这是一个mybatis的mapper类
@Mapper
//相当于@compoment 万能组件  @Repository 具体一点而已
@Repository
public interface BookMapper {
 public List<Book> querybooks() ;

}

mapper

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybayis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace 绑定一个Dao/Mapper接口 相当于实现该接口-->
<mapper namespace="com.example.demo.mapper.BookMapper">
    <select id="querybooks" resultType="Book">
        select * from book
    </select>

</mapper>

properties

spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

#整合mybatis

#给这个包下的类起别名 类名小写
mybatis.type-aliases-package=com.example.demo.pojo
#mapper注册
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml

controller

package com.example.demo.Controller;

import com.example.demo.mapper.BookMapper;
import com.example.demo.pojo.Book;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

@Controller
public class myconfig {
    @Autowired
    BookMapper bookMapper;
    @GetMapping("/hello")
    @ResponseBody
    public List<Book> query(){
        List<Book> list =bookMapper.querybooks();
        return list;
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值