SpringBoot
一、初识boot
可以从Spring或者idea上面直接创建boot项目
@RestController//返回字符串
@RestController//返回字符串
public class hellocontroller {
@RequestMapping("/hello")
public String hello(){
return "hello,world";
}
}
在application中启动程序
1. pom xml分析
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>helloworld</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>helloworld</name>
<description>helloworld</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- 这个boot的依赖集成了tomcat dispatcherServlet xml -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!--测试用的有依赖-->
<!--有一个共同的前缀就是spring-boot-starter-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--这里有时候需要收到导入一下这个web依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<!--打包的依赖,打包成jar包-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2. 配置端口
server.port = 8081 //properties配置端口文件
3. 启动器
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
- 启动器:就是boot的启动场景
- 比如spring-boot-starter-web,他就会帮我们自动导入web环境的所有依赖
- springboot会将所有的场景功能,都变成一个个的启动器
- 我们要使用什么功能,就只要找到对应的启动器就行了
4. 自动配置
boot所有的自动配置都是启动的时候扫描并加载, spring,factories所有的自动配置都在这里面,但是不一定生效,要判断条件是否成立,只要导入了对应的start,就有对应的启动器了,有了启动器,我们的自动装配就会生效,然后就会配置成功
- springboot在启动的时候,从类路径下/META/spring.factorirs 获取指定的值;
- 将这些自动配置导入容器,自动配置就会生效,帮我进行自动配置
- 整合JavaEE,解决方案和自动配置的东西都在spring-boot-autoconfigure-2.2.0.RELEASE.jar这个包下.
- 它会把所有需要导入的组件,以类名的方式返回,这些组件就会被添加到容器
- 容器也会存在非常多的xxxAutoConfiguration 的文件, 就是这些类给容器中导入了这个场景需要的所有组件
二、一些简单的boot操作
1. yaml语句
一定要记住有空格!!! 空格很重要 代表了他们之间的层级关系
1) 基础语法
name: william
#对象
student:
name:william
age:3
# 行内写法
student {name:william,age:3}
# 数组
pets
- cat
- dog
- pig
pets: [cat,dog,pig]
可以同时存在两个配置文件,但是他们有优先级
2) yaml可以直接个实体类赋值
- 常规方法
@Componet 标记为spring的组件 spring才会扫描
@Value ("") 为属性添加值
@Autowired自动装配过来
- yaml方法
配置了上图的configurationProperties()
@ConfigurationProperties(prefix = "person");
//这里就将yaml里person和类绑定起来了,就可以给类进行赋值
再加上对应的名 和yaml中的一样就可以赋值成功了
2. ConfigurationProperties
- 自定义配置文件
也可以自定义自己的配置文件绑定一下就行了
@PropertySouce(value = "classpath:qinjiang.properties")
...类...
- 也可以使用el表达式
person:
name: qinjiang${random.uuid}
age: ${random,int} # 给属性赋随机值
happy: false
birth: 2021/10/13
maps: {k1: v1,k2: v2}
list:
- code
- music
- girl
dog:
name: ${person.hello:hello}_旺财
age: 3
或者dog.name 那里 使用该表达式,如果person里(就上面那个类)有person.hello 就赋值person.hello 的值,否则就赋值"hello"
4. 松散绑定
5. 配置文件相关
几个能配置appliction的位置
配置多个端口
server:
port: 8080
spring:
profiles:
active: dev #激活yaml中的端口 active
---
server:
port: 8081
spring:
profiles: dev
---
server:
port: 8082
spring:
profiles: test
三、web开发
1.导入静态资源
//导入静态资源的源码,了解
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
} else {
this.addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
this.addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
registration.addResourceLocations(this.resourceProperties.getStaticLocations());
if (this.servletContext != null) {
ServletContextResource resource = new ServletContextResource(this.servletContext, "/");
registration.addResourceLocations(new Resource[]{resource});
}
});
}
}
静态资源主要可以放在这三个资源目录下,就可以直接通过 8080/wenjian_name.html来访问
如果存在相同名字的文件, 他们之间存在一个优先级为
resources>static>public
2.定制首页
把index文件放到静态资源的那三个目录里面,注意一定要是index这个名字
如果不放在那三个目录下,要放在template下则需要添加模板引擎,然后添加一个controller跳转
使用模板引擎thymeleaf
在pom.xml中导入这个依赖
<!--thymeleaf-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
这样以后template里的html文件通过controller 的跳转就可以访问了
简单的controller和thymeleaf使用
3.mvc配置原理
/**
*自定义一个视图解析器,并设置对应的url跳转到哪个位置
*/
@Configuration
public class MyMvcconfig implements WebMvcConfigurer {//自定义视图解析器
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");//输入这两个 url时会跳转到 templates 下的 index
registry.addViewController("/index.html").setViewName("index");
registry.addViewController("/main.html").setViewName("dashboard");
}
}
4.使用Lombok
Lombok注解快速注解一个标准类
<!-- lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Department {
public Integer id;
public String departName;
}
只需要几行代码,就已经配置好了上面所示的结构
5.thymeleaf使用
<!--在使用的时候都需要导入命名空间, thymeleaf的语法才会生效-->
<html lang="en" xmlns:th="http://www.thymeleaf.org"> <!-- 命名空间 -->
<!-- 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">
<img class="mb-4" th:src="@{/img/bootstrap-solid.svg}" alt="" width="72" height="72">
注意导入命名空间和 @{ } 就是用来放链接的
本地的链接 都需要改+th:
只要是被thymeleaf接管就需要加上th:
给默认路径前面增加一个chen 的url
在配置文件(application)里面加上这段代码就行了
server.servlet.context-path=/chen
6.数据层的实现
/**
*
*员工数据层
*/
@Repository
public class EmployeeDao {
private static Map<Integer, Employee> employees = null;
@Autowired//这里从仓库中获取之后才可以使用,注意这里注入之后DepartmentDao就变成了紫色
private DepartmentDao DepartmentDao;
static {
employees = new HashMap<Integer, Employee>();
employees.put(1001,new Employee( 1001,"AA","2230035341@qq.com",0,new Department(101,"教学部")));
employees.put(1002,new Employee( 1002,"BB","6454564456@qq.com",1,new Department(102,"市场部")));
employees.put(1003,new Employee( 1003,"CC","2230044447@qq.com",0,new Department(103,"教研部")));
employees.put(1004,new Employee( 1004,"DD","2230454441@qq.com",1,new Department(104,"运营部")));
employees.put(1005,new Employee( 1005,"EE","8599855697@qq.com",0,new Department(105,"后勤部")));
}
//主键自增
private static Integer initId = 1006;
//增加一个员工
public void save (Employee employee){
if(employee.getId()==null){
employee.setId(initId++);
}
employee.setDepartment(DepartmentDao.getDepartmentById(employee.getDepartment().getId()));
employees.put(employee.getId(),employee);
}
//查询员工的信息
public Collection<Employee> getAll(){
return employees.values();//注意这里,map集合.value()的返回值是Collection集合
}
//通过id查询员工
public Employee getEmployeeById(Integer id){
return employees.get(id);// 通过key获取对应的value值
}
//删除员工
public void delete(Integer id){
employees.remove(id);
}
}
/*
*部门数据层
*/
@Repository
public class DepartmentDao {
private static Map<Integer, Department> departments = null;
static {
departments = new HashMap<Integer, Department>();
departments.put(101,new Department(101,"教学部"));
departments.put(102,new Department(102,"市场部"));
departments.put(103,new Department(103,"教研部"));
departments.put(104,new Department(104,"运营部"));
departments.put(105,new Department(105,"后勤部"));
}
//获得所有部门的信息
public Collection<Department> getDepartment(){
return departments.values();
}
public Department getDepartmentById(Integer id){
return departments.get(id);
}
}
map集合.value()的返回值是Collection集合,并且一定要在该类的上面写上 @Repository注解,告诉spring这是一个dao的数据的层,封装一个bean,方便调用
7.登录功能的实现
//登录的controller
@Controller
public class loginController {
@RequestMapping("/user/login")
public String login(@RequestParam("username") String username, @RequestParam("password") String password, Model model, HttpSession session){
if(!StringUtils.isEmpty(username)&&"123456".equals(password)){
session.setAttribute("loginuser",username);
return "redirect:/main.html";
}else{
model.addAttribute("msg","用户名或密码错误");
return "index";
}
}
@RequestMapping("/user/logout")
public String logout(HttpSession session){
session.invalidate();//注销session
return "redirect:index.html";
}
}
- 同样的道理,也需要在controller的类上加上@Controller注解,方法里面返回字符串,spring才会执行字符串里的内容,如果是@Restcontroller的话,就只会把它当作普通的字符串返回给前端
- @RequestParam简单的来讲就是把参数绑定在了url上
详情请见 https://blog.csdn.net/sswqzx/article/details/84195043?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163473054216780366541664%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=163473054216780366541664&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_positive~default-1-84195043.pc_search_es_clickV2&utm_term=%40RequestParam&spm=1018.2226.3001.4187
- 并且设置了一个session将用户的名字以 “loginuser” 的名字保存了下来
然后前端在接收一波就可以在dashboard的界面中获取到登录的信息了,这里的这种写法[[${…}]]等同于th:text:" ${ …}" - 最后重定向到"main.html"这个url,因为前面 自定义了一个视图解析器,"main.html"这个url会跳转到dashboard这个html文件中。这样会比较安全
- 如果登录错误就将一个msg的数据通过model回传到前端
前端在刚刚的表单中用thymeleaf接收输出一下,就可以提示错误信息了 - 退出登录就是将session注销就行了 session.invalidate();
8.拦截器的配置
这个时候可以登录了,发现一个问题,你直接输入mian的url照样可以进入登录的后的界面,这又问题啊,这里就需要用到我们的拦截器了。
public class LoginHanderInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Object loginuser = request.getSession().getAttribute("loginuser");
if(loginuser==null){
request.setAttribute("msg","没有权限,请您先登录!");//
request.getRequestDispatcher("/index.html").forward(request,response);//把这个请求专发到index页面
return false;//设置拦截
}else{
return true;//设置放行
}
}
}
- 写拦截器首先需要实现一下HandlerInterceptor
- 然后重写preHandle
- 这里采用的是获取刚刚登录时发送的session 数据,要数据匹配才能登录
- 然后设置一个request的请求,设置一段话
- 通过转发的方法将这句话返回到登录的界面
request.getRequestDispatcher("/index.html").forward(request,response);//把这个请求专发到index页面
登录失败的时候就会显示这段话提醒
6. 最后还有一步
// 添加刚刚配置的那个视图解析器
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginHanderInterceptor()).addPathPatterns("/**")
.excludePathPatterns("/index.html","/","/user/login","/css/*","/js/**","/img/**");
}
最后一步就是将刚刚写好的拦截器配置一下,到刚刚继承了configurer的类里面重写一个addInterceptors的方法,配置他的拦截路径,new一个刚刚写好的拦截器,这里的addPathPatterns就是添加拦截路径,excludePathPatterns就是放行的路径。
然后一个拦截器就配置好了
增删改查的实现
最重要的功能–增删改查
@Controller
public class EmployeeController {
@Autowired
EmployeeDao employeeDao;
@Autowired
DepartmentDao departmentDao;
@RequestMapping("/emps")
public String list(Model model){
Collection<Employee> employees = employeeDao.getAll();
//这里map.value返回的是Collection的集合
model.addAttribute("emps",employees);
//通过model将数据返回给前端,前端通过使用循环一下,展现出所有的数据
return "list";
}
@GetMapping("/add")
public String add(Model model) {
Collection<Department> departments = departmentDao.getDepartment();
model.addAttribute("departments",departments);
return "add";//和前面同样的道理
}
@PostMapping("/add")//这里使用是post请求
public String toadd(Employee employee) {
employeeDao.save(employee);//将数据存储到假的数据库中
return "redirect:/emps";//重定向到emps
}
@GetMapping("/emp/{id}")
public String update(@PathVariable("id") Integer id,Model model) {
Employee employee = employeeDao.getEmployeeById(id);
model.addAttribute("emp",employee);
Collection<Department> departments = departmentDao.getDepartment();
model.addAttribute("departments",departments);
return "update";
}
@PostMapping("/updateEmp")
public String toupdate(Employee employee) {
employeeDao.save(employee);
return "redirect:/emps";
}
@GetMapping("/delete/{id}")
public String delete(@PathVariable("id") Integer id,Model model) {
employeeDao.delete(id);
return "redirect:/emps";
}
}
这一部分主要是对数据库的操作,原理都差不多的.
构建一个简单的网站就差不多到这儿了
四、springboot♂♀数据库
1.springboot整合JDBC
首先最重要的就是链接数据库
spring:
datasource:
username: root
password: root
# 设置时区和编码等
url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8
driver-class-name: com.mysql.cj.jdbc.Driver
这里使用的yaml配置,当然你使用properties也是差不多的
这里链接的是一个叫做mybatis的数据库,里面有一张叫做user的表
接着就是写jdbcController了
@RestController
//因为没有写对应的页面,所以就是直接返回字符串了
public class JDBCcontroller {
@Autowired
JdbcTemplate jdbcTemplate;
//只要配置了数据库就有这个类了
@GetMapping("/select")
public List<Map<String, Object>> userList(){
String sql = "select *from user";
List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);//返回list的值
return maps;
}
@GetMapping("/adduser")
public String adduserList(){
String sql = "insert into mybatis.user(id,name,pwd) values (4,'小明','123456')";
jdbcTemplate.update(sql);//返回list的值
return "add_ok";
}
@GetMapping("/update/{id}")
public String updateuserList(@PathVariable("id") int id){
String sql = "update mybatis.user set name= ?,pwd = ? where id = "+id;
//拼接sql
Object[] objects = new Object[2];
objects[0] = "小明";
objects[1] = "123445";
jdbcTemplate.update(sql,objects);//这里是提供了重载的方法的,传入进取取代两个?,使用数组注入
return "update_ok";
}
@GetMapping("/deleteuser/{id}")
public String deleteuserList(@PathVariable("id") int id){
String sql = "delete from mybatis.user where id = ?";
jdbcTemplate.update(sql,id);
return "update_ok";
}
}
这里唯一需要特别注意的就是第一个获取所有的数据的时候,jdbcTemplate.queryForList(sql)这里返回的是一个 List<Map<String, Object>>的数据类型
2.springboot集成Druid数据源
spring:
datasource:
username: root
password: root
# 设置时区和编码等
url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource #配置这个druid数据源
#SpringBoot默认是不注入这些的,需要自己绑定
#druid数据源专有配置
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
#配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入
#如果允许报错,java.lang.ClassNotFoundException: org.apache.log4j.Priority
#则导入log4j 依赖就行
filters: stat,wall,log4j2 #要使用这个日志功能需要导入log4j
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
前面的数据源的配置和前面的jdbc都是一样的,就是多了后一大堆,多了记录日志的功能,要使用这个功能需要再在xml里面导入log4j的依赖;
并且添加一个Druid的config
@Configuration
public class DruidConfig {
@ConfigurationProperties(prefix = "spring.datasource")
@Bean
public DataSource druidDatasource() {
return new DruidDataSource();
}
//后台监控
@Bean
public ServletRegistrationBean a() {
//因为boot内置了servlet的容器 所以么有web.xml 取而代之的时ServletRegistrationBean,想注册什么new 就欧克
ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
//后台的账号密码
HashMap<String, String> InitParameter = new HashMap<>();
InitParameter.put("loginUsername", "admin"); //这里需要使用固定的key loginUsername loginPassword
InitParameter.put("loginPassword", "123456");
//自己设置一个密码和账号
//允许谁可以访问
InitParameter.put("allow", "");
bean.setInitParameters(InitParameter);
return bean;
}
//filter,,配置一个过滤器
@Bean
public FilterRegistrationBean webStatFilter() {
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter(new WebStatFilter());
//可以过滤哪些请求呢?
Map<String, String> initParameters = new HashMap<>(); //这些东西不进行统计
initParameters.put("exclusions","*.js ,*.css,/druid/*");
bean.setInitParameters(initParameters);
return bean;
}
}
配置好了以后,你在url中输入druid就可以进入一个登录界面
输入刚刚配置的账号和密码后就可以进入页面了;
里面有各种日志信息
比如查询一下刚刚数据库里面的数据
就会有对应的sql信息
五、安全框架
1. SpringSecurity
SpringSecurity是针对Spring项目的安全框架,也是Spring Boot底层安全模块默认的技术选型,它可以实现强大的Web安全控制,对于安全控制,我们仅需要引入spring-boot-security模块,进行少量的配置,即可实现强大的安全管理
记住几个类
- WebSecurityConfigurerAdapter: 自定义Security策略
- AuthenticationManagerBuilder:自定义认证策略
- @EnableWebSecurity:开启WebSecurity模式
SpringSecurity的两个主要目标是“认证”和“授权”(访问控制)。
“认证”(Authentication)
“授权”(Authorization)
这个概念是通用的,而不是只在Spring Security中存在
1.1 设置页面的访问权限
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//链式编程
@Override
protected void configure(HttpSecurity http) throws Exception {
//首页所有人可以访问,功能页只有对应有权限的人才能访问
http.authorizeHttpRequests()
.antMatchers("/").permitAll() //首页所有人都可以访问
.antMatchers("/level1/**").hasRole("vip1") //只有vip1 的用户才可以访问level1下面的页面
.antMatchers("/level2/**").hasRole("vip2") //只有vip2 的用户才可以访问level2下面的页面
.antMatchers("/level3/**").hasRole("vip3"); //只有vip3 的用户才可以访问level3下面的页面
//没有权限默认到那个登录页,需要 写这个代码进行开启 加上后面的.loginPage后就可以定制登录页
http.formLogin().loginPage("/tologin");
}
通过继承和重写authorizeHttpRequests方法用以实现页面的访问权限,有点类似于拦截器配置路径
1.2 设置认证授权
通过对用户的认证授权,赋予用户不同的访问权限
//认证授权
//这里密码需要加密一下才能够使用
//这里使用的是BCryptPasswordEncoder
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
.withUser("kuangshen").password( new BCryptPasswordEncoder().encode("123456") ).roles("vip2","vip3")
.and()
.withUser("root").password( new BCryptPasswordEncoder().encode("123456") ).roles("vip1","vip2","vip3")
.and()
.withUser("guest").password( new BCryptPasswordEncoder().encode("123456") ).roles("vip1");
}
这里需要注意的是直接写密码是会报错的,因为spring会认为这不安全,需要加密一下,这里采用的是BCryptPasswordEncoder加密的方式,如果需要增加用户只需要加上and就行。
1.3 注销和记住我功能
emmmm,然后第三个功能注销和记住我功能的配置
//链式编程
@Override
protected void configure(HttpSecurity http) throws Exception {
//首页所有人可以访问,功能页只有对应有权限的人才能访问
http.authorizeHttpRequests()
.antMatchers("/").permitAll()
.antMatchers("/level1/**").hasRole("vip1")
.antMatchers("/level2/**").hasRole("vip2")
.antMatchers("/level3/**").hasRole("vip3");
//没有权限默认到那个登录页,需要 写这个代码进行开启 加上后面的.loginPage后就可以定制登录页
http.formLogin().loginPage("/tologin");
//开启注销的功能 并且设置注销后的跳转地址
http.logout().logoutSuccessUrl("/");
//开启记住我功能 就是使用cookie实现的 默认保存两周
http.rememberMe();
}
感觉没有啥写的,主要就是在那个方法里面配置这两行代码就行
1.4 SpringSecurity集成thymeleaf
虽然一直觉得thymeleaf拉跨得一批,但是该学得还是要学
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<!--这里自动配置得命名空间是不是这个地址,需要手动修改一下-->
<div class="column" sec:authorize = "hasRole('vip1')"> <!--这里得sec 就是security-->
<div class="ui raised segment">
<div class="ui">
<div class="content">
<h5 class="content">Level 1</h5>
<hr>
<div><a th:href="@{/level1/1}"><i class="bullhorn icon"></i> Level-1-1</a></div>
<div><a th:href="@{/level1/2}"><i class="bullhorn icon"></i> Level-1-2</a></div>
<div><a th:href="@{/level1/3}"><i class="bullhorn icon"></i> Level-1-3</a></div>
</div>
</div>
</div>
</div>
这里的 sec:authorize = “hasRole(‘vip1’)” 的意思就是只有登录的用户的权限是vip1的时候这短前端代码才会展示出来
六、一些常用的任务
1.异步任务
首先我们来看看普通的方法
使用多线程
@Serice
public class AsyncService{
public void hello(){
try{
Thread.sleep(3000);//使用线程使他停止三秒钟
}catch(InterruptedException e){
e.printStackTrace()
}
}
System.out.println("系统正在处理。。。。。");//然后再打印这个
}
/*---------------------------------------------------------*/
@RestController
public class AsyncController{
@Autowired
AsyncService asyncService;
@RequestMapping("/hello")
public String hello(){
asyncService.hello();//停止三秒
}
}
使用springboot实现,只需要两步就可以实现
@Serice
public class AsyncService{
//首先告诉spring这是一个异步的方法,加上一个注解就行
@Async
public void hello(){
try{
Thread.sleep(3000);
}catch(InterruptedException e){
e.printStackTrace()
}
}
System.out.println("系统正在处理。。。。。");
}
/*---------------------------------------------------------*/
//第二步就是开启功能
//这个只需要使用Enable那个注解在主类上面加上就ok
@EnableAsync
@SpringBootApplication
public class YibuApplication {
public static void main(String[] args) {
SpringApplication.run(YibuApplication.class, args);
}
}
大功告成,这样就可以实现异步任务了。
2.邮件任务
邮件任务也是经常需要写的任务。
- 导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
- 获取你邮箱的POP3/SMTP的码
- 在配置文件里面配置相关信息
spring.mail.username=2108796780@qq.com
spring.mail.password=刚刚的那个码
spring.mail.host=smtp.qq.com
# 开启加密验证
spring.mail.properties.mail.smtp.ssl.enable=true
这里需要注意:
host主机是qq就写qq,是163就写163
qq的才有开启加密验证,163没有
-
好的,现在来一个简单的邮件
-
一个复杂的邮件
-
你也可以把这个发邮件的方法封装一下
ok,邮件任务没了
3.定时任务
定时任务的实现也很简单,主要就是cron表达式有点难理解
- 首先需要开启定时功能,这个和之前的一样,只需要Enable就可以
这里使用的是 @EnableScheduling 注解,也是直接加到主类上面就可以了。 - 第二步就是编写一个方法,在方法的上面加上 @Scheduled() 就行,注解里面需要填写表达式,这个不需要记忆,需要的时候去查就行,附上一个链接在线的cron生成器,为了方便理解,附上一张图,如下图。
4.文件上传
最近在写一个项目的时候,需要用到文件的上传的任务,因此把代码粘在这里,以便后面继续回顾和使用
@RestController
public class FileController {
@Autowired
private DynamicService dynamicService;
@PostMapping(value = "/fileload")
public void fileUpload(@RequestPart("file") MultipartFile file, HttpServletRequest request ) {
String fileName = file.getOriginalFilename();//获取文件的原始的名字
String suffixName = fileName.substring(fileName.lastIndexOf("."));//文件后缀
String filePath = "D:/文档/新鲜出炉的程序/SpringBoot/LostandFound/src/main/resources/static/img/dynamic/";
fileName = UUID.randomUUID() + suffixName;//通过uuid生成唯一标识符
File dest = new File(filePath + fileName);
if (!dest.getParentFile().exists()) {
dest.getParentFile().mkdirs();
}
try {
file.transferTo(dest);
} catch (IOException e) {
e.printStackTrace();
}finally {
HttpSession session = request.getSession();
System.out.println(session.getId() +" "+session.getAttribute("uid")+(String)session.getAttribute("dtext")+session.getAttribute("dtag"));
dynamicService.addImg("img/dynamic/"+fileName, (Integer) session.getAttribute("uid"),(String)session.getAttribute("dtext"),(String)session.getAttribute("dtag"));
}
}
}