SpringBoot开发常见技术整合【学习笔记整理】

SpringBoot开发常见技术整合【学习笔记整理】

SpringBoot开发常见技术整合

1.返回json格式数据

jackson

@RestController = @Controller + @ResponseBody

1.1 响应码和统一数据格式

1. 自定义响应码[使用枚举类]

/** * 响应结果枚举,用于提供给GraceJSONResult返回给前端的 * 本枚举类中包含了很多的不同的状态码供使用,可以自定义 * 便于更优雅的对状态码进行管理,一目了然 频繁 */
public enum ResponseStatusEnum {
   

    SUCCESS(200, true, "操作成功!"),
    FAILED(500, false, "操作失败!"),

    // 50x
    SMS_CODE_FREQUENTLY(517,false,"60s内不能重复获取验证码"),
    UN_LOGIN(501,false,"请登录后再继续操作!"),
    TICKET_INVALID(502,false,"会话失效,请重新登录!"),
    NO_AUTH(503,false,"您的权限不足,无法继续操作!"),
    MOBILE_ERROR(504,false,"短信发送失败,请稍后重试!"),
    SMS_NEED_WAIT_ERROR(505,false,"短信发送太快啦~请稍后再试!"),
    SMS_CODE_ERROR(506,false,"验证码过期或不匹配,请稍后再试!"),
    USER_FROZEN(507,false,"用户已被冻结,请联系管理员!"),
    USER_UPDATE_ERROR(508,false,"用户信息更新失败,请联系管理员!"),
    USER_INACTIVE_ERROR(509,false,"请前往[账号设置]修改信息激活后再进行后续操作!"),
    FILE_UPLOAD_NULL_ERROR(510,false,"文件不能为空,请选择一个文件再上传!"),
    FILE_UPLOAD_FAILD(511,false,"文件上传失败!"),
    FILE_FORMATTER_FAILD(512,false,"文件图片格式不支持!"),
    FILE_MAX_SIZE_ERROR(513,false,"仅支持500kb大小以下的图片上传!"),
    FILE_NOT_EXIST_ERROR(514,false,"你所查看的文件不存在!"),
    USER_STATUS_ERROR(515,false,"用户状态参数出错!"),
    USER_NOT_EXIST_ERROR(516,false,"用户不存在!"),

    // 自定义系统级别异常 54x
    SYSTEM_INDEX_OUT_OF_BOUNDS(541, false, "系统错误,数组越界!"),
    SYSTEM_ARITHMETIC_BY_ZERO(542, false, "系统错误,无法除零!"),
    SYSTEM_NULL_POINTER(543, false, "系统错误,空指针!"),
    SYSTEM_NUMBER_FORMAT(544, false, "系统错误,数字转换异常!"),
    SYSTEM_PARSE(545, false, "系统错误,解析异常!"),
    SYSTEM_IO(546, false, "系统错误,IO输入输出异常!"),
    SYSTEM_FILE_NOT_FOUND(547, false, "系统错误,文件未找到!"),
    SYSTEM_CLASS_CAST(548, false, "系统错误,类型强制转换错误!"),
    SYSTEM_PARSER_ERROR(549, false, "系统错误,解析出错!"),
    SYSTEM_DATE_PARSER_ERROR(550, false, "系统错误,日期解析出错!"),

    // admin 管理系统 56x
    ADMIN_USERNAME_NULL_ERROR(561, false, "管理员登录名不能为空!"),
    ADMIN_USERNAME_EXIST_ERROR(562, false, "管理员登录名已存在!"),
    ADMIN_NAME_NULL_ERROR(563, false, "管理员负责人不能为空!"),
    ADMIN_PASSWORD_ERROR(564, false, "密码不能为空后者两次输入不一致!"),
    ADMIN_CREATE_ERROR(565, false, "添加管理员失败!"),
    ADMIN_PASSWORD_NULL_ERROR(566, false, "密码不能为空!"),
    ADMIN_NOT_EXIT_ERROR(567, false, "管理员不存在或密码错误!"),
    ADMIN_FACE_NULL_ERROR(568, false, "人脸信息不能为空!"),
    ADMIN_FACE_LOGIN_ERROR(569, false, "人脸识别失败,请重试!"),
    CATEGORY_EXIST_ERROR(570, false, "文章分类已存在,请换一个分类名!"),

    // 媒体中心 相关错误 58x
    ARTICLE_COVER_NOT_EXIST_ERROR(580, false, "文章封面不存在,请选择一个!"),
    ARTICLE_CATEGORY_NOT_EXIST_ERROR(581, false, "请选择正确的文章领域!"),
    ARTICLE_CREATE_ERROR(582, false, "创建文章失败,请重试或联系管理员!"),
    ARTICLE_QUERY_PARAMS_ERROR(583, false, "文章列表查询参数错误!"),
    ARTICLE_DELETE_ERROR(584, false, "文章删除失败!"),
    ARTICLE_WITHDRAW_ERROR(585, false, "文章撤回失败!"),
    ARTICLE_REVIEW_ERROR(585, false, "文章审核出错!"),
    ARTICLE_ALREADY_READ_ERROR(586, false, "文章重复阅读!"),

    // 人脸识别错误代码
    FACE_VERIFY_TYPE_ERROR(600, false, "人脸比对验证类型不正确!"),
    FACE_VERIFY_LOGIN_ERROR(601, false, "人脸登录失败!"),

    // 系统错误,未预期的错误 555
    SYSTEM_ERROR(555, false, "系统繁忙,请稍后再试!"),
    SYSTEM_OPERATION_ERROR(556, false, "操作失败,请重试或联系管理员"),
    SYSTEM_RESPONSE_NO_INFO(557, false, "");


    // 响应业务状态
    private Integer status;
    // 调用是否成功
    private Boolean success;
    // 响应消息,可以为成功或者失败的消息
    private String msg;

    ResponseStatusEnum(Integer status, Boolean success, String msg) {
   
        this.status = status;
        this.success = success;
        this.msg = msg;
    }

    public Integer status() {
   
        return status;
    }
    public Boolean success() {
   
        return success;
    }
    public String msg() {
   
        return msg;
    }
}

2 封装返回统一数据格式

import java.util.Map;

/** * 自定义响应数据类型枚举升级版本 * * @Title: IMOOCJSONResult.java * @Package com.imooc.utils * @Description: 自定义响应数据结构 * 本类可提供给 H5/ios/安卓/公众号/小程序 使用 * 前端接受此类数据(json object)后,可自行根据业务去实现相关功能 */
public class GraceJSONResult {
   

    // 响应业务状态码
    private Integer status;

    // 响应消息
    private String msg;

    // 是否成功
    private Boolean success;

    // 响应数据,可以是Object,也可以是List或Map等
    private Object data;

    /** * 成功返回,带有数据的,直接往OK方法丢data数据即可 * @param data * @return */
    public static GraceJSONResult ok(Object data) {
   
        return new GraceJSONResult(data);
    }
    /** * 成功返回,不带有数据的,直接调用ok方法,data无须传入(其实就是null) * @return */
    public static GraceJSONResult ok() {
   
        return new GraceJSONResult(ResponseStatusEnum.SUCCESS);
    }
    public GraceJSONResult(Object data) {
   
        this.status = ResponseStatusEnum.SUCCESS.status();
        this.msg = ResponseStatusEnum.SUCCESS.msg();
        this.success = ResponseStatusEnum.SUCCESS.success();
        this.data = data;
    }


    /** * 错误返回,直接调用error方法即可,当然也可以在ResponseStatusEnum中自定义错误后再返回也都可以 * @return */
    public static GraceJSONResult error() {
   
        return new GraceJSONResult(ResponseStatusEnum.FAILED);
    }

    /** * 错误返回,map中包含了多条错误信息,可以用于表单验证,把错误统一的全部返回出去 * @param map * @return */
    public static GraceJSONResult errorMap(Map map) {
   
        return new GraceJSONResult(ResponseStatusEnum.FAILED, map);
    }

    /** * 错误返回,直接返回错误的消息 * @param msg * @return */
    public static GraceJSONResult errorMsg(String msg) {
   
        return new GraceJSONResult(ResponseStatusEnum.FAILED, msg);
    }

    /** * 错误返回,token异常,一些通用的可以在这里统一定义 * @return */
    public static GraceJSONResult errorTicket() {
   
        return new GraceJSONResult(ResponseStatusEnum.TICKET_INVALID);
    }

    /** * 自定义错误范围,需要传入一个自定义的枚举,可以到[ResponseStatusEnum.java[中自定义后再传入 * @param responseStatus * @return */
    public static GraceJSONResult errorCustom(ResponseStatusEnum responseStatus) {
   
        return new GraceJSONResult(responseStatus);
    }
    public static GraceJSONResult exception(ResponseStatusEnum responseStatus) {
   
        return new GraceJSONResult(responseStatus);
    }

    public GraceJSONResult(ResponseStatusEnum responseStatus) {
   
        this.status = responseStatus.status();
        this.msg = responseStatus.msg();
        this.success = responseStatus.success();
    }
    public GraceJSONResult(ResponseStatusEnum responseStatus, Object data) {
   
        this.status = responseStatus.status();
        this.msg = responseStatus.msg();
        this.success = responseStatus.success();
        this.data = data;
    }
    public GraceJSONResult(ResponseStatusEnum responseStatus, String msg) {
   
        this.status = responseStatus.status();
        this.msg = msg;
        this.success = responseStatus.success();
    }

    public GraceJSONResult() {
   
    }

    public Integer getStatus() {
   
        return status;
    }

    public void setStatus(Integer status) {
   
        this.status = status;
    }

    public String getMsg() {
   
        return msg;
    }

    public void setMsg(String msg) {
   
        this.msg = msg;
    }

    public Object getData() {
   
        return data;
    }

    public void setData(Object data) {
   
        this.data = data;
    }

    public Boolean getSuccess() {
   
        return success;
    }

    public void setSuccess(Boolean success) {
   
        this.success = success;
    }
}

{
   
    “code":200,
    "msg":"成功",
    "status":"ok",
    "data":{
   
    	
	}
}

1.2 jackson

  • @JsonIgnore:转换json的时候把该字段忽略掉
  • @JsonFormat(pattern=”yyyy-MM-dd hh:mm:ss a”,locale=”zh”,timezone=”GMT+8”):日期格式转换
  • @JsonInclude(Include.NON_NULL):如果该字段为null,就不会返回给前端展示
 <!-- jackson -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.10.2</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.10.2</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.10.2</version>
</dependency>

application.yml中配置时间格式

jackson:
	date-format: yyyy-MM-dd HH:mm:ss
	time-zone: GMT+8

另外也可以使用alibaba 提供的FastJSON

1.JSONUtils

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;

/** * * @Title: JsonUtils.java * @Package com.lee.utils * @Description: 自定义响应结构, 转换类 * Copyright: Copyright (c) 2016 * Company:Nathan.Lee.Salvatore * * @author leechenxiang * @date 2016年4月29日 下午11:05:03 * @version V1.0 */
public class JsonUtils {
   

    // 定义jackson对象
    private static final ObjectMapper MAPPER = new ObjectMapper();

    /** * 将对象转换成json字符串。 * <p>Title: pojoToJson</p> * <p>Description: </p> * @param data * @return */
    public static String objectToJson(Object data) {
   
    	try {
   
			String string = MAPPER.writeValueAsString(data);
			return string;
		} catch (JsonProcessingException e) {
   
			e.printStackTrace();
		}
    	return null;
    }
    
    /** * 将json结果集转化为对象 * * @param jsonData json数据 * @param clazz 对象中的object类型 * @return */
    public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {
   
        try {
   
            T t = MAPPER.readValue(jsonData, beanType);
            return t;
        } catch (Exception e) {
   
        	e.printStackTrace();
        }
        return null;
    }
    
    /** * 将json数据转换成pojo对象list * <p>Title: jsonToList</p> * <p>Description: </p> * @param jsonData * @param beanType * @return */
    public static <T>List<T> jsonToList(String jsonData, Class<T> beanType) {
   
    	JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType);
    	try {
   
    		List<T> list = MAPPER.readValue(jsonData, javaType);
    		return list;
		} catch (Exception e) {
   
			e.printStackTrace();
		}
    	
    	return null;
    }
    
}

2.SpringBoot热部署

spring-boot-devtools

#spring.freemarker.cache=false
#关闭环衬,及时刷新
spring.thymeleaf.cache=true

#热部署生效
spring.devtools.restart.enabled=true
#设置重启的目录,添加那个目录的文件需要restart
spring.devtools.restart.additional-paths=src/maiin/java

3.资源文件属性配置


<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <version>2.3.1.RELEASE</version>
</dependency>

  • @Configuration
  • @ConfigurationProperties(prefix=”com.imooc.opensource”)
  • @PropertySource(value=”classpath:resource.properties”)

4.SpringBoot整合thymeleaf

<!-- 引入 thymeleaf 模板依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
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
  • 页面引入命名空间:<html xmlns:th="http://www.thymeleaf.org">
  • 服务端使用ModelMap 封装数据
public String index(ModelMap map){
   
    map.addAttribute("name","hello thymeleaf");
    return "index";//resource/tmplate/index.html
}

参考资料:https://www.cnblogs.com/topwill/p/7434955.html

5.springBoot异常处理

@ControllerAdvice 使用Spring AOP 异常拦截.

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

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

import com.imooc.pojo.IMoocJSONResult;

@ControllerAdvice
public class IMoocExceptionHandler {
   

	public static final String IMOOC_ERROR_VIEW = "error";

// @ExceptionHandler(value = Exception.class)
// public Object errorHandler(HttpServletRequest reqest, 
// HttpServletResponse response, Exception e) throws Exception {
   
// 
// e.printStackTrace();
// 
// ModelAndView mav = new ModelAndView();
// mav.addObject("exception", e);
// mav.addObject("url", reqest.getRequestURL());
// mav.setViewName(IMOOC_ERROR_VIEW);
// return mav;
// }
	
	@ExceptionHandler(value = Exception.class)
    public Object errorHandler(HttpServletRequest reqest, 
    		HttpServletResponse response, Exception e) throws Exception {
   
    	
    	e.printStackTrace();
    	
    	if (isAjax(reqest)) {
   
    		return IMoocJSONResult.errorException(e.getMessage());
    	} else {
   
    		ModelAndView mav = new ModelAndView();
            mav.addObject("exception", e);
            mav.addObject("url", reqest.getRequestURL());
            mav.setViewName(IMOOC_ERROR_VIEW);
            return mav;
    	}
    }
	
	/** * * @Title: IMoocExceptionHandler.java * @Package com.imooc.exception * @Description: 判断是否是ajax请求 */
	public static boolean isAjax(HttpServletRequest httpRequest){
   
		return  (httpRequest.getHeader("X-Requested-With") != null  
					&& "XMLHttpRequest"
						.equals( httpRequest.getHeader("X-Requested-With").toString()) );
	}
}

import javax.servlet.http.HttpServletRequest;

import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import com.imooc.pojo.IMoocJSONResult;

@RestControllerAdvice
public class IMoocAjaxExceptionHandler {
   

 	@ExceptionHandler(value = Exception.class)
	public IMoocJSONResult defaultErrorHandler(HttpServletRequest req, 
			Exception e) throws Exception {
   

		e.printStackTrace();
		return IMoocJSONResult.errorException(e.getMessage());
	}
}
import java.util.List;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

/** * * @Title: LeeJSONResult.java * @Package com.lee.utils * @Description: 自定义响应数据结构 * 这个类是提供给门户,ios,安卓,微信商城用的 * 门户接受此类数据后需要使用本类的方法转换成对于的数据类型格式(类,或者list) * 其他自行处理 * 200:表示成功 * 500:表示错误,错误信息在msg字段中 * 501:bean验证错误,不管多少个错误都以map形式返回 * 502:拦截器拦截到用户token出错 * 555:异常抛出信息 */
public class IMoocJSONResult {
   

    // 定义jackson对象
    private static final ObjectMapper MAPPER = new ObjectMapper();

    // 响应业务状态
    private Integer status;

    // 响应消息
    private String msg;

    // 响应中的数据
    private Object data;
    
    private String ok;	// 不使用

    public static IMoocJSONResult build(Integer status, String msg, Object data) {
   
        return new IMoocJSONResult(status, msg, data);
    }

    public static IMoocJSONResult ok(Object data) {
   
        return new IMoocJSONResult(data);
    }

    public static IMoocJSONResult ok() {
   
        return new IMoocJSONResult(null);
    }
    
    public static IMoocJSONResult errorMsg(String msg) {
   
        return new IMoocJSONResult(500, msg, null);
    }
    
    public static IMoocJSONResult errorMap(Object data) {
   
        return new IMoocJSONResult(501, "error", data);
    }
    
    public static IMoocJSONResult errorTokenMsg(String msg) {
   
        return new IMoocJSONResult(502, msg, null);
    }
    
    public static IMoocJSONResult errorException(String msg) {
   
        return new IMoocJSONResult(555, msg, null);
    }

    public IMoocJSONResult() {
   

    }

// public static LeeJSONResult build(Integer status, String msg) {
   
// return new LeeJSONResult(status, msg, null);
// }

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

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

    public Boolean isOK() {
   
        return this.status == 200;
    }

    public Integer getStatus() {
   
        return status;
    }

    public void setStatus(Integer status) {
   
        this.status = status;
    }

    public String getMsg() {
   
        return msg;
    }

    public void setMsg(String msg) {
   
        this.msg = msg;
    }

    public Object getData() {
   
        return data;
    }

    public void setData(Object data) {
   
        this.data = data;
    }

    /** * * @Description: 将json结果集转化为LeeJSONResult对象 * 需要转换的对象是一个类 */
    public static IMoocJSONResult formatToPojo(String jsonData, Class<?> clazz) {
   
        try {
   
            if (clazz == null) {
   
                return MAPPER.readValue(jsonData, IMoocJSONResult.class);
            }
            JsonNode jsonNode = MAPPER.readTree(jsonData);
            JsonNode data = jsonNode.get("data");
            Object obj = null;
            if (clazz != null) {
   
                if (data.isObject()) {
   
                    obj = MAPPER.readValue(data.traverse(), clazz);
                } else if (data.isTextual()) {
   
                    obj = MAPPER.readValue(data.asText(), clazz);
                }
            }
            return build(jsonNode.get("status").intValue(), jsonNode.get("msg").asText(), obj);
        } catch (Exception e) {
   
            return null;
        }
    }

    /** * * @Description: 没有object对象的转化 * @param json * @return * * @author leechenxiang * @date 2016年4月22日 下午8:35:21 */
    public static IMoocJSONResult format(String json) {
   
        try {
   
            return MAPPER.readValue(json, IMoocJSONResult.class);
        } catch (Exception e) {
   
            e.printStackTrace();
        }
        return null;
    }

    /** * * @Description: Object是集合转化 * 需要转换的对象是一个list */
    public static IMoocJSONResult formatToList(String jsonData, Class<?> clazz) {
   
        try {
   
            JsonNode jsonNode = MAPPER.readTree(jsonData);
            JsonNode data = jsonNode.get("data");
            Object obj = null;
            if (data.isArray() && data.size() > 0) {
   
                obj = MAPPER.readValue(data.traverse(),
                        MAPPER.getTypeFactory().constructCollectionType(List.class, clazz));
            }
            return build(jsonNode.get("status").intValue(), jsonNode.get("msg").asText(), obj);
        } catch (Exception e) {
   
            return null;
        }
    }

	public String getOk() {
   
		return ok;
	}

	public void setOk(String ok) {
   
		this.ok = ok;
	}

}

<!DOCTYPE html>
<html>
<head lang="en">
    <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>

6.SpringBoot整合Mybatis

目前使用Mybatisplus

PageHelper 分页插件 https://pagehelper.github.io/

6.1 SpringBoot整合持久层事物.

  • add | update | delete 的时候使用事物级别:@Transactional(propagation=Propagation.REQUIRED) 当前有事物,加入当前事物,如果没有,就另外开启一个事物

  • select 使用:@Transactional(propagation=Propagation.SUPPORTS) 如果当前有事物,加入当前事物,如果没有也没关系,可以脱离事物去执行。

7.SpringBoot整合redis

7.1 引入依赖

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

7.2 配置文件中进行配置

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

7.3 对RedisTemplate进行封装

import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisKeyValueTemplate;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

/** * * @Title: RedisOperator.java * @Package com.itzixi.web.component * @Description: 使用redisTemplate的操作实现类 Copyright: Copyright (c) 2016 * Company:FURUIBOKE.SCIENCE.AND.TECHNOLOGY * * @author leechenxiang * @date 2017年9月29日 下午2:25:03 * @version V1.0 */
@Component
public class RedisOperator {
   
	
// @Autowired
// private RedisTemplate<String, Object> redisTemplate;
	
	@Autowired
	private StringRedisTemplate redisTemplate;
	
	// Key(键),简单的key-value操作

	/** * 实现命令:TTL key,以秒为单位,返回给定 key的剩余生存时间(TTL, time to live)。 * * @param key * @return */
	public long ttl(String key) {
   
		return redisTemplate.getExpire(key);
	}
	
	/** * 实现命令:expire 设置过期时间,单位秒 * * @param key * @return */
	public void expire(String key, long timeout) {
   
		redisTemplate.expire(key, timeout, TimeUnit.SECONDS);
	}
	
	/** * 实现命令:INCR key,增加key一次 * * @param key * @return */
	public long incr(String key, long delta) {
   
		return redisTemplate.opsForValue().increment(key, delta);
	}

	/** * 实现命令:KEYS pattern,查找所有符合给定模式 pattern的 key */
	public Set<String> keys(String pattern) {
   
		return redisTemplate.keys(pattern);
	}

	/** * 实现命令:DEL key,删除一个key * * @param key */
	public void del(String key) {
   
		redisTemplate.delete(key);
	}

	// String(字符串)

	/** * 实现命令:SET key value,设置一个key-value(将字符串值 value关联到 key) * * @param key * @param value */
	public void set(String key, String value) {
   
		redisTemplate.opsForValue().set(key, value);
	}

	/** * 实现命令:SET key value EX seconds,设置key-value和超时时间(秒) * * @param key * @param value * @param timeout * (以秒为单位) */
	public void set(String key, String value, long timeout) {
   
		redisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS);
	}

	/** * 实现命令:GET key,返回 key所关联的字符串值。 * * @param key * @return value */
	public String get(String key) {
   
		return (String)redisTemplate.opsForValue().get(key);
	}

	// Hash(哈希表)

	/** * 实现命令:HSET key field value,将哈希表 key中的域 field的值设为 value * * @param key * @param field * @param value */
	public void hset(String key, String field, Object value) {
   
		redisTemplate.opsForHash().put(key, field, value);
	}

	/** * 实现命令:HGET key field,返回哈希表 key中给定域 field的值 * * @param key * @param field * @return */
	public String hget(String key, String field) {
   
		return (String) redisTemplate.opsForHash().get(key, field);
	}

	/** * 实现命令:HDEL key field [field ...],删除哈希表 key 中的一个或多个指定域,不存在的域将被忽略。 * * @param key * @param fields */
	public void hdel(String key, Object... fields) {
   
		redisTemplate.opsForHash().delete(key, fields);
	}

	/** * 实现命令:HGETALL key,返回哈希表 key中,所有的域和值。 * * @param key * @return */
	public Map<Object, Object> hgetall(String key) {
   
		return redisTemplate.opsForHash().entries(key);
	}

	// List(列表)

	/** * 实现命令:LPUSH key value,将一个值 value插入到列表 key的表头 * * @param key * @param value * @return 执行 LPUSH命令后,列表的长度。 */
	public long lpush(String key, String value) {
   
		return redisTemplate.opsForList().leftPush(key, value);
	}

	/** * 实现命令:LPOP key,移除并返回列表 key的头元素。 * * @param key * @return 列表key的头元素。 */
	public String lpop(String key) {
   
		return (String)redisTemplate.opsForList().leftPop(key);
	}

	/** * 实现命令:RPUSH key value,将一个值 value插入到列表 key的表尾(最右边)。 * * @param key * @param value * @return 执行 LPUSH命令后,列表的长度。 */
	public long rpush(String key, String value) {
   
		return redisTemplate.opsForList().rightPush(key, value);
	}

}

8.Springboot整合定时任务task

@EnableScheduling 放在启动类上表示开启一个定时任务

参考

在方法级别上使用@Scheduled注解,和core表达式结合使用 core=”0 0 0 1 * ?”

9 SpringBoot 整合异步任务

  • 使用注解@EnableAsync开启异步,会自动扫描
  • 定义@Component @Async 作为组件被容器扫描执行

10 SpringBoot使用拦截器

  • 使用注解@Configuration配置拦截器
  • 继承WebMvcConfigurerAdapter
  • 重写addInterceptors添加需要的拦截器
import com.imooc.exception.GraceException;
import com.imooc.grace.result.ResponseStatusEnum;
import com.imooc.utils.IPUtil;
import com.imooc.utils.RedisOperator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

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

/** * 短信验证码拦截 */
@Slf4j
public class PassportInterceptor implements HandlerInterceptor {
   

    @Autowired
    public RedisOperator redis;

    public static final String MOBILE_SMSCODE = "mobile:smscode";

    /** * 拦截请求,访问controller之前 * * @param request * @param response * @param handler * @return * @throws Exception */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
   

        // 获得用户ip
        String userIp = IPUtil.getRequestIp(request);

        boolean keyIsExist = redis.keyIsExist(MOBILE_SMSCODE + ":" + userIp);

        if (keyIsExist) {
   
            //根据用户Ip 进行限制,限制用户60s内只能获得一次验证码
            GraceException.display(ResponseStatusEnum.SMS_NEED_WAIT_ERROR);
            log.info("短信发送频率太大!");
            return false;
        }

        /** * false:请求被拦截 * true:请求通过验证,放行 */
        return true;
    }


    /** * 请求访问到controller之后,渲染视图之前 * * @param request * @param response * @param handler * @param modelAndView * @throws Exception */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
   

    }

    /** * 请求访问到controller之后,渲染视图之后 * * @param request * @param response * @param handler * @param ex * @throws Exception */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
   

    }
}

import com.imooc.api.interceptors.PassportInterceptor;
import com.imooc.api.interceptors.UserActiveInterceptor;
import com.imooc.api.interceptors.UserTokenInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class InterceptorConfig implements WebMvcConfigurerAdapter {
   

    @Bean
    public PassportInterceptor passportInterceptor() {
   
        return new PassportInterceptor();
    }

   @Bean
    public UserTokenInterceptor userTokenInterceptor() {
   
        return new UserTokenInterceptor();
    }
/* @Bean public ArticleReadInterceptor articleReadInterceptor() { return new ArticleReadInterceptor(); }*/

    @Bean
    public UserActiveInterceptor userActiveInterceptor() {
   
        return new UserActiveInterceptor();
    }

    /* @Bean public AdminTokenInterceptor adminTokenInterceptor() { return new AdminTokenInterceptor(); }*/

    /** * 添加或者注册一个拦截器到spring容器中 * @param registry */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
   

        registry.addInterceptor(passportInterceptor())
                .addPathPatterns("/passport/getSMSCode");

       registry.addInterceptor(userTokenInterceptor())
                .addPathPatterns("/user/getAccountInfo")
                .addPathPatterns("/user/updateUserInfo")
                .addPathPatterns("/fs/uploadFace")
                .addPathPatterns("/fs/uploadSomeFiles")
                .addPathPatterns("/fans/follow")
                .addPathPatterns("/fans/unfollow");

        registry.addInterceptor(userActiveInterceptor())
                .addPathPatterns("/fs/uploadSomeFiles")
                .addPathPatterns("/fans/follow")
                .addPathPatterns("/fans/unfollow");
/* registry.addInterceptor(adminTokenInterceptor()) .addPathPatterns("/adminMng/adminIsExist") .addPathPatterns("/adminMng/addNewAdmin") .addPathPatterns("/adminMng/getAdminList") .addPathPatterns("/fs/uploadToGridFS") .addPathPatterns("/fs/readInGridFS") .addPathPatterns("/friendLinkMng/saveOrUpdateFriendLink") .addPathPatterns("/friendLinkMng/getFriendLinkList") .addPathPatterns("/friendLinkMng/delete") .addPathPatterns("/categoryMng/saveOrUpdateCategory") .addPathPatterns("/categoryMng/getCatList"); registry.addInterceptor(articleReadInterceptor()) .addPathPatterns("/portal/article/readArticle");*/

    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/100726.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 126邮箱登录html,126邮箱登陆界面[通俗易懂]

    126邮箱登录html,126邮箱登陆界面[通俗易懂]大家常常会使用一些手机软件,怎么登录126邮箱,操作简单,容易理解,下面大家一起来学习一下吧。网易邮箱大师6.10.3苹果7IOS12安装并运行网易邮箱大师客户端。在登录栏中填写126邮箱账号。在密码栏填写邮箱密码。找到并点击添加选项。总结如下。网易126邮箱您的专业电子邮局,15年邮箱运营经验,系统快速稳定,垃圾邮件拦截率超过99%,邮箱容量自动翻倍,支持高达3G超大附件,提供免费网盘及手机号码…

  • 联想服务器ts系列介绍,联想服务器ThinkServerTS230.ppt「建议收藏」

    联想服务器ts系列介绍,联想服务器ThinkServerTS230.ppt「建议收藏」联想服务器ThinkServerTS230联想在2012年底推出的专为中小型网络应用环境设计的单路塔式服务器——ThinkServerTS230。作为联想ThinkServer服务器家族的入门级产品,ThinkServerTS230在具备极高性价比的同时,亦完美传承了可靠品质、创新引领、全程关怀三大Think基因,具备…

  • 使用jedis操作redis_hadoop集群如何使用

    使用jedis操作redis_hadoop集群如何使用在上一篇文章中小编为大家介绍的Redis最新版本Redis-5.0.5版本的集群环境安装。集群环境的使用不可能使用客户端命令的方式,肯定要集成到我们的代码中以实现数据缓存功能。对应Java来说Redis官网向用户推荐了Java客户端,如下图所示:在Redis官网推荐的众多Java客户端中,Jedis是一个比较简单而功能强大的客户端,它实现Redis服务的封装,提供了简单的API调用。下面小编就…

  • sql语句大全(详细)

    sql语句大全(详细)数据库操作查看所有数据库showdatabases;查看当前使用的数据库selectdatabase();创建数据库createdatabases数据库名charset=utf8;5.删除数据库dropdatabase数据库名6.使用数据句库usedatabase数据库名7.查看数据库中所有表showtables;表的操作1…

  • JSP九大内置对象

    JSP九大内置对象

    2020年11月12日
  • 相关网站_如何制作一个网站

    相关网站_如何制作一个网站一、职称申报无锡市职称申报系统二、一建报名中国人事考试网三、无锡人事考试网无锡人事考试网四、社保卡江苏人力资源和社会保障网江苏社保卡服务网五、个人公积金查询公积金查询入口六、个人社保查询个人社保查询入口

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号