
 编辑
编辑
springboot快速入门一篇文章全
 springboot01、基本配置
springboot简介
 
 Spring Boot 为简化 Spring 应用开发而生,Spring Boot 中的 Boot 一词,即为快速启动的意思。Spring Boot 可以在零配置情况下一键启动,简洁而优雅。
 
 为了让 Spring 开发者痛快到底,Spring 团队做了以下设计:
 
  
  - 简化依赖,提供整合的依赖项,告别逐一添加依赖项的烦恼;
- 简化配置,提供约定俗成的默认配置,告别编写各种配置的繁琐;
- 简化部署,内置 servlet 容器,开发时一键即运行。可打包为 jar 文件,部署时一行命令即启动;
- 简化监控,提供简单方便的运行监控方式。
基于以上设计目的,Spring 团队推出了 Spring Boot 。
 
目录
1、pom.xml
2、项目层次
3、启动文件【com.item/Action.java】
4、controller文件
5、启动测试(数据是跨域的)
1、pom.xml
2、项目层次
3、启动文件【com.item/Action.java】
4、controller文件
其中@RestController = @Controller + @ResponseBody;
5、启动测试(数据是跨域的)

 编辑
编辑
访问路径:【http://127.0.0.1:8080/GetInfo】

 编辑
编辑
 springboot02、打war包
Spring Boot 打包为 war 并运行
 
 将 Spring Boot 打包为 war ,然后放置于 Tomcat 的 webapps 目录下加载运行,接下来我们就详细描述下打包为 war 的过程。
 
目录
1、修改打包方式
2、修改启动文件【Action.java】
3、打包命令
4、打包效果:
1、修改打包方式
在【pom.xml】文件中修改默认的打包方式,显式指定打包方式为 war。

 编辑
编辑
由于 Spring Boot 内置了 Tomcat ,所以我们在打包时需要排除内置的 Tomcat ,这样可以避免内置 Tomcat 和 war 包部署运行的 Tomcat 产生冲突。在 pom.xml 中添加如下依赖即可:

 编辑
编辑
2、修改启动文件【Action.java】
3、打包命令
项目路径中打开【cmd】并执行

 编辑
编辑
4、打包效果:
 
 使用 mvn clean package -Dmaven.test.skip=true 命令打包应用了,运行命令后会在 target 目录下生成 war 文件,将该文件放置于 Tomcat 的 webapps 目录下运行即可。
 

 编辑
编辑
前后端分离部署的方式,更能发挥服务器的性能,如果要进行版本升级,直接替换后端war包就OK。
springboot03、实现mybatis
目录
1、pom引包
2、数据源配置application.properties
3、model对应数据库的类Users
4、dao层·需要加上@Repository注解
5、添加映射文件UsersMapper.xml
6、service层编码
7、serviceimpl层编码
8、Controller层编码
9、测试效果:
1、pom引包
2、数据源配置application.properties
 
 Spring Boot 会将数据源自动注入到 MyBatis 的 sqlSessionFactory 组件中。对于我们开发者来说,这一切都是自动实现的,非常简单。
 
3、model对应数据库的类Users
4、dao层·需要加上@Repository注解
5、添加映射文件UsersMapper.xml
6、service层编码
7、serviceimpl层编码
8、Controller层编码
备注:dao层引入
9、测试效果:
可以使用postman测试:

 编辑
编辑
效果很明显,成功了。
StringUtils判断字符串是否为空
 可以直接看到测试效果,无论是null还是""都是空。
StringUtils依赖包:
StringUtils测试编码:
StringUtils测试效果:

 编辑
编辑
 springboot04、swagger配置
前言:
 
 springboot的swagger配置与SSM稍微有些不同,SSM对2.9.0以上的兼容性很差,但是springboot就可以使用2.9.0以上的包了,其实区别不算太大,除了能对对象直接操作外就是页面更清爽了。
 
目录
1、pom依赖
2、swagger配置文件
3、接口api写法
4、启动效果:【http://127.0.0.1:8088/swagger-ui.html】
5、使用方法
编辑
6、可能出现的异常总结:
1、pom依赖
2、swagger配置文件
这里单独创建了一个包【com.item.swagger】来放置swagger的配置文件
需要注意的是:【com.item.controller】这里需要改成自己的包位置。
3、接口api写法
我写了一套的注释方法,一目了然
 
 package com.item.controller;
import com.item.model.Users;
import com.item.service.UsersService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
@Api("用户操作接口")
@RestController
@CrossOrigin
public class UsersController {
    @Autowired
    private UsersService usersService;
    /**
     * 获取所有信息
     * @return
     */
    @GetMapping("/GetInfoApi")
    @ApiOperation(value = "获取信息",notes = "没啥留言的")
    public Object GetInfoApi(){
        List<Users> list=usersService.GetInfo();
        HashMap<String,Object> map=new HashMap<String,Object>();
        map.put("state",true);
        map.put("msg","成功");
        map.put("result",list);
        return map;
    }
    @GetMapping("/GetName")
    @ApiOperation(value = "获取信息",notes = "没啥留言的")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "nickName",required = true,paramType = "query",dataType = "String",value = "通过昵称模糊查询")
    })
    public Object GetName(HttpServletRequest request,Model model){
        String nickName = request.getParameter("nickName");
        List<Users> list=usersService.SelectName(nickName);
        HashMap<String,Object> map=new HashMap<String,Object>();
        map.put("state",true);
        map.put("msg","成功");
        map.put("result",list);
        return map;
    }
    /**
     * 添加信息
     * @param userName
     * @param pwd
     * @param nickName
     * @return
     */
    @PostMapping(value = "/UserAddInfoApi")
    @ApiOperation(value = "添加",notes = "没啥留言的")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userName",required = true,paramType = "query",dataType = "String",value = "用户名"),
            @ApiImplicitParam(name = "pwd",required = true,paramType = "query",dataType = "String",value = "密码"),
            @ApiImplicitParam(name = "nickName",required = true,paramType = "query",dataType = "String",value = "昵称")
    })
    public Object UserAddInfoApi(String userName,String pwd,String nickName){
        HashMap<String,Object> map=new HashMap<String,Object>();
        if(
                StringUtils.isEmpty(userName)||
                StringUtils.isEmpty(pwd)||
                StringUtils.isEmpty(nickName)
        ){
            map.put("state",false);
            map.put("msg","参数不润许为空");
            map.put("result","");
            return map;
        }
        usersService.UsersAddInfo(userName, pwd, nickName);
        map.put("state",true);
        map.put("msg","成功");
        map.put("result","");
        return map;
    }
    /**
     * 单个查询
     * @param id
     * @return
     */
    @GetMapping("/UsersSelectById")
    @ApiOperation(value = "id查询",notes = "没啥留言的")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id",required = true,paramType = "query",dataType = "String",value = "编号")
    })
    public Object UsersSelectById(String id){
        Users users = usersService.UsersSelectById(Integer.parseInt(id));
        HashMap<String,Object> map=new HashMap<String,Object>();
        map.put("state",true);
        map.put("msg","成功");
        map.put("result",users);
        return map;
    }
    /**
     * 修改api
     * @param id
     * @param pwd
     * @return
     */
    @PostMapping(value = "/UserUpdateInfoApi")
    @ApiOperation(value = "添加",notes = "没啥留言的")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id",required = true,paramType = "query",dataType = "String",value = "编号"),
            @ApiImplicitParam(name = "pwd",required = true,paramType = "query",dataType = "String",value = "密码"),
    })
    public Object UserUpdateInfoApi(String id,String pwd){
        usersService.UsersUpdateInfo(pwd,Integer.parseInt(id));
        HashMap<String,Object> map=new HashMap<String,Object>();
        map.put("state",true);
        map.put("msg","成功");
        map.put("result","");
        return map;
    }
    /**
     * 删除api
     * @param id
     * @return
     */
    @GetMapping(value = "/UsersDeleteById")
    @ApiOperation(value = "根据id删除",notes = "没啥留言的")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id",required = true,paramType = "query",dataType = "String",value = "编号")
    })
    public Object UsersDeleteById(String id){
        usersService.UsersDeleteById(Integer.parseInt(id));
        HashMap<String,Object> map=new HashMap<String,Object>();
        map.put("state",true);
        map.put("msg","成功");
        map.put("result","");
        return map;
    }
}
  
 
这里为了看着方便,我将服务路径改为了【/】

 编辑
编辑
5、使用方法

 编辑
编辑

 编辑
编辑

 编辑
编辑
POST的也类似

 编辑
编辑

 编辑
编辑
6、可能出现的异常总结:
1、SwaggerConfig的配置文件中忘记写注解,就2个注解:
2、接口中的注解:
3、没有明确接口的访问类型,导致出现一堆的同名不同访问类型的接口提示。
使用@GetMapping或者@PostMapping就可以解决此问题。
 springboot05、封装结果集
不可能一直用map写数据返回,很麻烦的,那么咱们就可以进行一次封装此次使用。
目录
springboot05、封装结果集
创建【com.item.res】包
注意问题
编辑一个SUCCESS类和ERROR类,他们都有state、msg、result,那么就创建一个公用的父类base。
创建【com.item.res】包
Base:
ERROR:
SUCCESS:
返回修改:
 
 package com.item.controller;
import com.item.model.Users;
import com.item.res.ERROR;
import com.item.res.SUCCESS;
import com.item.service.UsersService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
@Api("用户操作接口")
@RestController
@CrossOrigin
public class UsersController {
    @Autowired
    private UsersService usersService;
    /**
     * 获取所有信息
     * @return
     */
    @GetMapping("/GetInfoApi")
    @ApiOperation(value = "获取信息",notes = "没啥留言的")
    public Object GetInfoApi(){
        List<Users> list=usersService.GetInfo();
        return new SUCCESS(list);
    }
    @GetMapping("/GetName")
    @ApiOperation(value = "获取信息",notes = "没啥留言的")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "nickName",required = true,paramType = "query",dataType = "String",value = "通过昵称模糊查询")
    })
    public Object GetName(HttpServletRequest request,Model model){
        String nickName = request.getParameter("nickName");
        List<Users> list=usersService.SelectName(nickName);
        return new SUCCESS(list);
    }
    /**
     * 添加信息
     * @param userName
     * @param pwd
     * @param nickName
     * @return
     */
    @PostMapping(value = "/UserAddInfoApi")
    @ApiOperation(value = "添加",notes = "没啥留言的")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userName",required = true,paramType = "query",dataType = "String",value = "用户名"),
            @ApiImplicitParam(name = "pwd",required = true,paramType = "query",dataType = "String",value = "密码"),
            @ApiImplicitParam(name = "nickName",required = true,paramType = "query",dataType = "String",value = "昵称")
    })
    public Object UserAddInfoApi(String userName,String pwd,String nickName){
        HashMap<String,Object> map=new HashMap<String,Object>();
        if(
                StringUtils.isEmpty(userName)||
                StringUtils.isEmpty(pwd)||
                StringUtils.isEmpty(nickName)
        ){
            return new ERROR("参数为空","参数错误");
        }
        usersService.UsersAddInfo(userName, pwd, nickName);
        return new SUCCESS("添加成功");
    }
    /**
     * 单个查询
     * @param id
     * @return
     */
    @GetMapping("/UsersSelectById")
    @ApiOperation(value = "id查询",notes = "没啥留言的")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id",required = true,paramType = "query",dataType = "String",value = "编号")
    })
    public Object UsersSelectById(String id){
        Users users = usersService.UsersSelectById(Integer.parseInt(id));
        HashMap<String,Object> map=new HashMap<String,Object>();
        map.put("state",true);
        map.put("msg","成功");
        map.put("result",users);
        return map;
    }
    /**
     * 修改api
     * @param id
     * @param pwd
     * @return
     */
    @PostMapping(value = "/UserUpdateInfoApi")
    @ApiOperation(value = "添加",notes = "没啥留言的")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id",required = true,paramType = "query",dataType = "String",value = "编号"),
            @ApiImplicitParam(name = "pwd",required = true,paramType = "query",dataType = "String",value = "密码"),
    })
    public Object UserUpdateInfoApi(String id,String pwd){
        usersService.UsersUpdateInfo(pwd,Integer.parseInt(id));
        HashMap<String,Object> map=new HashMap<String,Object>();
        map.put("state",true);
        map.put("msg","成功");
        map.put("result","");
        return map;
    }
    /**
     * 删除api
     * @param id
     * @return
     */
    @GetMapping(value = "/UsersDeleteById")
    @ApiOperation(value = "根据id删除",notes = "没啥留言的")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id",required = true,paramType = "query",dataType = "String",value = "编号")
    })
    public Object UsersDeleteById(String id){
        usersService.UsersDeleteById(Integer.parseInt(id));
        HashMap<String,Object> map=new HashMap<String,Object>();
        map.put("state",true);
        map.put("msg","成功");
        map.put("result","");
        return map;
    }
}
  
 
使用swagger访问测试返回效果如下:

 编辑
编辑
设置完成。 
注意问题:
每个人的习惯方式均不同,需要看看公司具体用什么方式:
也可能是这样返回:
{
“code”: -9999,
“message”: “Invalid Request”,
“data”:{ }
}
注意:无论是【ERROR】还是【SUCCESS】他们的返回结果都需要一致,否则前端在处理的时候就会很麻烦,对是一套解析,错又是一套解析,很麻烦。
例如:
正确返回:
错误返回:
这就没法玩了。。。。 会挨骂的。
避免层级过深的URI
/ 在url中表达层级,用于按实体关联关系进行对象导航,一般根据id导航。
过深的导航容易导致url膨胀,不易维护,如 GET /zoos/1/areas/3/animals/4,尽量使用查询参数代替路劲中的实体导航,如GET /animals?zoo=1&area=3。
结果过滤,排序,搜索
url最好越简短越好,对结果过滤、排序、搜索相关的功能都应该通过参数实现。
过滤:例如你想限制GET /tickets 的返回结果:只返回那些open状态的ticket, GET /tickets?state=open 这里的state就是过滤参数。
排序:和过滤一样,一个好的排序参数应该能够描述排序规则,而不和业务相关。复杂的排序规则应该通过组合实现。排序参数通过 , 分隔,排序参数前加 - 表示降序排列。
 springboot06、log4j2日志配置
目录
前言:
1、pom配置
2、log4j2-spring.xml配置文件
3、在application.properties中引入log4j2的配置
4、log4j使用
前言:
 
 日志接口(slf4j)
 
 slf4j是对所有日志框架制定的一种规范、标准、接口,并不是一个框架的具体的实现,因为接口并不能独立使用,需要和具体的日志框架实现配合使用(如log4j、logback)。
 
 接口用于定制规范,可以有多个实现,使用时是面向接口的(导入的包都是slf4j的包而不是具体某个日志框架中的包),即直接和接口交互,不直接使用实现,所以可以任意的更换实现而不用更改代码中的日志相关代码。
 
 
 
 日志实现(log4j、logback、log4j2)
 
 Log4j:Apache的一个开源项目,可以控制日志信息输送的目的地是控制台、文件、GUI组件等,可以控制每一条日志的输出格式,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。虽然已经停止维护了,但目前绝大部分企业都是用的log4j。
 
 LogBack:logback同样是由log4j的作者设计完成的,拥有更好的特性,用来取代log4j的一个日志框架,是slf4j的原生实现。
 
 Log4j2:Log4j2是log4j 1.x和logback的改进版,据说采用了一些新技术(无锁异步、等等),使得日志的吞吐量、性能比log4j 1.x提高10倍,并解决了一些死锁的bug,而且配置更加简单灵活。
 
1、pom配置
2、log4j2-spring.xml配置文件
我精简了配置,只输出到控制台。
3、在application.properties中引入log4j2的配置
4、log4j使用
包:
声明:
使用:
效果:

 编辑
编辑
 springboot07、task定时任务
定时任务的概述
 
 在项目中开发定时任务应该是一种比较常见的需求,在Java中开发定时任务主要有三种方案:一是使用JDK自带的Timer,二是使用第三方组件Quartz',三是使用Spring Task。
 
 Timer是JDK自带的定时任务工具,其简单易用,但是对于复杂的定时规则无法满足,在实际项目开发中也很少使用到,Quartz功能强大,但是使用起来相对笨重,而Spring Task则具备了前两者之间的优点,使用起来简单,除Spring 相关的包外不需要额外的包,而且支持注解和配置文件两种形式。
 
 所以咱们这里使用springboot的task,相对方便、快捷、高效。
 
1、启动类上添加@EnableScheduling
2、创建测试包【com.item.task】
2.1fixedRate定时
2.2cron定时
Cron表达式
 
 cronExpression表达式有至少6个由空格分隔的时间元素,从左往右,这些元素的定义如下:
 
 秒,分,时,月份中的日期,月份,星期,年份
 
 字段 允许值 允许的特殊字符 
秒 0-59 , - * / 
分 0-59 , - * / 
小时 0-23 , - * / 
日期 1-31 , - * ? / L W C 
月份 1-12 或者 JAN-DEC , - * / 
星期 1-7 或者 SUN-SAT , - * ? / L C # 
年(可选) 留空, 1970-2099 , - * / 
 
 * 表示所有值; 
? 表示未说明的值,即不关心它为何值; 
- 表示一个指定的范围; 
, 表示附加一个可能值; 
/ 符号前表示开始时间,符号后表示每次递增的值; 
 
常用定时:
 
 每隔5秒执行一次任务:  "*/5 * * * * ?"
 
每隔1分钟执行一次任务:  "0 */1 * * * ?"
 
每天23点执行一次任务:  "0 0 23 * * ?"
 
每天凌晨1点执行一次任务:  "0 0 1 * * ?"
 
每月1号凌晨1点执行一次任务:  "0 0 1 1 * ?"
 
每月1号凌晨2点执行一次任务:  "0 0 2 1 * ? *"
 
每月最后一天23点执行一次任务:  "0 0 23 L * ?"
 
每周星期天凌晨1点执行一次任务:  "0 0 1 ? * L"
 
效果:

 编辑
编辑
springboot08、拦截器HandlerInterceptor
前言
 
 拦截器这个名词定义的非常形象,就像导弹要攻击目标的时候,可能会被先进的反导系统拦截,此处的反导系统就是一种拦截器。
 
 我们开发的应用,对外暴露的是控制器中定义的 API 方法,我们可以在 API 方法的外围放置拦截器,所有对 API 的访问都可以通过拦截器进行过滤。
 
 OK,那么这样的拦截有什么意义吗,其实已经很明显了,反导系统可以保护目标的安全并识别对目标的攻击行为。同理,拦截器可以跟踪对应用的访问行为,对合法访问行为予以放行,对非法访问行为予以拒绝。怎么样,是不是很牛,接下来咱们就在 Spring Boot 项目中具体实现下。
 
1、创建拦截器【com.item.handler】
通过【request】可以获取任何值
 
 在上面的实例中,我们定义了一个拦截器类 MyInterceptor ,通过实现 HandlerInterceptor 接口,该类具备了拦截器的功能。
 
 MyInterceptor 中的方法执行顺序为 preHandle – Controller 方法 – postHandle – afterCompletion ,所以拦截器实际上可以对 Controller 方法执行前后进行拦截监控。
 
 最后还有一个非常重要的注意点, preHandle 需要返回布尔类型的值。 preHandle 返回 true 时,对控制器方法的请求才能到达控制器,继而到达 postHandle 和 afterCompletion 方法;如果 preHandle 返回 false ,后面的方法都不会执行。
 
2、生效配置【com.item.handler】内创建【WebConfig】
如果想让配置器生效,还需要通过配置类进行相应配置。
3、拦截器效果: 

 编辑
编辑
4、拦截器作用
主要完成请求参数的解析、将页面表单参数赋给值栈中相应属性、执行功能检验、程序异常调试等工作,例如:登录校验、Token验证等。
springboot09、监控
前言
因为公司开发的项目多、为客户部署的项目实例多。工作中我们都会经常遇到,由于某个客户的项目突然无法访问,一堆研发、售后部门的同事火急火燎处理问题的场景。
 
  
  - 能够有一个界面,监控所有关注的项目实例运行状态。
- 对于某个项目实例来说,可以监控该实例的各项运行参数,例如内存占用情况、磁盘使用情况、数据库连接情况。
利用 Spring Boot Admin 实现可视化监控,此时至少需要两个项目实例,一个是监控的管理端,一个是被监控的客户端。
 
 注:会与swagger冲突。这个功能是在上线后使用,所以注意关闭swagger。
 
目录
前言
1、pom配置
2、启动项配置
3、访问主页
4、客户端pom依赖:
5、修改客户端配置
1、pom配置
2、启动项配置
3、访问主页
根据端口号访问就行【http://127.0.0.1:8088/】

 编辑
编辑
4、客户端pom依赖:
5、修改客户端配置

 编辑
编辑
启动client_test,可以看到应用是1了,可以多启动几个,都能看到

 编辑
编辑
点击进去:

 编辑
编辑

 编辑
编辑
多弄几个效果还是很明显的。
 springboot10、AOP
前言
 
 Spring 最重要的两个功能,就是依赖注入和面向切面编程(AOP)。
 
 AOP 为我们提供了处理问题的全局化视角,使用得当可以极大提高编程效率。
 
 Spring Boot 中使用 AOP 与 Spring 中使用 AOP 几乎没有什么区别,只是建议尽量使用 Java 配置代替 XML 配置。
 
目录
编辑springboot09、AOP
前言
1、pom依赖
2、AOP控制器【com.item.aop】
3、测试apo效果
4、使用 AOP 监控性能
1、pom依赖
2、AOP控制器【com.item.aop】
3、测试apo效果
可以根据返回的路径进行接口控制

 编辑
编辑
4、使用 AOP 监控性能
在研发项目的性能测试阶段,或者项目部署后,我们会希望查看服务层方法执行的时间。以便精准的了解项目中哪些服务方法执行速度慢,后续可以针对性的进行性能优化。
此时我们就可以使用 AOP 的环绕通知,监控服务方法的执行时间。

 编辑
编辑
springboot11、redis
前言
 
 redis可以说是现在最火的非关系型数据库,主要是它处理数据的能力是真的很强。就说win环境的处理能力一般的机器也能在每秒3万次以上,已经很厉害了。我们一般的几万用户的APP根本不需要集群,一个Redis即可搞定几乎所有的小规模并发性问题了。
 
资源地址:redis服务(windows版)&redis可视化工具.rar_asp.netcoreredis-.Net文档类资源-CSDN下载
目录
1、pom依赖
2、配置声明(application.properties中)
3、编写配置文件【com.item.redis】
4、操作提示
5、RedisBase编码(只包含字符串处理)
6、创建测试接口【com.item.controller】内
7、编写redis层级【com.item.Base】
8、启动测试http://127.0.0.1:8088/swagger-ui.htm
1、pom依赖
2、配置声明(application.properties中)
3、编写配置文件【com.item.redis】
中间有输出语句就是为了表现配置成功,可以删掉。
4、操作提示
5、RedisBase编码(只包含字符串处理)
6、创建测试接口【com.item.controller】内
7、编写redis层级【com.item.Base】

 编辑
编辑

 编辑
编辑

 编辑
编辑
能写入,能查询,没问题。 
我个人喜欢用String和list,自己用自己封装吧。
         
        
评论(0)