[ SpringBoot ] 新手小白的详细使用方法
一. 概述
1.为什么使用SpringBoot
Spring虽然有很多优点, 但是Spring框架的搭建非常麻烦
1. 配置麻烦,而且很多都是模版化的配置(固定的)
2. 需要添加很多依赖, 例如web层依赖jackson组件,需要我们自己添加, 版本也可能不匹配
基于以上两点,spring官方推出了SpringBoot .
2. 搭建
new project ---- java ----Maven
添加父工程 (不放在dependencies里面)
<!--依赖的父级工程-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.6</version>
<relativePath/>
</parent>
添加依赖
<!--添加基本的 springweb 依赖-->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
添加打包插件(不放在dependencies里面)
<!--打包插件-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.6.6</version>
</plugin>
</plugins>
</build>
添加启动类
package com.ffyc.news;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
/*springboot应用的启动类*/
@SpringBootApplication
//@EnableScheduling
@MapperScan("com.ffyc.news.dao")
public class NewsApplication {
public static void main(String[] args) {
SpringApplication.run(NewsApplication.class);
}
}
创建web层 service层 dao层 model层 config层(配置层) interceptor层(拦截器)
在resources下创建applicantion.yml文件(配置值的文件)
3. 配置值文件
application.properties
属性文件格式,内容为键值对 server.port=8080
properties 格式比较简单,没有什么难度,在此我们以第二种 yaml 格式为例.
application.yml(重要)
yml 是 YAML(YAML Ain’t Markup Language)语言的文件,以数据为中心.
1.yaml 基本语法: 语法结构:key:空格 value; ( 注意: 空格不能省略)
2. 以空格的缩进来控制层级关系,只要是左边对齐的一列数据都是同一个层级的;
3. 字面量直接写在后面就可以,字符串默认不用加上双引号或者单引号;
4. 以#作为注释符号.
5. 使用@Value 注解标签将配置文件中的内容映射到类中的属性. @Value("${user.name}")
二.SpringBoot的深入了解
1. Spring数据访问管理
数据源配置
为了连接数据库需要引入 jdbc 支持,在 pom.xml 中添加依赖 (记得添加 mysql 驱动依赖)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
在 application.yml 中配置数据源信息(本次使用的是阿里数据源)
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
#url: jdbc:mysql://127.0.0.1:3306/newsdb?serverTimezone=Asia/Shanghai
url: jdbc:mysql://192.168.244.128:3306/newsdb?serverTimezone=Asia/Shanghai
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource #指定数据库连接管理类
initialSize: 5
maxActive: 20
添加阿里数据源依赖
<!-- 阿里数据源 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
复制一个前端项目, 删除里面不需要的文件和配置

2. 如何解决跨域问题
出现此错误需要解决跨域问题

添加配置类
package com.ffyc.news.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import java.util.Collections;
@Configuration//配置类,启动时被扫描
public class CorsConfig {
@Bean//等价于<bean id="" class=""/>配置我们的类(创建 配置 和返回对象),交给spring管理
public CorsFilter corsFilter() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
//1,允许任何来源
corsConfiguration.setAllowedOriginPatterns(Collections.singletonList("*"));
//2,允许任何请求头
corsConfiguration.addAllowedHeader(CorsConfiguration.ALL);
//3,允许任何方法
corsConfiguration.addAllowedMethod(CorsConfiguration.ALL);
//4,允许凭证
corsConfiguration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfiguration);
return new CorsFilter(source);
}
}
虽然springboot简化了spring应用的搭建,将一些常用的基础组件自动配置
但是项目中会用到各种各样的组件,有的组件springboot没有提供自动配置,
需要我们自己来配置
springboot不使用xml文件配置,而是使用Java代码中配置
3.token拦截器的添加
操作: 登录成功后在后端生成token, 在前端浏览器保存token
在util包下导入jwt(秘钥获得token),并添加依赖.
package com.ffyc.news.util;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.JWTVerifier;
import com.ffyc.news.model.Admin;
import com.ffyc.news.model.User;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* JWT工具类
*/
public class JWTUtil {
/**
* 根据用户id,账号生成token
* @param admin
* @return
*/
public static String getToken(Admin admin) {
String token = "";
try {
//过期时间 为1970.1.1 0:0:0 至 过期时间 当前的毫秒值 + 有效时间
Date expireDate = new Date(new Date().getTime() + 3600*1000);
//秘钥及加密算法
Algorithm algorithm = Algorithm.HMAC256("ZCEQIUBFKSJBFJH2020BQWE");
//设置头部信息
Map<String,Object> header = new HashMap<>();
header.put("typ","JWT");
header.put("alg","HS256");
//携带id,账号信息,生成签名
token = JWT.create()
.withHeader(header)//第一部分
//第二部分
.withClaim("id",admin.getId())
.withClaim("account",admin.getAccount())
.withClaim("type",admin.getType())//在token里面显示管理员类型
.withExpiresAt(expireDate)//设置有效时间
.sign(algorithm);//第三部分
}catch (Exception e){
e.printStackTrace();
return null;
}
return token;
}
public static String getUserToken(User user) {
String token = "";
try {
//过期时间 为1970.1.1 0:0:0 至 过期时间 当前的毫秒值 + 有效时间
Date expireDate = new Date(new Date().getTime() + 3600*24*14*1000);
//秘钥及加密算法
Algorithm algorithm = Algorithm.HMAC256("ZCEQIUBFKSJBFJH2020BQWE");
//设置头部信息
Map<String,Object> header = new HashMap<>();
header.put("typ","JWT");
header.put("alg","HS256");
//携带id,账号信息,生成签名
token = JWT.create()
.withHeader(header)//第一部分
//第二部分
.withClaim("id",user.getId())
.withClaim("email",user.getEmail())
.withExpiresAt(expireDate)//设置有效时间
.sign(algorithm);//第三部分
}catch (Exception e){
e.printStackTrace();
return null;
}
return token;
}
/**
* 验证token是否有效
* @param token
* @return
*/
public static boolean verify(String token){
try {
//验签
Algorithm algorithm = Algorithm.HMAC256("ZCEQIUBFKSJBFJH2020BQWE");
JWTVerifier verifier = JWT.require(algorithm).build();
DecodedJWT jwt = verifier.verify(token);
return true;
} catch (Exception e) {//当传过来的token如果有问题,抛出异常
return false;
}
}
/**
* 获得token 中playload部分数据,按需使用
* @param token
* @return
*/
public static DecodedJWT getTokenInfo(String token){
return JWT.require(Algorithm.HMAC256("ZCEQIUBFKSJBFJH2020BQWE")).build().verify(token);
}
public static Admin getOperAdmin(String token){
DecodedJWT decodedJWT = JWTUtil.getTokenInfo(token);
int adminid = decodedJWT.getClaim("id").asInt();
Admin admin = new Admin();
admin.setId(adminid);
return admin;
}
}
<!--jwt组件-->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.8.2</version>
</dependency>
操作: 在后端创建token验证拦截器,并配置拦截器
添加拦截器
package com.ffyc.news.interceptor;
import com.auth0.jwt.JWT;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ffyc.news.model.Result;
import com.ffyc.news.util.JWTUtil;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//拦截器
public class TokenInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token =request.getHeader("token");
System.out.println("token 认证拦截器:"+token);
if(JWTUtil.verify(token)){//认证token
return true;//离开拦截器,继续向后到达自定义处理器
}else {
response.setContentType("text/html;charset=utf-8");//设置响应内容的格式
Result result = new Result(401,"token认证失败",null);
response.getWriter().write(new ObjectMapper().writeValueAsString(result));
return false;//不继续向后执行
}
}
}
配置拦截器
package com.ffyc.news.config;
import com.ffyc.news.interceptor.TokenInterceptor;
import com.ffyc.news.interceptor.UserTokenInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;
@Configuration
public class WebConfig implements WebMvcConfigurer{
//添加(配置)拦截器
public void addInterceptors(InterceptorRegistry registry) {
//添加(配置)管理员拦截器
InterceptorRegistration inter = registry.addInterceptor(new TokenInterceptor());//注册自己的拦截器
inter.addPathPatterns("/api/**"); //进入拦截器的地址 (管理员需要拦截的地址)
inter.excludePathPatterns("/api/loginCtl/login");//不进入拦截器的地址
//添加(配置)用户拦截器
InterceptorRegistration userInter = registry.addInterceptor(new UserTokenInterceptor());//注册自己的拦截器
userInter.addPathPatterns("/user/userCtl/**"); //进入拦截器的地址 (管理员需要拦截的地址)
//以下不需要进入拦截器
userInter.excludePathPatterns("/user/userCtl/createCode");//生成邮箱验证码不进入拦截器的地址
userInter.excludePathPatterns("/user/userCtl/saveUser");//注册保存不进入拦截器的地址
userInter.excludePathPatterns("/user/userCtl/create");//生成图形验证码不进入拦截器的地址
userInter.excludePathPatterns("/user/userCtl/login");//用户登录不进入拦截器的地址
}
}
三. 项目中运用
1. 管理员管理
数据初始化: 建一张admin表,并填充几个数据

查询基本的管理员列表

为列表添加查询条件功能
前端( 注意: 添加在el-card下面就好了 )
<!-- 查询条件-->
<el-row :gutter="20">
<el-col :span="6">
<el-input placeholder="账号" v-model="form.account"></el-input>
</el-col>
<el-col :span="6">
<el-input placeholder="电话" v-model="form.phone"></el-input>
</el-col>
<el-col :span="6">
<el-button type="primary" icon="el-icon-search" @click="findList()" >查询</el-button>
</el-col>
</el-row>

后端:大部分和基础查询的写法一致,少部分有改变 例如:
将数据封装在admin对象里面,同时添加判断
<resultMap id="adminMap" type="Admin">
<id column="id" property="id"></id>
<result column="account" property="account"></result>
<result column="gender" property="gender"></result>
<result column="phone" property="phone"></result>
<result column="type" property="type"></result>
<result column="oper_time" property="operTime"></result>
<!--封装操作人对象数据-->
<association property="admin" javaType="Admin">
<result column="oper_account" property="account"></result>
</association>
</resultMap>
<select id="admins" parameterType="Admin" resultMap="adminMap">
select
a.id,
a.account,
a.gender,
a.phone,
a.type,
oa.account oper_account,
a.oper_time
from
admin a
inner join admin oa
on a.adminid = oa.id
where a.type = 1
<if test="account!=''">
and a.account=#{account}
</if>
<if test="phone!=''">
and a.phone=#{phone}
</if>
</select>
2.. 分页组件
1. 后端使用mybatis分页组件, 快捷实现后端分页功能
添加分页组件依赖
<!-- pagehelper依赖 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.5</version>
</dependency>
applicantion.yml中
spring:
main:
allow-circular-references: true #开始支持spring循环依赖
public PageInfo<Admin> admins(Admin admin){
//告诉分页组件,当前页数,页数大小,会自动算出开始位置,并且会在sql后面自动添加limit语句
PageHelper.startPage(admin.getPageNo(), admin.getPageSize());
ArrayList<Admin> admins = adminDao.admins(admin);
//会再生成一条sql 查询总条数 会把与分页相关的数据封装到PageInfo中
PageInfo<Admin> pageInfo = new PageInfo<>(admins);
return pageInfo;
}
2. 前端使用elementui
<!-- 分页组件-->
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="form.pageNo"
:page-sizes="[2,4,6,8]"
:page-size="form.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total">
</el-pagination>

3. 新增管理员对话框
导入导入--注册组件--使用组件
添加方法,打开对话框(this.$refs.add.dialogVisible =true;)----调用方法
修改之前的div内容(例如this. form)
4.动态显示菜单数据
(1)搭建静态菜单信息
顺序: controller层---service层---dao层---mapper层
注意: menu是以ArrayList数组的形式返回
简单的数据直接以注解的形式在dao层查询, 不用到mapper层
(2)动态查询菜单信息
组件格式可以通过elementUI查找 (这里只展示部分代码)


5.管理员的增删改
1.新增并保存管理员
(1)后端接收
注意: token需要添加注解 @RequestHeader("token")
1.为管理员生成默认密码并加密密码
2.从token中获取当前管理员id
3.保存管理员信息到数据库的admin表,并拿到管理员id
4.保存给管理员分配的权限数据

2. 删除管理员
注意: 先删除关系表, 再删除管理员

3.修改管理员

6.添加登录时密码加密
修改登录

修改jwt密码加密


7. 动态循环查询菜单

注意: 两个参数以上时传递参数需要使用注解

四.SpringBoot的其他常用功能
1. 统一异常处理
在util包中添加,在出现异常时,java后端会进行异常处理, 打印异常信息,就不需要在controller层进行try{}catch{}
package com.ffyc.news.util;
import com.ffyc.news.model.Result;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
//基于AOP实现 全局 的统一异常处理
@RestControllerAdvice
public class GlobalExceptionHandler {
/**
* 异常处理通知,当controller中的方法出现异常,执行该方法
*/
@ExceptionHandler(Exception.class)
public Result globalException(Exception e) {
Result commonResult = new Result(500,"服务器忙,请稍后再试",e.getMessage());
//测试期间
e.printStackTrace();
return commonResult;
}
}
2. 日志功能
1. 概述
日志可以对程序运行的过程进行检测,尤其在生产环境中,由于生产环境中没有控制台,需要把程序运行产生的一些数据存储到日志文件中,便于后期排查错误
2. 日志需要记录哪些信息(常问)
1.记录参数数据 例如进入某个方法,需要接受的参数,将参数进行保存
2.记录程序运行轨迹 进入不同的方法,打印不同日志 (先启动啥,然后初始化了啥,接下来干了啥.......)
3.记录异常信息
3. 如何添加日志
(1) 用IO流将异常 参数 步骤信息等输出到指定文件中
(2) 通过市面上的日志组件,实现日志保存功能
市面上常用的日志组件:
slf4j(Simple Logging Facade for Java)
commons-logging 接口
Log4J
Log4J2
Logback
JUL(Java Utils Logging
在applicantion.yml中添加日志配置
logging:
level:
com.ffyc.news: debug # 打印日志的文件 : 级别
file:
name: D:/log/log.log # 日志文件打印地址
日志的级别划分:debug<info<warn<error 日志会打印自身及以上级别的信息
方法一:
其余信息在 logback 配置文件中 在类中使用 ,创建 Logger 对象
private static Logger logger = LoggerFactory.getLogger(当前类名.class);
在需要的位置调用具体的日志级别方法输出
logger.debug("user account:{},user password:{}", user.getAccount(),user.getPassword());
logger.info("user account:{},user password:{}", user.getAccount(),user.getPassword());
logger.warn("user account:{},user password:{}", user.getAccount(),user.getPassword());logger.error("user account:{},user password:{}", user.getAccount(),user.getPassword());
package com.ffyc.news.web;
import com.ffyc.news.model.Admin;
import com.ffyc.news.model.Result;
import com.ffyc.news.service.LoginService;
import com.ffyc.news.util.JWTUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
//服务器
@RestController
@RequestMapping(path = "/api/loginCtl")
public class LoginController {
//日志定义
private static Logger logger = LoggerFactory.getLogger(LoginController.class);
@Autowired
private LoginService loginService;
@PostMapping(path="/login")
public Result login(@RequestBody Admin admin){
//日志打印
logger.info("enter login method");
logger.debug("login account:{},password:{}",admin.getAccount(),admin.getPassword());
logger.error("系统忙,请稍后再试");
//参数保存
admin = loginService.login(admin);
//System.out.println(1/0);
//判断登录是否成功
if(admin==null){
return new Result(201,"登录失败",null);
}else {
//登录成功,为管理员提供token
String token = JWTUtil.getToken(admin);//为当前admin提供一个token
admin.setToken(token);//将提供的token set到 admin对象里面
return new Result(200,"登录成功",admin);
}
}
@GetMapping(path = "/test")
public String test(){
System.out.println("test");
return "success";
}
/*
查询管理员菜单
*/
@GetMapping(path = "/menus")
public Result menus(@RequestHeader("token") String token){
ArrayList menus=loginService.menus(token);
return new Result(200,"查询成功",menus);
}
}
方法二: 使用 AOP 统一打印日志
导入依赖 jar
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
定义切面通知类
package com.ffyc.news.util;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
@Component
@Aspect
public class LogAspect {
private Logger logger = LoggerFactory.getLogger(LogAspect.class);
// 任意返回值 web包下任意类 任意方法
@Before("execution(public * com.ffyc.news.web.*.*(..))")
public void savelog(JoinPoint joinPoint) {
ServletRequestAttributes attributes =
(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
Object[] objs = joinPoint.getArgs();//获取方法参数
logger.info("method args:{}", Arrays.toString(objs));
// 记录下请求内容
logger.info("HTTP_METHOD :{} ", request.getMethod());
logger.info("IP : {}", request.getRemoteAddr());//客户端 ip
}
}
3. 集成 Swagger 在线文档
1.概述
(1)api 文档: 目前开发是前后端分离的 ,后端开发人需要为前端开发人员提供一个api说明文档
(2)前提: 当代码修改时,也需要修改api文档 ,频繁修改文档,不方便
(3)Swagger好处:
使用Swagger可以直接通过代码生成文档,不需要自己手动编写接口文档
Swagger 生成的文档支持在线测试
(提供Web页面在线测试API参数和格式都定好了,直接在界面上输入参数的值即可在线测试)
本次使用 knife4j (前身swagger-bootstrap-ui)实现接口文档生成
文档访问地址:http://ip:端口/doc.html
2.导入jar依赖
<dependency>
<groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi2-spring-boot-starter</artifactId>
<version>4.4.0</version>
</dependency>
3.添加配置类
package com.ffyc.news.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;
@Configuration//配置类,启动自动扫扫描
@EnableSwagger2WebMvc
public class Knife4jConfiguration {
@Bean(value = "dockerBean")
public Docket dockerBean() {
//指定使用Swagger2规范
Docket docket=new Docket(DocumentationType.SWAGGER_2)
.apiInfo(new ApiInfoBuilder()
//描述字段支持Markdown语法
.description("# Knife4j RESTful APIs")
.termsOfServiceUrl("https://doc.xiaominfo.com/")
.contact("xiaoymin@foxmail.com")
.version("1.0")
.build())
//分组名称
.groupName("用户服务")
.select()
//这里指定Controller扫描包路径
.apis(RequestHandlerSelectors.basePackage("com.ffyc.news.web"))
.paths(PathSelectors.any())
.build();
return docket;
}
}
4. 注解介绍
Swagger 使用的注解及其说明
@Api:用在类上,说明该类的作用,tags 类的功能进行描述.
@Api(tags="用户登录控制器")
@ApiOperation:用在方法上,用于对方法功能说明。
@ApiOperation(value="方法概述")
@ApiImplicitParam:用来注解来给方法入参增加说明
@ApiModel:描述一个 Model 的信息(参数为实体类时使用)
@ApiModelProperty:描述一个 model 的属性
@ApiResponses:用于表示一组响应
@ApiResponse:用在@ApiResponses 中,一般用于表达响应信息
5. 测试
package com.ffyc.news.web;
//服务器
import com.ffyc.news.model.Admin;
import com.ffyc.news.model.Result;
import com.ffyc.news.service.LoginService;
import com.ffyc.news.util.JWTUtil;
import io.swagger.annotations.*;
import org.aspectj.apache.bcel.classfile.Code;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
@Api("管理登录处理器")
@RestController
@RequestMapping(path = "/api/loginCtl")
public class LoginController {
//日志定义
private static Logger logger = LoggerFactory.getLogger(LoginController.class);
@Autowired
private LoginService loginService;
@ApiOperation("管理员登录接口")
@ApiResponses({
@ApiResponse(code = 200,message = "响应成功"),
@ApiResponse(code = 200,message = "响应成功"),
@ApiResponse(code = 200,message = "响应成功"),
@ApiResponse(code = 200,message = "响应成功"),
})
@PostMapping(path="/login")
public Result login(@RequestBody Admin admin){
//日志打印
logger.info("enter login method");
logger.debug("login account:{},password:{}",admin.getAccount(),admin.getPassword());
logger.error("系统忙,请稍后再试");
//参数保存
admin = loginService.login(admin);
//System.out.println(1/0);
//判断登录是否成功
if(admin==null){
return new Result(201,"登录失败",null);
}else {
//登录成功,为管理员提供token
String token = JWTUtil.getToken(admin);//为当前admin提供一个token
admin.setToken(token);//将提供的token set到 admin对象里面
return new Result(200,"登录成功",admin);
}
}
@GetMapping(path = "/test")
public String test(){
System.out.println("test");
return "success";
}
/**
查询管理员菜单
*/
@ApiOperation("查询管理员权限菜单")
@ApiImplicitParams({
@ApiImplicitParam(name="token",value = "管理员token",required = true,type = "String")
})
@GetMapping(path = "/menus")
public Result menus(@RequestHeader("token") String token){
ArrayList menus=loginService.menus(token);
return new Result(200,"查询成功",menus);
}
}
文档访问地址:http://ip:端口/doc.html
4.定时任务
(1)实现方式:
方式 1: 使用 java 自带的 TimerTask,Timer
public static void main(String[] args) {
// 定义一个任务
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
System.out.println("打印当前时间:" + new Date());
}
};
// 计时器
Timer timer = new Timer();
// 开始执行任务 (延迟 1000 毫秒执行,每 3000 毫秒执行一次)
timer.schedule(timerTask, 1000, 3000);
}
方式 2: 使用 spring 框架中提供的定时任务
a.开启定时任务
在 SpringBoot 的启动类上声明 @EnableScheduling
b.添加定时任务
只需使用@Scheduled 注解标注即可,Spring Boot 启动后会自动加载并执行定时任务,无需手动操作
@Component
public class TestTask {
@Scheduled(cron = "*/6 * * * * ?")//每六秒执行一次
private void process() {
System.out.println("现在时间:" + new Date());
}
}
(2)网站学习介绍
https://cron.qqe2.com


更多推荐





所有评论(0)