一、初识boot 
 
可以从Spring或者idea上面直接创建boot项目
@RestController//返回字符串 
1 2 3 4 5 6 7 8 9 10 @RestController public  class  hellocontroller   {     @RequestMapping("/hello")      public  String hello ()  {          return  "hello,world" ;      } }
 
在application中启动程序 
1. pom xml分析 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 <?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 />       </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 >          <dependency >              <groupId > org.springframework.boot</groupId >              <artifactId > spring-boot-starter</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-web</artifactId >          </dependency >               </dependencies >      <build >          <plugins >              <plugin >                  <groupId > org.springframework.boot</groupId >                  <artifactId > spring-boot-maven-plugin</artifactId >              </plugin >          </plugins >      </build > </project > 
 
2. 配置端口 
1 server.port = 8081    // properties配置端口文件
 
3. 启动器 
1 2 3 4 <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) 基础语法 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 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()
1 2 @ConfigurationProperties(prefix = "person") ;
 
再加上对应的名  和yaml中的一样就可以赋值成功了
2. ConfigurationProperties 
自定义配置文件 
 
也可以自定义自己的配置文件绑定一下就行了
1 2 @PropertySouce(value = "classpath:qinjiang.properties")  ...类...
 
也可以使用el表达式 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 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的位置
配置多个端口 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 server:    port:  8080 spring:    profiles:      active:  dev    --- server:    port:  8081 spring:    profiles:  dev --- server:    port:  8082 spring:    profiles:  test 
 
三、web开发 
1. 导入静态资源 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 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中导入这个依赖
1 2 3 4 5 <dependency >      <groupId > org.springframework.boot</groupId >      <artifactId > spring-boot-starter-thymeleaf</artifactId > </dependency > 
 
这样以后template里的html文件通过controller 的跳转就可以访问了
简单的controller和thymeleaf使用  
 
3. mvc配置原理 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @Configuration public  class  MyMvcconfig  implements  WebMvcConfigurer   {     @Override      public  void  addViewControllers (ViewControllerRegistry registry)   {         registry.addViewController("/" ).setViewName("index" );         registry.addViewController("/index.html" ).setViewName("index" );         registry.addViewController("/main.html" ).setViewName("dashboard" );     } }
 
4. 使用Lombok 
Lombok注解快速注解一个标准类
1 2 3 4 5          <dependency >              <groupId > org.projectlombok</groupId >              <artifactId > lombok</artifactId >          </dependency > 
 
1 2 3 4 5 6 7 8 9 10 11 @Data @AllArgsConstructor @NoArgsConstructor public  class  Department   {     public  Integer id;     public  String departName; }
 
 
只需要几行代码,就已经配置好了上面所示的结构
5. thymeleaf使用 
1 2 3 4 5 6 7 8 9 10 11 <html  lang ="en"  xmlns:th ="http://www.thymeleaf.org" >   <link  th:href ="@{/css/bootstrap.min.css}"  rel ="stylesheet" > <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. 数据层的实现 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 @Repository public  class  EmployeeDao   {     private  static  Map<Integer, Employee> employees = null ;     @Autowired      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();     }                                       public  Employee getEmployeeById (Integer id)  {         return  employees.get(id);     }          public  void  delete (Integer id)  {         employees.remove(id);     } }
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 @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. 登录功能的实现 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 @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();         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-2~all~top_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照样可以进入登录的后的界面,这又问题啊,这里就需要用到我们的拦截器了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 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);             return  false ;         }else {             return  true ;         }     } }
 
写拦截器首先需要实现一下HandlerInterceptor 
然后重写preHandle 
这里采用的是获取刚刚登录时发送的session 数据,要数据匹配才能登录 
然后设置一个request的请求,设置一段话 
通过转发的方法将这句话返回到登录的界面 
 
request.getRequestDispatcher(“/index.html”).forward(request,response);//把这个请求专发到index页面
 
登录失败的时候就会显示这段话提醒 
6. 最后还有一步
1 2 3 4 5 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就是放行的路径。 
然后一个拦截器就配置好了
9. 增删改查的实现 
最重要的功能–增删改查
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 @Controller public  class  EmployeeController   {     @Autowired      EmployeeDao employeeDao;     @Autowired      DepartmentDao departmentDao;     @RequestMapping("/emps")      public  String list (Model model)  {         Collection<Employee> employees = employeeDao.getAll();                  model.addAttribute("emps" ,employees);                  return  "list" ;     }     @GetMapping("/add")      public  String add (Model model)   {         Collection<Department> departments = departmentDao.getDepartment();         model.addAttribute("departments" ,departments);         return  "add" ;     }     @PostMapping("/add")      public  String toadd (Employee employee)   {         employeeDao.save(employee);         return  "redirect:/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 
首先最重要的就是链接数据库
1 2 3 4 5 6 7 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了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 @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);         return  maps;     }     @GetMapping("/adduser")      public  String  adduserList ()  {         String sql = "insert into mybatis.user(id,name,pwd) values (4,'小明','123456')" ;         jdbcTemplate.update(sql);         return  "add_ok" ;     }     @GetMapping("/update/{id}")      public  String updateuserList (@PathVariable("id")  int  id)  {         String sql = "update mybatis.user set name= ?,pwd = ? where id = " +id;                  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数据源 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 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                     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,wall,log4j2       maxPoolPreparedStatementPerConnectionSize:  20      useGlobalDataSourceStat:  true      connectionProperties:  druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500 
 
前面的数据源的配置和前面的jdbc都是一样的,就是多了后一大堆,多了记录日志的功能,要使用这个功能需要再在xml里面导入log4j的依赖;
 
并且添加一个Druid的config
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 @Configuration public  class  DruidConfig   {     @ConfigurationProperties(prefix = "spring.datasource")      @Bean      public  DataSource druidDatasource ()   {         return  new  DruidDataSource();     }          @Bean      public  ServletRegistrationBean a ()   {                  ServletRegistrationBean<StatViewServlet> bean = new  ServletRegistrationBean<>(new  StatViewServlet(), "/druid/*" );                  HashMap<String, String> InitParameter = new  HashMap<>();         InitParameter.put("loginUsername" , "admin" );           InitParameter.put("loginPassword" , "123456" );                  InitParameter.put("allow" , "" );         bean.setInitParameters(InitParameter);         return  bean;     }          @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信息 
五、SpringSecurity 
SpringSecurity是针对Spring项目的安全框架,也是Spring Boot底层安全模块默认的技术选型,它可以实现强大的Web安全控制,对于安全控制,我们仅需要引入spring-boot-security模块,进行少量的配置,即可实现强大的安全管理
记住几个类
WebSecurityConfigurerAdapter: 自定义Security策略 
AuthenticationManagerBuilder:自定义认证策略 
@EnableWebSecurity:开启WebSecurity模式 
SpringSecurity的两个主要目标是“认证”和“授权”(访问控制)。 
“认证”(Authentication) 
“授权”(Authorization) 
这个概念是通用的,而不是只在Spring Security中存在 
 
1. 设置页面的访问权限 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @EnableWebSecurity public  class  SecurityConfig   extends  WebSecurityConfigurerAdapter   {          @Override      protected  void  configure (HttpSecurity http)  throws  Exception  {                  http.authorizeHttpRequests()                 .antMatchers("/" ).permitAll()                             .antMatchers("/level1/**" ).hasRole("vip1" )                   .antMatchers("/level2/**" ).hasRole("vip2" )                   .antMatchers("/level3/**" ).hasRole("vip3" );                                    http.formLogin().loginPage("/tologin" );     }
 
通过继承和重写authorizeHttpRequests方法用以实现页面的访问权限,有点类似于拦截器配置路径
2.设置认证授权 
通过对用户的认证授权,赋予用户不同的访问权限
1 2 3 4 5 6 7 8 9 10 11 12                @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就行。
3.注销和记住我功能 
emmmm,然后第三个功能注销和记住我功能的配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20     @Override     protected  void  configure (HttpSecurity http)  throws  Exception  {                http.authorizeHttpRequests()                .antMatchers("/" ).permitAll()                .antMatchers("/level1/**" ).hasRole("vip1" )                .antMatchers("/level2/**" ).hasRole("vip2" )                .antMatchers("/level3/**" ).hasRole("vip3" );                http.formLogin().loginPage("/tologin" );                http.logout().logoutSuccessUrl("/" );                http.rememberMe();    }
 
感觉没有啥写的,主要就是在那个方法里面配置这两行代码就行
4.SpringSecurity集成thymeleaf 
虽然一直觉得thymeleaf拉跨得一批,但是该学得还是要学
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <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')" >                   <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.异步任务 
首先我们来看看普通的方法
使用多线程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 @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实现,只需要两步就可以实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 @Serice public  class  AsyncService  {     @Async      public  void  hello ()  {        try {            Thread.sleep(3000 );        }catch (InterruptedException e){            e.printStackTrace()        }     }     System.out.println("系统正在处理。。。。。" ); } @EnableAsync @SpringBootApplication public  class  YibuApplication   {     public  static  void  main (String[] args)   {         SpringApplication.run(YibuApplication.class, args);     } }
 
大功告成,这样就可以实现异步任务了。
2.邮件任务 
邮件任务也是经常需要写的任务。
导入依赖 
 
1 2 3 4 5 <dependency >             <groupId > org.springframework.boot</groupId >             <artifactId > spring-boot-starter-mail</artifactId > </dependency > 
 
获取你邮箱的POP3/SMTP的码 
 
在配置文件里面配置相关信息 
 
1 2 3 4 5 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.文件上传 
最近在写一个项目的时候,需要用到文件的上传的任务,因此把代码粘在这里,以便后面继续回顾和使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 @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;         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" ));         }     } }