springboot总结(一)
常用依赖
<properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><!-- 打包时跳过测试--><skipTests>true</skipTests></properties>
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><!-- mysql --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><!-- 作用域 --><scope>runtime</scope></dependency><!-- mybatis-plus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.3</version></dependency><!-- 测试 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><!-- 作用域 --><scope>test</scope></dependency><!-- 实体类使用@Data --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!-- swagger2测试--><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId> <version>2.9.2</version></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>2.9.2</version></dependency><!-- json工具--><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.76</version></dependency></dependencies>
<build><!-- 打jar包插件 maven>双击package --><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
常用配置
server:port: 8888servlet:context-path: /stest #路径名#应用名称
spring:jeckson:date-format: yyyy-MM-dd hh:mm:sstime-zone: GTM+8 #后台返回前台时间处理 hh:mm:ss解决后台返回前台时间不一致redis:port: 63792host: 127.0.0.1password: 123456application:name: spiderdatasource:name: yinxun #数据库名url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&useSSL=false #假如时区报错,就增加一个时区配置?serverTimezone=UTCusername: root #用户名password: 123456 #密码 driver-class-name: com.mysql.cj.jdbc.Driver #数据库链接驱动#mybatis-plus
mybatis-plus:mapper-locations: classpath:mapper/*.xml #配置映射文件 自定义时使用configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #日志打印lucenePath: F:/tmp/lucene/ #别的地方可通过@Value取得
启动类
@EnableTransactionManagement//事务管理
@EnableScheduling//开启定时任务
@MapperScan("com.liulang.xx.mapper")//扫描包,也可以放在mybatis-plus 上
@SpringBootApplication
public class SssApp {public static void main(String[] args) {SpringApplication.run(SssApp.class,args);}}
mybatis-plus 使用
依赖(pom)
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.3</version></dependency>
(application.yml)
#mybatis-plus
mybatis-plus:mapper-locations: classpath:mapper/*.xml #配置映射文件 自定义时使用configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #日志打印
配置类
@Configuration
@MapperScan("com.yx.spider.dao.mapper")
public class MybatisPlusConfig {//分页插件@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor(){MybatisPlusInterceptor interceptor =new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor());return interceptor;}
}
使用例子
mapper层
@Repository
public interface SysUserMapper extends BaseMapper<SysUser> {
pojo层
@Data
@TableName("sys_user")
public class SysUser {
// @TableId(type = IdType.ASSIGN_ID) // 默认id类型 分布式id 雪花算法
// @TableId(type = IdType.AUTO)// 数据库自增//@JsonFormat 用来表示json序列化的一种格式或者类型,shap表示序列化后的一种类型//解决后台到前台 精度缺失@JsonFormat(shape = JsonFormat.Shape.STRING)private Long id;@TableField("create_date")private Date createDate;@TableLogic //逻辑删除 默认0 表示未删除 需要在添加时设置 1表示已删除private Integer deleted;
查询
// 根据id 查询
SysUser sysUser = sysUserMapper.selectById(id);//查询一条
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(SysUser::getAccount,account);queryWrapper.eq(SysUser::getPassword,password);queryWrapper.select(SysUser::getAccount,SysUser::getId,SysUser::getAvatar,SysUser::getNickname);
queryWrapper.last("limit 1");//表示在sql语句末尾添加 查询一条可以不使用
SysUser sysuser =sysUserMapper.selectOne(queryWrapper);//查询多条LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.orderByDesc(Article::getViewCounts);queryWrapper.select(Article::getId,Article::getTitle);queryWrapper.last("limit "+limit);//注意limit后加空格List<Article> articles = articleMapper.selectList(queryWrapper);
//快捷使用
List<BannerItem> bannerItems = new LambdaQueryChainWrapper<>(bannerItemMapper).eq(BannerItem::getBannerId, id).list();
BannerItem bannerItem = new LambdaQueryChainWrapper<>(bannerItemMapper).eq(BannerItem::getId, id).one();
// queryWraper 单条语句之间,默认使用and
// 使用 or 时如下queryWraper.and(i -> i.like(Article::getTitle, "%"+finalKeywords).or().like(Article::getKeyWords,"%"+finalKeywords));
添加
SysUser sysUser = new SysUser();
sysUser.setAccount(userParms.getAccount());
sysUser.setNickname(userParms.getNickname());
sysUserMapper.insert(sysUser);
//添加完后可获得数据库生成 id
Long id = sysUser.getId();
修改
//查询
SysUser sysUser = sysUserMapper.selectById(id);
//修改
sysUser.setAccount(userParms.getAccount());
sysUserMapper.updateById(sysUser)
删除
// 单个删除
sysUserMapper.deleteById(id);
// 批量删除
ArrayList<Long> integers = new ArrayList<>();integers.add()。。。
。。。。//获得 id 列表
sysUserMapper.deleteBatchIds(integers);
swagger测试 使用
依赖
<!-- swagger2--><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.9.2</version></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>2.9.2</version></dependency>
配置类
/*** @ClassName SwaggerConfig* @Description 访问地址 http://127.0.0.1:8081/swagger-ui.html**/
@Configuration//配置到配置里
@EnableSwagger2 //开启swagger
public class SwaggerConfig {
}
使用
//访问地址 http://127.0.0.1:8081/swagger-ui.html 在Controller类添加注解
@Api(tags = "用户管理")
@RestController
@RequestMapping("users")
public class UserController {
。。。 @ApiOperation("获取当前用户信息")@GetMapping("currentUser")public Result currentUser(@RequestHeader("Authorization") String token )
常见问题
解决跨域
在 Controller 类 上加注解 @CrossOrigin
后端返回前端时间少一天(8小时)
配置文件修改
spring:jeckson:date-format: yyyy-MM-dd hh:mm:sstime-zone: GTM+8 #后台返回前台时间处理 hh:mm:ss
实体类中对date类型进行注解序列化
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd hh:mm:ss")
对象中相同数据转化
import org.springframework.beans.BeanUtils;
//将 article 与articlevo 中相同属性转换
BeanUtils.copyProperties(article,articleVo);
WebMvc配置拦截器
自定义拦截器
/*** @ClassName LoginInterceptor* 登陆拦截器 也可以自定义实现权限控制**/
@Component
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {@Autowiredprivate LoginService loginService;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//在执行controller方法(Handler)之前进行执行if (!(handler instanceof HandlerMethod)){//handler 可能是 RequestResourceHandler springboot 程序 访问静态资源 默认去classpath下的static目录去查询return true;}//获取tokenString token = request.getHeader("Authorization");//日志打印log.info("=================request start===========================");String requestURI = request.getRequestURI();log.info("request uri:{}",requestURI);log.info("request method:{}",request.getMethod());log.info("token:{}", token);log.info("=================request end===========================");if (StringUtils.isBlank(token)){Result result = Result.fail(ErrorCode.NO_LOGIN.getCode(), "未登录");response.setContentType("application/json;charset=utf-8");response.getWriter().print(JSON.toJSONString(result));return false;}SysUser sysUser = loginService.checkToken(token);if (sysUser == null){Result result = Result.fail(ErrorCode.NO_LOGIN.getCode(), "未登录");response.setContentType("application/json;charset=utf-8");response.getWriter().print(JSON.toJSONString(result));return false;}return true;}
}
将拦截器加入配置
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {@Autowiredprivate LoginInterceptor loginInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry){//拦截所有除了/login /swagger*/** /errorregistry.addInterceptor(loginInterceptor).addPathPatterns("/**").excludePathPatterns("/login").excludePathPatterns("/swagger*/**").excludePathPatterns("/error");}}
定时任务
springboot 自带实现
在启动类上添加注解 @EnableScheduling//开启定时任务
在 ServiceImpl 具体方法上添加 @Scheduled
//开启定时 每月第一天 12 点执行 @Scheduled(cron = "0 0 12 1 * ?")
任务开启,关闭,线程实现
Controller
/*** @ClassName DynamicTaskController**/
@Api(tags = "定时任务")
@RestController
@CrossOrigin
@RequestMapping("task")
public class DynamicTaskController {@Autowiredprivate ThreadPoolTaskScheduler threadPoolTaskScheduler; //任务线程池@Autowiredprivate Scheme2Mapper scheme2Mapper;private Map<Long,ScheduledFuture<?>> taskMap = new HashMap<>();@Beanpublic ThreadPoolTaskScheduler threadPoolTaskScheduler(){return new ThreadPoolTaskScheduler();}@PostMapping("startCron")@ApiOperation("开始定时任务")public Result startCron(@RequestBody TaskParms taskParms) throws InterruptedException {String task = taskParms.getTask();Long corn = taskParms.getCorn();ScheduledFuture<?> schedule = threadPoolTaskScheduler.schedule(new MyRunable1(task), new Trigger() {//定时任务触发器@Overridepublic Date nextExecutionTime(TriggerContext triggerContext) {
// return new CronTrigger(corn).nextExecutionTime(triggerContext);
// return new PeriodicTrigger(2, TimeUnit.SECONDS).nextExecutionTime(triggerContext);return new PeriodicTrigger(corn, TimeUnit.HOURS).nextExecutionTime(triggerContext);}});List<String> response_list = MyRunable1.response_list;//执行信息列表//修改 方案状态Scheme2 scheme2 = scheme2Mapper.selectById(taskParms.getId());scheme2.setStatus(1);//方案 定时scheme2.setCorn(corn);scheme2Mapper.updateById(scheme2);// taskParms.getId() 必须唯一taskMap.put(taskParms.getId(),schedule);return Result.success();}@PostMapping("stopCron")@ApiOperation("关闭定时任务")public Result stopCron(@RequestParam("id") Long id) {if (taskMap.get(id) != null) {taskMap.get(id).cancel(true);//定时任务关闭}//修改 方案状态Scheme2 scheme2 = scheme2Mapper.selectById(id);scheme2.setStatus(0);scheme2Mapper.updateById(scheme2);taskMap.remove(id);return Result.success();}}
具体任务 MyRunable1
/*** @ClassName MyRunable1* 定时任务1**/
public class MyRunable1 implements Runnable{@Autowiredprivate SiteMapper siteMapper;public static List<String> response_list;private static String task;public MyRunable1(String task1) {this.task = task1;}@Overridepublic void run() {。。。。//任务内容}
}
事务处理
- 在启动类上添加注解 @EnableTransactionManagement//事务管理
- 在 ServiceImpl 具体方法上添加 @Transactional//开启事务
JWT生成工具类
依赖
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency>
package com.test.spider.utils;import io.jsonwebtoken.Jwt;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;import java.util.Date;
import java.util.HashMap;
import java.util.Map;public class JWTUtils {//秘钥private static final String jwtToken = "654123yqwe!@#$$";public static String createToken(Long userId){Map<String,Object> claims = new HashMap<>();claims.put("userId",userId);JwtBuilder jwtBuilder = Jwts.builder().signWith(SignatureAlgorithm.HS256, jwtToken) // 签发算法,秘钥为jwtToken.setClaims(claims) // body数据,要唯一,自行设置.setIssuedAt(new Date()) // 设置签发时间.setExpiration(new Date(System.currentTimeMillis() + 24 * 60 * 60 * 60 * 1000));// 一天的有效时间String token = jwtBuilder.compact();return token;}public static Map<String, Object> checkToken(String token){try {Jwt parse = Jwts.parser().setSigningKey(jwtToken).parse(token);return (Map<String, Object>) parse.getBody();}catch (Exception e){e.printStackTrace();}return null;}public static void main(String[] args) {//生成tokenString token = JWTUtils.createToken(100L);System.out.println(token);//获取token中的用户idMap<String, Object> map = JWTUtils.checkToken(token);System.out.println(map.get("userId"));}
}
设置全局返回结果
Result
import lombok.AllArgsConstructor;
import lombok.Data;/*** @ClassName Result* @Description 定义全局返回结果**/
@Data
@AllArgsConstructor//使用后添加一个构造函数,该构造函数含有所有已声明字段属性参数
public class Result {private boolean success;private int code;private String msg;private Object data;public static Result success(Object data){return new Result(true,200,"success",data);}public static Result success(){return new Result(true,200,"success",null);}public static Result success(String msg){return new Result(true,200,msg,null);}public static Result fail(int code,String msg){return new Result(false,code,msg,null);}}
ErrorCode
public enum ErrorCode {PARAMS_ERROR(10001,"参数有误"),ACCOUNT_PWD_NOT_EXIST(10002,"用户名或密码错误"),TOKEN_ERROR(10003,"token不合法"),ACCOUNT_EXIST(10004,"账号已存在"),PARAMS_NOEXIST(10007,"参数不存在"),ACCOUNT_PWD_NOT_NULL(10005,"账户或密码不能为空"),ACCOUNT_FORBIDDEN(10006,"用户被禁用"),ARTICLE_REPORT_ERROR(30001,"文章已上报"),ARTICLE_WARN_ERROR(40001,"文章已预警"),NO_PERMISSION(70001,"无访问权限"),SESSION_TIME_OUT(90001,"会话超时"),NO_LOGIN(90002,"未登录"),SYSTENM_ERROR(-999,"系统异常");private int code;private String msg;ErrorCode(int code, String msg){this.code = code;this.msg = msg;}public int getCode() {return code;}public void setCode(int code) {this.code = code;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}
}
设置统一异常处理
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
/*** @ClassName AllExceptionHandler* @Description 统一异常处理**/
@ControllerAdvice
public class AllExceptionHandler {//进行异常处理,处理Exception.class的异常@ExceptionHandler(Exception.class)@ResponseBodypublic Result doException(Exception ex){return Result.fail(ErrorCode.SYSTENM_ERROR.getCode(), ErrorCode.SYSTENM_ERROR.getMsg());}
}
MD5加密
import org.apache.commons.codec.digest.DigestUtils;
password = DigestUtils.md5Hex(password+slat);//salt 加密盐
连接redis
依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>
配置
spring:redis:port: 63792host: 127.0.0.1password: 123456
使用
@Autowiredprivate RedisTemplate<String,String> redisTemplate;//存入redis redisTemplate.opsForValue().set("TOKEN_"+token, JSON.toJSONString(sysUser),1, TimeUnit.DAYS);//设置过期时间1天//从redis中取出String userJson = redisTemplate.opsForValue().get("TOKEN_"+token)//redis 删除对应的keyredisTemplate.delete("TOKEN_"+token);
json 与对象转换
//将 对象转化为 json 字符串
String s = JSON.toJSONString(sysUser);
//将 string 转化为 对象
SysUser sysUser = JSON.parseObject(userJson,SysUser.class);
后端接收前端 数据
接收json 数据 进行解析
通用方式一
{"enterprise": {"code": "qwerr","id": 10000,"name": "xx"},"first_name": "张","last_name": "三","mail": "xx.com","phone": "1111111"
}
单格式的JSON如上,后端接收接收json字符串的时候使用(@RequestBody String data) String类型,然后用JSONObject转换成对应的实体类 给逻辑层去处理。
import com.alibaba.fastjson.JSONObject;public Result login(@RequestBody JSONObject data){//获得mailString mail = (String) data.get("mail");//获得 nameHashMap<String,String> enterprise = (HashMap)data.get("enterprise");String name = enterprise.get("name");
方式二
创建实体类 使用实体对象接收
public Result list(@RequestBody ArticleListParms articleListParms)
接收路径上数据
@GetMapping("/{id}")public Result queryArticleById(@PathVariable("id") Long id)
接收表单数据
@PostMapping("deleteBatch")public Result deleteBatchIds(@RequestParam("ids") String ids )
接收请求头数据
public Result logout(@RequestHeader("Authorization") String token)
springboot总结(一)相关推荐
- 继承WebMvcConfigurer 和 WebMvcConfigurerAdapter类依然CORS报错? springboot 两种方式稳定解决跨域问题
继承WebMvcConfigurer 和 WebMvcConfigurerAdapter类依然CORS报错???springboot 两种方式稳定解决跨域问题! 之前我写了一篇文章,来解决CORS报错 ...
- Dockerfile springboot项目拿走即用,将yml配置文件从外部挂入容器
Dockerfile 将springboot项目jar包打成镜像,并将yml配置文件外挂. # 以一个镜像为基础,在其上进行定制.就像我们之前运行了一个 nginx 镜像的容器,再进行修改一样,基础镜 ...
- SpringBoot部署脚本,拿走即用!
一个可以直接拿来使用的shell脚本,适用于springboot项目 #!/bin/bash # 这里可替换为你自己的执行程序,其他代码无需更改,绝对路径相对路径均可. # 若使用jenkins等工具 ...
- SpringBoot项目使用nacos,kotlin使用nacos,java项目使用nacos,gradle项目使用nacos,maven项目使用nacos
SpringBoot项目使用nacos kotlin demo见Gitte 一.引入依赖 提示:这里推荐使用2.2.3版本,springboot与nacos的依赖需要版本相同,否则会报错. maven ...
- springboot整合swagger2之最佳实践
来源:https://blog.lqdev.cn/2018/07/21/springboot/chapter-ten/ Swagger是一款RESTful接口的文档在线自动生成.功能测试功能框架. 一 ...
- SpringBoot中实现quartz定时任务
Quartz整合到SpringBoot(持久化到数据库) 背景 最近完成了一个小的后台管理系统的权限部分,想着要扩充点东西,并且刚好就完成了一个自动疫情填报系统,但是使用的定时任务是静态的,非常不利于 ...
- Springboot 利用AOP编程实现切面日志
前言 踏入Springboot这个坑,你就别想再跳出来.这个自动配置确实是非常地舒服,帮助我们减少了很多的工作.使得编写业务代码的时间占比相对更大.那么这里就讲一下面向切面的日志收集.笔者使用lomb ...
- 【Springboot】日志
springBoot日志 1.目前市面上的日志框架: 日志门面 (日志的抽象层): JCL(Jakarta Commons Logging) ...
- 【springboot】配置
配置文件 SpringBoot使用一个全局的配置文件,配置文件名是固定的: •application.properties •application.yml 配置文件的作用:修改SpringBoot自 ...
- 【springboot】入门
简介: springBoot是spring团队为了整合spring全家桶中的系列框架做研究出来的一个轻量级框架.随着spring4.0推出而推出,springBoot可以説是J2SEE的一站式解决方案 ...
最新文章
- 力扣——所有可能的满二叉树
- go git 安装配置与使用 (windows 7 64bit)
- leetcode 654. 构造最大二叉树 思考分析
- python vba 秒出结果_为什么公司每天用20个人手工处理数据出报告,也不用5个会vba,python的人来制作??...
- 村庄规划用途管制的相关内容
- Hibernate读书笔记---继承映射
- Globle Get 多线程下载系统
- 卸载精灵(bue directx) r4.0 完美版 绿色
- 个人简介之物理层安全
- 自建服务器部署WEB网站可公网访问
- 2019-08-01软件工程总结
- 基于php的外卖订餐系统开题报告_校园网上订餐系统的设计与实现(PHP,MySQL)
- 【新年福利】2019年值得一用的8款协作工具
- 编译make px4_fmu-v2_default upload时,报错ERROR Board can accept larger flash images (2080768 bytes)
- Gazebo機器人仿真學習探索筆記(七)连接ROS
- list与tuple
- kml文件转成cvs_如何将excel转换成kml
- IDEA 如何查看 class 文件反编译后的内容
- 计算机毕业设计Java学生学籍信息管理系统(源码+系统+mysql数据库+lw文档)
- USB接口无法识别设备