SpringBoot
2021-04-22 11:33:54 20 举报
AI智能生成
SpringBoot入门使用,整合mybatis,thymeleaf,扩展定时任务,异步任务,邮件发送,短信发送
作者其他创作
大纲/内容
第一个springbooot项目
新建一个springboot项目
完善项目结构
强迫症不喜欢多余的文件,该删删,删成这样就行了
一个标准的web应用目录结构
小彩蛋
启动项目控制台的输出是这样的
resource目录下新建banner.txt,输入你想要的效果
编写测试controller
package com.xiaoye.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* @author 小也
* @create 2021/4/11 19:03
*/
@Controller
@RequestMapping("/hello")
public class HelloWorldController {
@ResponseBody
@RequestMapping("/h1")
public String hello(){
return "Hello,World";
}
}
还有一个规范点:springboot的配置文件官方建议使用yaml,而不是properties
yaml的语法:以空格区分层次关系
key:(空格)value
yaml的强大之处在于可以给实体类赋值
定义实体类
package com.xiaoye.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @author 小也
* @create 2021/4/12 8:33
*/
@Data //这是lombok插件,偷懒神器,不用手写get/set方法了
@AllArgsConstructor //全参构造注解
@NoArgsConstructor //无参构造注解
@Component //把该实体类作为组件交给IOC容器
@ConfigurationProperties(prefix = "user") //这是把该实体类属性与yaml配置文件中的值对应绑定
public class User {
private String name;
private int age;
private String sex;
}
这里会爆红,pom.xml引入一个依赖就可以解决了,不引入也不影响运行
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
编写yaml
user:
name: xiaoye
age: 20
sex: 男
⭐yaml对空格要求极为严格
启动项目,请求接口,看看是否成功输出HelloWorld
初探原理
maven项目我们当然要先看pom.xml文件
我们发现这个项目依赖父项目
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
再往上还有一个父项目
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath>../../spring-boot-dependencies</relativePath>
</parent>
这里才是springboot的控制中心,所有的依赖版本都在这里了
启动器:spring-boot-starter
springboot-boot-starter-xxx:就是spring-boot的场景启动器
spring-boot-starter-web:帮我们导入了web模块正常运行所依赖的组件;
springboot把所有的功能场景抽离出来形成一个个starter(启动器)
只需要引入需要的starter,springboot就会帮我们引入相关的依赖
我们再来看主启动类
//@SpringBootApplication 来标注一个主程序类,说明这是一个SpringBoot应用
@SpringBootApplication
public class SpringbootApplication {
public static void main(String[] args) {
//这里并不是启动一个方法而已,他其实启动了一个服务
SpringApplication.run(SpringbootApplication.class, args);
}
}
我们分析一下这个主程序启动类中唯一的注解:@SpringBootApplication
追进这个注解发现这里面还有很多别的注解,我们找几个重要的看
@SpringBootConfiguration
SpringBoot的配置类 ,标注在某个类上 , 表示这是一个SpringBoot的配置类;
继续追进去
@Configuration说明这是一个配置类
@EnableAutoConfiguration
springboot开启自动配置功能
继续追进去
@AutoConfigurationPackage:自动配置包
继续追进去
@Import({Registrar.class}):这是把主程序所在包及其子包的所有bean加载到spring容器中
@Import({AutoConfigurationImportSelector.class}):给容器导入组件
AutoConfigurationImportSelector :自动配置导入选择器
追进去会发现几个重要的方法
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(
this.getSpringFactoriesLoaderFactoryClass(),
this.getBeanClassLoader() );
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories.
If you are using a custom packaging, make sure that file is correct.");
//返回的就是我们最先看到的启动自动导入配置文件的注解类:@EnableAutoConfiguration
return configurations;
}
这里调用了SpringFactoriesLoader类的静态方法loadFactoryNames
public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
ClassLoader classLoaderToUse = classLoader;
if (classLoader == null) {
classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
}
String factoryTypeName = factoryType.getName();
//这里调用该类的loadSpringFactories方法
return (List)loadSpringFactories(classLoaderToUse).getOrDefault(factoryTypeName, Collections.emptyList());
}
private static Map<String, List<String>> loadSpringFactories(ClassLoader classLoader) {
//获取classloader
Map<String, List<String>> result = (Map)cache.get(classLoader);
if (result != null) {
return result;
} else {
HashMap result = new HashMap();
try {
//这里获取一个资源:"/META-INF/spring-factories"
Enumeration urls = classLoader.getResources("META-INF/spring.factories");
//遍历得到的资源,封装成Properties
while(urls.hasMoreElements()) {
URL url = (URL)urls.nextElement();
UrlResource resource = new UrlResource(url);
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
Iterator var6 = properties.entrySet().iterator();
while(var6.hasNext()) {
Entry<?, ?> entry = (Entry)var6.next();
String factoryTypeName = ((String)entry.getKey()).trim();
String[] factoryImplementationNames = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
String[] var10 = factoryImplementationNames;
int var11 = factoryImplementationNames.length;
for(int var12 = 0; var12 < var11; ++var12) {
String factoryImplementationName = var10[var12];
((List)result.computeIfAbsent(factoryTypeName, (key) -> {
return new ArrayList();
})).add(factoryImplementationName.trim());
}
}
}
result.replaceAll((factoryType, implementations) -> {
return (List)implementations.stream().distinct().collect(
Collectors.collectingAndThen(Collectors.toList(),
Collections::unmodifiableList));
});
cache.put(classLoader, result);
return result;
} catch (IOException var14) {
throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var14);
}
}
}
我们再来看一下这个spring.factories
这里面都是一个个的自动配置文件,里面找个认识的追进去会发现是java配置类
所以springboot的自动装配是从classpath中搜寻所有的META-INF/spring.factories配置文件,通过反射获取实例注入到IOC容器中的
得到结论
springboot启动时从类路径/META-INF/spring.properties中读取EnableAutoConfiguration指定的值
把这些值的自动装配类导入容器,自动装配类就生效了
整个javaee的整体解决方案和自动装配都在springboot-autoconfiguration的jar包中
有了自动装配类,就免去了我们手动配置、注入功能组件的操作
纵向观察
yaml
yaml配置类中可以设置的属性值都是XXXAutoConfiguration自动类中的属性
XXXAutoConfiguration自动类
这些都是java配置类,如果yaml中没有配置属性,就从XXXPeoteries文件中读取默认值
XXXPeoteries
这里存放的都是Java配置类中的默认属性值
@ComponentScan
自动扫描并加载符合条件的组件或者bean , 将这个bean定义加载到IOC容器中
最后看下SpringApplication.run()
这个类主要做了以下四件事情
推断应用的类型是普通的项目还是Web项目
查找并加载所有可用初始化器 , 设置到initializers属性中
找出所有的应用程序监听器,设置到listeners属性中
推断并设置main方法的定义类,找到运行的主类
查看类构造器
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.sources = new LinkedHashSet();
this.bannerMode = Mode.CONSOLE;
this.logStartupInfo = true;
this.addCommandLineProperties = true;
this.addConversionService = true;
this.headless = true;
this.registerShutdownHook = true;
this.additionalProfiles = Collections.emptySet();
this.isCustomEnvironment = false;
this.lazyInitialization = false;
this.applicationContextFactory = ApplicationContextFactory.DEFAULT;
this.applicationStartup = ApplicationStartup.DEFAULT;
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
this.webApplicationType = WebApplicationType.deduceFromClasspath();
this.bootstrappers = new ArrayList(this.getSpringFactoriesInstances(Bootstrapper.class));
this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = this.deduceMainApplicationClass();
}
web开发:网站开发走起
首先创建一个项目,不必多说
然后我们解决一下静态资源导出问题
webjars(这个只是简单说一下,我们使用下面那种方式)
通过导入maven的方式
映射到localhost:8080/webjars/
public / static / resources
映射到localhost:8080/
优先级
resources > static(默认) > public
⭐扩展装配springmvc
新建MyMvcConfig实现WebMvcConfigurer接口
⭐添加@Configuration注解
⭐一定不要添加@EnableWebMvc
这个注解会使自动装配失效
原理
观察WebMvcAutoConfiguration自动装配类
而我们再看看这个@EnableWebMvc注解
它实际上是导入了DegatingWebMvcConfiguration类,我们追进去
直接发现这个东西继承了WebMvcConfigurationSupport
简单设计一下首页
创建首页index,放在静态资源目录下(templates )
引入thymeleft模板引擎
导入依赖
<!--模板引擎,基于3.x开发-->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf.spring5</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-java8time</artifactId>
</dependency>
引入头文件
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1 th:text="${msg}"></h1>
</body>
</html>
templates里的html页面都需要通过controller返回
⭐但是首页根资源我们使用springmvc配置映射
配置首页映射(重写addViewControllers方法)
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
}
}
只要路径地址是/,就会映射到index
首页找个bootstrap的模板吧,记得下载css
网址:https://getbootstrap.com/docs/4.0/examples/
网址:https://getbootstrap.com/docs/4.0/examples/
<!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>NaN~NaN</title>
<link th:href="@{/css/bootstrap.min.css}" rel="stylesheet">
<link th:href="@{/css/signin.css}" rel="stylesheet">
</head>
<body class="text-center">
<form class="form-signin">
<h1 class="h3 mb-3 font-weight-normal">Please sign in</h1>
<label for="inputEmail" class="sr-only">Email address</label>
<input type="email" id="inputEmail" class="form-control" placeholder="Email address" required="" autofocus="">
<label for="inputPassword" class="sr-only">Password</label>
<input type="password" id="inputPassword" class="form-control" placeholder="Password" required="">
<div class="checkbox mb-3">
<label>
<input type="checkbox" value="remember-me"> Remember me
</label>
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
<div class="mt-3">
<a th:href="@{/}" th:text="中文"/>
<a th:href="@{/}" th:text="English"/>
</div>
<p class="mt-3 mb-3 text-muted">© 2017-2018</p>
</form>
</body>
</html>
整个国际化,显得高大上
首先保证我们开发环境是基于UTF-8的
建立资源目录---i18n(Internationalization的简写,还有个相同的k8s)
创建配置文件
zh_CN中文,en_US英文
采用可视化配置
首先打开可视化配置界面
开始配置
配置application.yaml
spring.message.basename: i18n.login
使用#{ }在html页面取值
button元素和其他的不同
配置自己的地区化解析器
新建MyLocaleResolver类实现LocaleResolver接口
package com.admin.config;
import org.springframework.web.servlet.LocaleResolver;
import org.thymeleaf.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;
/**
* @author 小也
* @create 2021/4/14 8:46
*/
public class MyLocaleResolver implements LocaleResolver {
@Override
public Locale resolveLocale(HttpServletRequest httpServletRequest) {
//获取请求携带的地区参数
String language = httpServletRequest.getParameter("language");
//声明一个默认的locale
Locale locale = Locale.getDefault();
//如果请求携带的地区值不为空就返回自定义的locale
if(!StringUtils.isEmpty(language)){
String[] split = language.split("_");
locale = new Locale(split[0], split[1]);
}
return locale;
}
@Override
public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {
}
}
把自定义的地区化解析器配置到springmvc中,通过构造函数实现自动装配
package com.admin.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @author 小也
* @create 2021/4/13 19:44
* 扩展 springmvc
*/
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
}
@Bean
public LocaleResolver localeResolver(){
return new MyLocaleResolver();
}
}
html页面的切换按钮,携带参数跳转
<div>
<a th:href="@{/index.html(language='zh_CN')}" th:text="中文" class="mr-3"/>
<a th:href="@{/index.html(language='en_US')}" th:text="English" class="ml-3"/>
</div>
实现登录功能
html页面表单提交地址
<form class="form-signin" th:action="@{/login/toHome}">
controller控制是否登录成功,新建controller
package com.admin.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* @author 小也
* @create 2021/4/14 9:07
*/
@Controller
@RequestMapping("/login")
public class LoginController {
@RequestMapping("/toHome")
public String toHome(@RequestParam("username")String username,
@RequestParam("password")String password,
Model model){
//这里应该是查数据库的操作,但是我们先构建出项目框架模板再加入数据库,所以这里写固定值
if(username.equals("asd") && password.equals("asd")){
model.addAttribute("username",username);
//转发重定向,防止表单重复提交
return "redirect:/home.html";
}else{
//登陆失败返回登录页,并且提示账户名或者密码错误
model.addAttribute("msg","用户名或密码错误");
return "index";
}
}
}
重定向的视图映射
package com.admin.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @author 小也
* @create 2021/4/13 19:44
* 扩展 springmvc
*/
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
registry.addViewController("/home.html").setViewName("home");
}
@Bean
public LocaleResolver localeResolver(){
return new MyLocaleResolver();
}
}
重定向到主页面后,我们发现不需要账户名和密码,直接url栏访问主页面也可以,所以我们配置拦截器
首先创建LoginHandlerInterceptor类实现HandlerInterceptor接口,实现pre方法
package com.admin.config;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author 小也
* @create 2021/4/14 12:29
* 继承拦截器接口,进入页面前拦截
*/
public class LoginHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//查看session是否有值,有就放行,没有就拦截
Object username = request.getSession().getAttribute("username");
if(username == null){
//添加提示信息
request.setAttribute("msg","您没有访问权限,请先登录...");
//转发到登录首页
request.getRequestDispatcher("index.html").forward(request,response);
return false;
}else{
//查询到值,放行
return true;
}
}
}
然后通过springmvc扩展类装配
package com.admin.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @author 小也
* @create 2021/4/13 19:44
* 扩展 springmvc
*/
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
registry.addViewController("/home.html").setViewName("home");
}
@Bean
public LocaleResolver localeResolver(){
return new MyLocaleResolver();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
//配置资源拦截
//addPathPatterns("/**")==》拦截所有请求
//excludePathPatterns("/","/css/**","/img/**","/js/**","/index.html","/login/toHome")不拦截这些请求
registry.addInterceptor(new LoginHandlerInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/","/css/**","/img/**","/js/**","/index.html","/login/toHome");
}
}
实现注销功能
登录后我们在登录的controller里添加一个注销方法,很简单,就是单纯的去除session
package com.admin.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import javax.servlet.http.HttpSession;
/**
* @author 小也
* @create 2021/4/14 9:07
*/
@Controller
@RequestMapping("/login")
public class LoginController {
@RequestMapping("/toHome")
public String toHome(@RequestParam("username")String username,
@RequestParam("password")String password,
Model model,HttpSession session){
//这里应该是查数据库的操作,但是我们先构建出项目框架模板再加入数据库,所以这里写固定值
if(username.equals("asd") && password.equals("asd")){
//登录信息加载到session中
session.setAttribute("username",username);
//转发重定向,防止表单重复提交
return "redirect:/home.html";
}else{
model.addAttribute("msg","用户名或密码错误");
return "index";
}
}
@RequestMapping("/signOut")
public String toHome(HttpSession session){
session.setAttribute("username",null);
return "index";
}
}
抽离出页面多次使用的代码形成组件,实现代码复用(使用th:freagment和th:replace)
抽离代码形成组件
实现复用
组件间通信
错误页面,直接在templates目录下建一个error文件夹,里面新建404、500等错误页面,springboot会帮我们自动找到这些页面
然后CRUD就不必多说了吧,我们现在有大概模板了,上数据库
pom导入druid依赖(因为druid集成了后台监控,我们试试这个东西)
application.yaml进行配置
spring:
datasource:
username: root
password: root
url: jdbc:mysql://localhost:3306/sbs?useSSL=false&useUnicode=true&characterEncoding=utf-8&setTimezone=CTT
driver-class-name: com.mysql.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
编写配置类
@Configuration声明配置类,@Bean交给Spring接管
package com.admin;
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;
/**
* @author 小也
* @create 2021/4/14 18:18
*/
@Configuration
public class DruidConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource druidDataSource(){
return new DruidDataSource();
}
@Bean
public ServletRegistrationBean statViewServlet(){
ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(),"/druid/*");
HashMap<String,String> hashMap = new HashMap<>();
//这是进入后台监控的账号密码,map的key一定不能写错
hashMap.put("loginUsername","root");
hashMap.put("loginPassword","root");
bean.setInitParameters(hashMap);
return bean;
}
}
配置成功就能进入这样的后台页面(别人写好的,我们直接使用就好)
整合mybatis
导入整合包依赖
<!--mybatis整合包-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
更改一下druid的版本,因为localdate的问题,遇到的一个坑,希望大家不要浪费时间在这
<!--druid数据源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.22</version>
</dependency>
配置springmvc.config(其实我知道这样是不标准的,因为明明yuml中有配置信息,为什么还手写呢?因为我拿不出来yuml的数据,。。。。。。。)
package com.admin.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.sql.DataSource;
/**
* @author 小也
* @create 2021/4/13 19:44
* 扩展 springmvc
*/
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Bean
public LocaleResolver localeResolver(){
return new MyLocaleResolver();
}
@Bean DataSource druidDataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl("jdbc:mysql://localhost:3306/sbs?useSSL=false&useUnicode=true&charaterEncoding=utf-8&serverTimezome=UTC");
dataSource.setUsername("root");
dataSource.setPassword("root");
return dataSource;
}
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
registry.addViewController("/home.html").setViewName("home");
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
//配置资源拦截
//addPathPatterns("/**")==》拦截所有请求
//excludePathPatterns("/","/css/**","/img/**","/js/**","/index.html","/login/toHome")不拦截这些请求
registry.addInterceptor(new LoginHandlerInterceptor())
.addPathPatterns("/**").excludePathPatterns("/","/css/**","/img/**","/js/**","/index.html","/login/toHome");
}
}
创建mapper,这个我们放在classpath:mybatis/mapper下
目录结构
mapper文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.admin.mapper.StudentMapper">
<!--这里这么配置,是因为数据库中的_连接符都需要变成驼峰写法-->
<resultMap id="studentOne" type="com.admin.pojo.Student">
<result column="major_id" property="majorId"/>
<result column="admission_date" property="admissionDate"/>
</resultMap>
<select id="getAllStudents" resultMap="studentOne">
select * from student
</select>
<select id="getStudentByUsername" resultMap="studentOne">
select * from student where username = #{username}
</select>
</mapper>
配置yuml的mybatis相关配置项(别名以及扫描包)
mybatis:
type-aliases-package: com.admin.pojo
mapper-locations: classpath:mybatis/mapper/*.xml
编写mapper的dao层接口
package com.admin.mapper;
import com.admin.pojo.Student;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* @author 小也
* @create 2021/4/14 20:28
*
* @Mapper 表明这是一个myabtis的mapperl类
* @Repository 把给类交给spring管理
*/
@Mapper
@Repository
public interface StudentMapper {
/**
* 查询所有学生
* @return List<Student>
*/
List<Student> getAllStudents();
/**
* 根据名字查找
* @param username
* @return Student
*/
Student getStudentByUsername(@Param("username")String username);
}
现在加上service接口和实现类,配合controller就可以快乐的CURD了
扩展功能
安全扩展(认证、授权)
⭐SpringSecurity
shiro
swagger接口文档
添加pom依赖
<!--swagger接口文档-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>
启动类添加@EnableSwagger2注解开启swagger
项目启动后,输入localhost:8080/swagger-ui.html就可以访问默认界面了
⭐这个功能在项目上线后必须关闭,它不仅会暴露接口造成风险,还会降低性能
异步任务(比如后台响应需要时间,但是前台等待会影响体验)
在需要异步处理的方法上加上@Async注解
在主启动类上添加@EnableAsync注解开启异步功能
邮件发送
导入依赖
<!--邮件发送-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
邮箱开启smtp,获得授权码
配置yml文件
spring:
mail:
username: 邮箱地址
password: 授权码
host: smtp.相关邮箱.com
properties:
mail:
smtp:
ssl:
enable: true
编写测试代码(需要用到JavaMailSenderImpl类,我们用spring的自动装配实现)
简单文本
直接发送SimpleMailMessage对象
直接发送SimpleMailMessage对象
代码
SimpleMailMessage message = new SimpleMailMessage();
message.setSubject("SimpleMailMessage");
message.setText("<h1 style='color:red'>SimpleMailMessage</h1>");
message.setFrom("自己的邮箱地址");
message.setTo("收件人邮箱地址");
mailSender.send(message);
注意点
简单邮件电脑端不支持html解析,想要支持html解析就使用MimeMessage
其实,手机是支持html标签解析的,但是建议不要使用了,毕竟官方建议需要html解析使用MimeMessage
带附件传送,可解析html
MimeMessage对象是邮件的基本内容,需要MimeMssageHelaper组装发送
MimeMessage对象是邮件的基本内容,需要MimeMssageHelaper组装发送
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message,true); //这个true是开启多附件传输
helper.setSubject("MimeMessage");
helper.setText("<h1 style='color:red'>这是MimeMessage的测试邮件主题</h1>",true);
helper.addAttachment("1.jpg", new File("C:\\Users\\22944\\Pictures\\联想锁屏壁纸\\1.jpg"));
helper.setFrom("自己的邮箱");
helper.setTo("收件人邮箱");
mailSender.send(message);
短信发送(我选择使用阿里云的服务【大鱼】)
登录阿里云大鱼平台,开通短信服务,新人有使用,可以领取测试
https://dayu.aliyun.com/
https://dayu.aliyun.com/
进入控制台,右上角头像悬浮鼠标,创建AccessKey
添加签名
定时任务
在需要异步处理的方法上加上@Schdule(cron = "秒 分 时 日 月 星期")注解
大家需要去了解一下cron表达式
在主启动类上添加@EnableSchdule注解开启异步功能
测试
package com.admin.utils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
/**
* @author 小也
* @create 2021/4/22 11:16
*/
@Component
public class MySchedule {
@Scheduled(cron = "0/2 * * * * *") //每两秒打印一次时间
public void now(){
System.out.println(LocalDateTime.now());
}
}
0 条评论
下一页