[ SpringBoot ] 新手小白的详细使用方法
一. 概述
1.为什么使用SpringBoot
2. 搭建
3. 配置值文件
二.SpringBoot的深入了解
1. Spring数据访问管理
2. 如何解决跨域问题
3.token拦截器的添加
三. 项目中运用
1. 管理员管理
2.. 分页组件
3. 新增管理员对话框
4.动态显示菜单数据
5.管理员的增删改
1.新增并保存管理员
2. 删除管理员
3.修改管理员
6.添加登录时密码加密
7. 动态循环查询菜单
四.SpringBoot的其他常用功能
1. 统一异常处理
2. 日志功能
1. 概述
2. 日志需要记录哪些信息(常问)
3. 如何添加日志
3. 集成 Swagger 在线文档
1.概述
2.导入jar依赖
3.添加配置类
4. 注解介绍
5. 测试
4.定时任务
(1)实现方式:
(2)网站学习介绍
一. 概述
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 {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String token =request.getHeader("token");System.out.println("token 认证拦截器:"+token);if(JWTUtil.verify(token)){//认证tokenreturn 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">selecta.id,a.account,a.gender,a.phone,a.type,oa.account oper_account,a.oper_timefromadmin ainner join admin oaon a.adminid = oa.idwhere 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);@Autowiredprivate 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 {//登录成功,为管理员提供tokenString token = JWTUtil.getToken(admin);//为当前admin提供一个tokenadmin.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);@Autowiredprivate 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 {//登录成功,为管理员提供tokenString token = JWTUtil.getToken(admin);//为当前admin提供一个tokenadmin.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