Springboot开发常用技术

目录

一、springboot返回Jsonson对象

二、springboot使用devtools进行热部署

三、springboot资源文件属性配置

四、springboot整合模板引擎

五、springboot异常处理

六、springboot整合mybatis

七、springboot整合redis

八、springboot整合定时任务

九、springboot整合异步任务及使用场景

十、springboot使用拦截器

 


一、springboot返回Jsonson对象

1、新建用户对象,其中密码password字段设置不返回显示,日期字段返回字符串,如下图所示

package com.example.entity;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;

import java.util.Date;

/**
 * TODO
 *
 * @author Andy
 * @date 2021/4/11 13:14
 */
@Data
public class User {
    private String name;
    @JsonIgnore
    private String password;
    private Integer age;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date birthday;
    private String desc;
}

2、新建测试controller

package com.example.controller;

import com.example.entity.User;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;

/**
 * TODO
 *
 * @author Andy
 * @date 2021/4/11 13:13
 */
@RestController
@RequestMapping("/user")
public class UserController {


    @RequestMapping("/info")
    @ResponseBody
    public User getUserInfo(){
        User user = new User();
        user.setAge(29);
        user.setName("andy");
        user.setBirthday(new Date());
        user.setPassword("123456");
        return user;
    }

}

3、启动并访问路径

从返回结果可以看出,用户对象中并没有返回密码属性,同时日期格式按照我们制定的规则进行了转换

二、springboot使用devtools进行热部署

1、添加devtools依赖

2、添加以下配置

(1)application.properties

(2)开启自动编译

当我们修改了类文件后,idea不会自动编译,得修改idea设置。

(a)File-Settings-Compiler-Build Project automatically


(b)ctrl + shift + alt + / ,选择Registry,勾上 Compiler autoMake allow when app running

(3)修改configuration

都配置完成后重启测试,不重启情况下修改文件

再次访问:

说明热部署配置已成功!

 

三、springboot资源文件属性配置

1、资源文件属性配置

(1) pom.xml添加相应依赖

(2) 创建资源文件qiniufile.peoperties

(3) 创建实体对象QiniuFile,并添加相应注解

package com.example.util;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

/**
 * TODO
 *
 * @author Andy
 * @date 2021/4/11 13:59
 */
@Configuration
@ConfigurationProperties(prefix="com.example.qiniufile")
@PropertySource(value="classpath:qiniufile.properties")
@Data
public class QiniuFile {
    private String accesstoken;
    private String key;

}

(4) 用户controller中注入QiniuFile对象,并进行赋值

(5) 访问测试

2、server属性配置

修改application.properties添加如下配置

##########################################################################
#
#Server相关配置
#
##########################################################################
#配置API端口号
server.port=8880
#配置context_path,一般来说,这个配置在正式环境下不配置
server.servlet.context-path=/cms
#配置session最大超时时间
server.session-timeout=60
#该服务绑定IP地址,启动服务器如本机不是该IP地址则抛出异常启动失败
#只有特殊需求的情况下才配置,具体根据各自的业务来设置
server.address=192.168.43.129

配置完成后需要更改访问路径为正确的ip并且上下文路径才能访问:

 

四、springboot整合模板引擎

1、springboot整合themeleaf

(1) 引入依赖

(2) application.peoperties配置

#thymeleaf模板配置
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.content-type=text/html
#关闭缓存,及时刷新,上线生产需改为true
spring.thymeleaf.cache=false

(3) 新建html页面

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
Thyme模板引擎
<h1 th:text="${name}">hello world</h1>
</body>
</html>

 

(4) 新建thymeleafController

package com.example.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * TODO
 * @author Andy
 * @date 2021/4/11 12:58
 */
@Controller
@RequestMapping("th")
public class ThymeleafController {

    @RequestMapping("/index")
    public String index(ModelMap map){
        map.addAttribute("name","andythomas");
        return "thymeleaf/index";
    }
}

需要注意的是这里使用的注解是@Controller,否则会识别不出ModelMap,无法带出传入的值

(5) 启动程序访问

五、springboot异常处理

1、页面跳转形式

(1)新建error.html

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>捕获全局异常</title>
</head>
<body>
    <h1 style="color:red">发生错误:</h1>
    <div th:text="${url}"></div>
    <div th:text="${exception.message}"></div>

</body>
</html>

(2)新增统一异常拦截

添加 @ControllerAdvice注解。

package com.example.exception;

import com.sun.deploy.net.HttpResponse;
import org.springframework.http.HttpRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * TODO
 *
 * @author Andy
 * @date 2021/4/11 15:29
 */
@ControllerAdvice
public class TRSExceptionHandler {
    public static final String TRS_ERROR_VIEW = "thymeleaf/error";


    @ExceptionHandler(value = Exception.class)
    public Object errorHandler(HttpServletRequest request, HttpServletResponse response, Exception e){
        e.printStackTrace();
        ModelAndView mav = new ModelAndView();
        mav.addObject("exception",e);
        mav.addObject("url",request.getRequestURL());
        mav.setViewName(TRS_ERROR_VIEW);
        return mav;
    }
}

启动应用后,被 @ExceptionHandler、@InitBinder、@ModelAttribute 注解的方法,都会作用在 被 @RequestMapping 注解的方法上。

@ModelAttribute:在Model上设置的值,对于所有被 @RequestMapping 注解的方法中,都可以通过 ModelMap 获取

(3)制造异常测试

package com.example.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * TODO
 * @author Andy
 * @date 2021/4/11 12:58
 */
@Controller
@RequestMapping("err")
public class ErrorController {

    @RequestMapping("/error")
    public String error(ModelMap map){
        int a = 1/0;
        return "thymeleaf/error";
    }
}

(4)访问查看效果

2、ajax形式

(1) 新建ajax测试页面ajaxerror.html

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title></title>
    <script th:src="@{https://ajax.aspnetcdn.com/ajax/jquery/jquery-3.5.1.min.js}"></script>
</head>
<body>
    <h1 >测试ajax错误异常</h1>
    <script >
        debugger

        $.ajax({
            url:"/err/getAjaxError",
            type:"POST",
            async:false,
            success:function (data) {
                if(data.status==200 && data.msg=="ok"){
                    alert("success");
                }else{
                    alert("发生异常:"+data.msg);
                }
            }

        });
    </script>

</body>
</html>

(2) 新建ajax处理类

package com.example.exception;

import com.example.entity.TRSJsonResult;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * TODO
 *
 * @author Andy
 * @date 2021/4/11 15:29
 */
@RestControllerAdvice
public class TRSAjaxExceptionHandler {

    @ExceptionHandler(value = Exception.class)
    public TRSJsonResult errorHandler(HttpServletRequest request, HttpServletResponse response, Exception e){
        e.printStackTrace();
        return TRSJsonResult.errorException(e.getMessage());
    }
}

 

(3) 新建异常处理类

package com.example.entity;

import lombok.Data;

/**
 * TODO
 *
 * @author Andy
 * @date 2021/4/11 15:50
 */
@Data
public class TRSJsonResult {
    /**
     * 响应业务状态
     */
    private Integer status;
    /**
     * 响应信息
     */
    private String  msg;
    /**
     * 响应中过的数据
     */
    private Object data;


    public TRSJsonResult() {

    }
    public TRSJsonResult(Object data) {
        this.status = 200;
        this.msg = "OK";
        this.data = data;
    }

    public TRSJsonResult(Integer status, String msg, Object data) {
        this.status = status;
        this.msg = msg;
        this.data = data;
    }

    public static TRSJsonResult errorException(String msg){
        return new TRSJsonResult(555,msg,null);
    }

    public static TRSJsonResult ok(){
        return new TRSJsonResult(null);
    }
}

(4) ErrorController添加入口

package com.example.controller;

import com.example.entity.TRSJsonResult;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

/**
 * TODO
 * @author Andy
 * @date 2021/4/11 12:58
 */
@Controller
@RequestMapping("err")
public class ErrorController {

    @RequestMapping("/error")
    public String error(ModelMap map){
        int a = 1/0;
        return "thymeleaf/error";
    }

    @RequestMapping("/ajax")
    public String ajax(ModelMap map){
        return "thymeleaf/ajaxerror";
    }

    @RequestMapping("/getAjaxError")
    @ResponseBody
    public TRSJsonResult ajaxerror(ModelMap map){
        int a = 1/0;
        return TRSJsonResult.ok();
    }
}

(5)访问测试

可以看出,在调用ajax请求的时候,进入了统一的异常处理

将业务的实际报错返回给了前台页面

3、统一返回异常的形式,兼容web和ajax

(1)改造异常处理

package com.example.exception;

import com.example.entity.TRSJsonResult;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * TODO
 *
 * @author Andy
 * @date 2021/4/11 15:29
 */
@RestControllerAdvice
public class TRSAjaxExceptionHandler {
    public static final String TRS_ERROR_VIEW = "thymeleaf/error";
    @ExceptionHandler(value = Exception.class)
    public Object errorHandler(HttpServletRequest request, HttpServletResponse response, Exception e){
        e.printStackTrace();
//        return TRSJsonResult.errorException(e.getMessage());

        if(isAjax(request)){
            return TRSJsonResult.errorException(e.getMessage());
        }else{
            ModelAndView mav = new ModelAndView();
            mav.addObject("exception",e);
            mav.addObject("url",request.getRequestURL());
            mav.setViewName(TRS_ERROR_VIEW);
            return mav;
        }

    }


    /**
     * 判断是否是ajax请求
     * @param request
     * @return
     */
    public static boolean isAjax(HttpServletRequest request){
        return (request.getHeader("X-Requested-With")!=null&&
                "XMLHttpRequest".equals(request.getHeader("X-Requested-With").toString()));
    }
}

(2)测试

六、springboot整合mybatis

(1)事务隔离级别

所谓事务的传播行为是指,如果在开始当前事务之前,一个事务上下文已经存在,此时有若干选项可以指定一个事务性方法的执行行为。

我们可以看 org.springframework.transaction.annotation.Propagation 枚举类中定义了6个表示传播行为的枚举值:

public enum Propagation {  
    REQUIRED(0),
    SUPPORTS(1),
    MANDATORY(2),
    REQUIRES_NEW(3),
    NOT_SUPPORTED(4),
    NEVER(5),
    NESTED(6);
}
  • REQUIRED :如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
  • SUPPORTS :如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
  • MANDATORY :如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
  • REQUIRES_NEW :创建一个新的事务,如果当前存在事务,则把当前事务挂起。
  • NOT_SUPPORTED :以非事务方式运行,如果当前存在事务,则把当前事务挂起。
  • NEVER :以非事务方式运行,如果当前存在事务,则抛出异常。
  • NESTED :如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于 REQUIRED 。

指定方法:通过使用 propagation 属性设置,例如:

@Transactional(propagation = Propagation.REQUIRED)

(2)测试

对于下图中的写法先插入用户,后发生异常,在删除用户;在没有事务的控制下是不会进行回滚的

所以需要事务来进行控制,对于增删改的加入如下注解

对于查询的话需要加入如下注解

七、springboot整合redis

(1) pom.xml 中引入相关依赖

<!--引入redis依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
<!-- fastjson依赖 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.15</version>
        </dependency>

(2)配置文件中加入redis相关配置

# Redis数据库索引(默认为0)
spring.redis.database=0
# Redis服务器地址
spring.redis.host=127.0.0.1
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=20
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=10
# 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=2
# 连接超时时间(毫秒)
spring.redis.timeout=1000

(3)添加redis工具类

package com.example.util;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * redisTemplate封装
 *  @author Andy
 */
@Component
public class RedisUtil {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;


    /**
     * 指定缓存失效时间
     * @param key 键
     * @param time 时间(秒)
     * @return
     */
    public boolean expire(String key,long time){
        try {
            if(time>0){
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据key 获取过期时间
     * @param key 键 不能为null
     * @return 时间(秒) 返回0代表为永久有效
     */
    public long getExpire(String key){
        return redisTemplate.getExpire(key,TimeUnit.SECONDS);
    }

    /**
     * 判断key是否存在
     * @param key 键
     * @return true 存在 false不存在
     */
    public boolean hasKey(String key){
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 删除缓存
     * @param key 可以传一个值 或多个
     */
    @SuppressWarnings("unchecked")
    public void del(String ... key){
        if(key!=null&&key.length>0){
            if(key.length==1){
                redisTemplate.delete(key[0]);
            }else{
                redisTemplate.delete(CollectionUtils.arrayToList(key));
            }
        }
    }

    //============================String=============================
    /**
     * 普通缓存获取
     * @param key 键
     * @return 值
     */
    public Object get(String key){
        return key==null?null:redisTemplate.opsForValue().get(key);
    }

    /**
     * 普通缓存放入
     * @param key 键
     * @param value 值
     * @return true成功 false失败
     */
    public boolean set(String key,Object value) {
        try {
            redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 普通缓存放入并设置时间
     * @param key 键
     * @param value 值
     * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
     * @return true成功 false 失败
     */
    public boolean set(String key,Object value,long time){
        try {
            if(time>0){
                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            }else{
                set(key, value);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 递增
     * @param key 键
     * @param delta 要增加几(大于0)
     * @return
     */
    public long incr(String key, long delta){
        if(delta<0){
            throw new RuntimeException("递增因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, delta);
    }

    /**
     * 递减
     * @param key 键
     * @param delta 要减少几(小于0)
     * @return
     */
    public long decr(String key, long delta){
        if(delta<0){
            throw new RuntimeException("递减因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, -delta);
    }

    //================================Map=================================
    /**
     * HashGet
     * @param key 键 不能为null
     * @param item 项 不能为null
     * @return 值
     */
    public Object hget(String key,String item){
        return redisTemplate.opsForHash().get(key, item);
    }

    /**
     * 获取hashKey对应的所有键值
     * @param key 键
     * @return 对应的多个键值
     */
    public Map<Object,Object> hmget(String key){
        return redisTemplate.opsForHash().entries(key);
    }

    /**
     * HashSet
     * @param key 键
     * @param map 对应多个键值
     * @return true 成功 false 失败
     */
    public boolean hmset(String key, Map<String,Object> map){
        try {
            redisTemplate.opsForHash().putAll(key, map);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * HashSet 并设置时间
     * @param key 键
     * @param map 对应多个键值
     * @param time 时间(秒)
     * @return true成功 false失败
     */
    public boolean hmset(String key, Map<String,Object> map, long time){
        try {
            redisTemplate.opsForHash().putAll(key, map);
            if(time>0){
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 向一张hash表中放入数据,如果不存在将创建
     * @param key 键
     * @param item 项
     * @param value 值
     * @return true 成功 false失败
     */
    public boolean hset(String key,String item,Object value) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 向一张hash表中放入数据,如果不存在将创建
     * @param key 键
     * @param item 项
     * @param value 值
     * @param time 时间(秒)  注意:如果已存在的hash表有时间,这里将会替换原有的时间
     * @return true 成功 false失败
     */
    public boolean hset(String key,String item,Object value,long time) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            if(time>0){
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 删除hash表中的值
     * @param key 键 不能为null
     * @param item 项 可以使多个 不能为null
     */
    public void hdel(String key, Object... item){
        redisTemplate.opsForHash().delete(key,item);
    }

    /**
     * 判断hash表中是否有该项的值
     * @param key 键 不能为null
     * @param item 项 不能为null
     * @return true 存在 false不存在
     */
    public boolean hHasKey(String key, String item){
        return redisTemplate.opsForHash().hasKey(key, item);
    }

    /**
     * hash递增 如果不存在,就会创建一个 并把新增后的值返回
     * @param key 键
     * @param item 项
     * @param by 要增加几(大于0)
     * @return
     */
    public double hincr(String key, String item,double by){
        return redisTemplate.opsForHash().increment(key, item, by);
    }

    /**
     * hash递减
     * @param key 键
     * @param item 项
     * @param by 要减少记(小于0)
     * @return
     */
    public double hdecr(String key, String item,double by){
        return redisTemplate.opsForHash().increment(key, item,-by);
    }

    //============================set=============================
    /**
     * 根据key获取Set中的所有值
     * @param key 键
     * @return
     */
    public Set<Object> sGet(String key){
        try {
            return redisTemplate.opsForSet().members(key);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 根据value从一个set中查询,是否存在
     * @param key 键
     * @param value 值
     * @return true 存在 false不存在
     */
    public boolean sHasKey(String key,Object value){
        try {
            return redisTemplate.opsForSet().isMember(key, value);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将数据放入set缓存
     * @param key 键
     * @param values 值 可以是多个
     * @return 成功个数
     */
    public long sSet(String key, Object...values) {
        try {
            return redisTemplate.opsForSet().add(key, values);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 将set数据放入缓存
     * @param key 键
     * @param time 时间(秒)
     * @param values 值 可以是多个
     * @return 成功个数
     */
    public long sSetAndTime(String key,long time,Object...values) {
        try {
            Long count = redisTemplate.opsForSet().add(key, values);
            if(time>0) {
                expire(key, time);
            }
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 获取set缓存的长度
     * @param key 键
     * @return
     */
    public long sGetSetSize(String key){
        try {
            return redisTemplate.opsForSet().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 移除值为value的
     * @param key 键
     * @param values 值 可以是多个
     * @return 移除的个数
     */
    public long setRemove(String key, Object ...values) {
        try {
            Long count = redisTemplate.opsForSet().remove(key, values);
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    //===============================list=================================

    /**
     * 获取list缓存的内容
     * @param key 键
     * @param start 开始
     * @param end 结束  0 到 -1代表所有值
     * @return
     */
    public List<Object> lGet(String key, long start, long end){
        try {
            return redisTemplate.opsForList().range(key, start, end);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取list缓存的长度
     * @param key 键
     * @return
     */
    public long lGetListSize(String key){
        try {
            return redisTemplate.opsForList().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 通过索引 获取list中的值
     * @param key 键
     * @param index 索引  index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
     * @return
     */
    public Object lGetIndex(String key,long index){
        try {
            return redisTemplate.opsForList().index(key, index);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 将list放入缓存
     * @param key 键
     * @param value 值
     * @return
     */
    public boolean lSetMIn(String key, Object value) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            expire(key, 60);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将list放入缓存
     * @param key 键
     * @param value 值
     * @return
     */
    public boolean lSet(String key, Object value) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将list放入缓存
     * @param key 键
     * @param value 值
     * @param time 时间(秒)
     * @return
     */
    public boolean lSet(String key, Object value, long time) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将list放入缓存
     * @param key 键
     * @param value 值
     * @return
     */
    public boolean lSetList(String key, List<Object> value) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将list放入缓存
     * @param key 键
     * @param value 值
     * @param time 时间(秒)
     * @return
     */
    public boolean lSetList(String key, List<Object> value, long time) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据索引修改list中的某条数据
     * @param key 键
     * @param index 索引
     * @param value 值
     * @return
     */
    public boolean lUpdateIndex(String key, long index,Object value) {
        try {
            redisTemplate.opsForList().set(key, index, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据索引弹出list中的首条数据
     * @param key 键
     * @param index 等待时间(秒)
     * @return
     */
    public Object lPop(String key, long index) {
        try {
            Object o = redisTemplate.opsForList().leftPop(key, index, TimeUnit.SECONDS);
            return o;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 移除N个值为value
     * @param key 键
     * @param count 移除多少个
     * @param value 值
     * @return 移除的个数
     */
    public long lRemove(String key,long count,Object value) {
        try {
            Long remove = redisTemplate.opsForList().remove(key, count, value);
            return remove;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

}

(4)创建测试controller

package com.example.controller;

import com.alibaba.fastjson.JSONObject;
import com.example.entity.TRSJsonResult;
import com.example.entity.User;
import com.example.util.QiniuFile;
import com.example.util.RedisUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Date;

/**
 * TODO
 *
 * @author Andy
 * @date 2021/4/11 13:13
 */
@org.springframework.web.bind.annotation.RestController
@RequestMapping("/redis")
public class RestController {

    @Autowired
    private RedisUtil redisUtil;

    @RequestMapping("/test")
    public TRSJsonResult test(){
        redisUtil.set("name","andy");
        User user = new User();
        user.setAge(18);
        user.setName("ange");
        user.setBirthday(new Date());
        redisUtil.set("json:user", JSONObject.toJSONString(user));
        return TRSJsonResult.ok(redisUtil.get("json:user"));
    }






}

(5)访问进行测试

(6)使用RMD查看数据信息

八、springboot整合定时任务

1、使用注解@EnableScheduling开启定时任务,会自动扫描

2、定义@Component作为组件被自动扫描

package com.example.task;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * TODO
 *
 * @author Andy
 * @date 2021/4/11 18:12
 */
@Component
public class TestTask {
    private static final SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");


    @Scheduled(fixedRate = 3000)
    public void reportCurrentTime(){
        System.out.println("当前时间:"+sdf.format(new Date()));
    }

}

查看控制台打印

3、表达式生成地址

http://cron.qqe2.com

九、springboot整合异步任务及使用场景

1、使用注解@EnableAsync开启异步,会自动扫描

2、定义@Component@Async作为组件被容器自动扫描

package com.example.task;

import com.example.entity.TRSJsonResult;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.Future;

/**
 * TODO
 *
 * @author Andy
 * @date 2021/4/11 18:12
 */
@Component
public class AsyncTask {

    @Async
    public Future<Boolean> doTask1() throws Exception{
        long start = System.currentTimeMillis();
        Thread.sleep(1000);
        long end = System.currentTimeMillis();
        System.out.println("任务1耗时:"+(end - start)+"毫秒");
        return new AsyncResult<>(true);
    }

    @Async
    public Future<Boolean> doTask2() throws Exception{
        long start = System.currentTimeMillis();
        Thread.sleep(700);
        long end = System.currentTimeMillis();
        System.out.println("任务2耗时:"+(end - start)+"毫秒");
        return new AsyncResult<>(true);
    }

    @Async
    public Future<Boolean> doTask3() throws Exception{
        long start = System.currentTimeMillis();
        Thread.sleep(600);
        long end = System.currentTimeMillis();
        System.out.println("任务3耗时:"+(end - start)+"毫秒");
        return new AsyncResult<>(true);
    }

}

3.创建测试controller

package com.example.controller;

import com.alibaba.fastjson.JSONObject;
import com.example.entity.TRSJsonResult;
import com.example.entity.User;
import com.example.task.AsyncTask;
import com.example.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.Date;
import java.util.concurrent.Future;

/**
 * TODO
 *
 * @author Andy
 * @date 2021/4/11 13:13
 */
@org.springframework.web.bind.annotation.RestController
@RequestMapping("/tasks")
public class DoTaskController {

    @Autowired
    private AsyncTask asyncTask;

    @RequestMapping("/test1")
    public String test1() throws Exception{
        long start = System.currentTimeMillis();
        Future<Boolean> a = asyncTask.doTask1();
        Future<Boolean> b = asyncTask.doTask2();
        Future<Boolean> c = asyncTask.doTask3();
        while(!a.isDone()||!b.isDone()||!c.isDone()){
            if(a.isDone()&&b.isDone()&&c.isDone()){
                break;
            }
        }
        long end = System.currentTimeMillis();
        String times = "任务全部完成,总耗时:"+(end-start)+"毫秒";
        System.out.println(times);
        return times;
    }






}

4、访问测试

5、异步执行使用场景

(1)发生短信

(2)发送邮件

(3)App消息推送

(4)节省运维凌晨任务发布时间,提升效率

十、springboot使用拦截器

1、实现HandlerInterceptor接口自定义拦截器

package com.example.config;

import com.example.entity.User;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * TODO
 *
 * @author Andy
 * @date 2021/4/11 18:54
 */
public class OneInterceptor implements HandlerInterceptor {

    /**
     * 在请求处理之前进行调用(Controller方法调用之前)
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        System.out.println("被one拦截,放行...");

        return true;//如果设置为false时,被请求时,拦截器执行到此处将不会继续操作
        //如果设置为true时,请求将会继续执行后面的操作
    }

    /**
     * 请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
//         System.out.println("执行了TestInterceptor的postHandle方法");
    }

    /**
     * 在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
//        System.out.println("执行了TestInterceptor的afterCompletion方法");
    }
}

2、使用注解@Configuration配置拦截器

3、重写addInterceptors添加需要的拦截器地址

package com.example.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * TODO
 *
 * @author Andy
 * @date 2021/4/11 18:54
 */
@Configuration
public class LoginConfig implements WebMvcConfigurer {
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //注册TestInterceptor拦截器
        InterceptorRegistration registration = registry.addInterceptor(new OneInterceptor());
        registration.addPathPatterns("/**");                      //所有路径都被拦截
        registration.excludePathPatterns(                         //添加不拦截路径
                                         "你的登陆路径",            //登录
                                         "/**/*.html",            //html静态资源
                                         "/**/*.js",              //js静态资源
                                         "/**/*.css",             //css静态资源
                                         "/**/*.woff",
                                         "/**/*.ttf"
                                         );    
    }
}

4、访问hello接口,查看运行结果

 

 

  • 0
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值