草稿箱功能
一.请求对象
package com.bdzl.domain.vo;
import com.bdzl.common.validation.SaveAction;
import lombok.Data;
import org.hibernate.validator.constraints.NotBlank;
/**
* @program: mse
* @description: 草稿箱
* @author: @Dog_Elder
* @create: 2021-03-23 17:48
**/
@Data
public class DraftBoxDTO {
/**
* 类型中的 唯一标识 用户id
*/
@NotBlank(message = "唯一标识不能为空 例如 用户id ",groups = {SaveAction.class,Inquiry.class})
private String id;
/**
* 类型 对应 redis的kye 例如 packageNames:methodName:
*/
@NotBlank(message = "类型不能为空 对应 redis的kye 例如 packageNames:methodName:",groups = {SaveAction.class,Inquiry.class})
private String type;
/**
* 参数值 数据
*/
@NotBlank(message = "数据不能为空",groups = {SaveAction.class})
private String str;
/**
* 过期时间
*/
private Integer expireDate;
/**
* 查询
*/
public interface Inquiry{}
}
二.JedisConfig
package com.dog.common.config.jedis;
import com.dog.common.utils.StringUtils;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
/**
* Jedis配置,项目启动注入JedisPool
* http://www.cnblogs.com/GodHeng/p/9301330.html
* @author dolyw.com
* @date 2018/9/5 10:35
*/
@Configuration
@EnableAutoConfiguration
@ConfigurationProperties(prefix = "redis")
@Data
public class JedisConfig {
/**
* logger
*/
private static final Logger logger = LoggerFactory.getLogger(JedisConfig.class);
private String host;
private int port;
private String password;
private int timeout;
@Value("${redis.pool.max-active}")
private int maxActive;
@Value("${redis.pool.max-wait}")
private int maxWait;
@Value("${redis.pool.max-idle}")
private int maxIdle;
@Value("${redis.pool.min-idle}")
private int minIdle;
@Bean
public JedisPool redisPoolFactory() {
try {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxIdle(maxIdle);
jedisPoolConfig.setMaxWaitMillis(maxWait);
jedisPoolConfig.setMaxTotal(maxActive);
// 密码为空设置为null
if (StringUtils.isBlank(password)) {
password = null;
}
JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout, password);
logger.info("初始化Redis连接池JedisPool成功!地址: " + host + ":" + port);
return jedisPool;
} catch (Exception e) {
logger.error("初始化Redis连接池JedisPool异常:" + e.getMessage());
}
return null;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getTimeout() {
return timeout;
}
public void setTimeout(int timeout) {
this.timeout = timeout;
}
public int getMaxActive() {
return maxActive;
}
public void setMaxActive(int maxActive) {
this.maxActive = maxActive;
}
public int getMaxWait() {
return maxWait;
}
public void setMaxWait(int maxWait) {
this.maxWait = maxWait;
}
public int getMaxIdle() {
return maxIdle;
}
public void setMaxIdle(int maxIdle) {
this.maxIdle = maxIdle;
}
public int getMinIdle() {
return minIdle;
}
public void setMinIdle(int minIdle) {
this.minIdle = minIdle;
}
}
application.yml配置redis
# redis 配置
redis:
# 地址
host: 127.0.0.1
# 端口,默认为6379
port: 6379
# 数据库索引
database: 0
# 密码
password: 123456
# 连接超时时间
timeout: 10000
pool:
# 连接池中的最小空闲连接
min-idle: 0
# 连接池中的最大空闲连接
max-idle: 8
# 连接池的最大数据库连接数
max-active: 200
# #连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1
三.JedisUtil
ps: CustomException 这是个自定义异常 修改成自己额即可
package com.dog.common.utils;
import com.dog.common.constant.Constant;
import com.dog.common.exception.CustomException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import java.util.Set;
/**
* redis工具类
* @author @Dog_Elder
*/
@Component
@Slf4j
public class JedisUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext = null;
public JedisUtil() {
}
/**
* 获取redis实例
* @return
*/
public Jedis getJedis() {
Jedis jedis = null;
synchronized (Jedis.class) {
try {
jedis = getJedisPool().getResource();
} finally {
if (jedis != null) {
getJedisPool().returnBrokenResource(jedis);
}
}
}
return jedis;
}
public JedisPool getJedisPool() {
JedisPool jedisPool = null;
if (jedisPool == null) {
synchronized (JedisPool.class) {
if (jedisPool == null) {
jedisPool = applicationContext.getBean(JedisPool.class);
}
}
}
return jedisPool;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (JedisUtil.applicationContext == null) {
JedisUtil.applicationContext = applicationContext; //初始化 spring applicationContext
}
}
/**
* 根据key查看是否存在
*
* @param key
* @return
*/
public boolean hasKey(String key) {
Jedis jedis=null;
try{
jedis = getJedis();
return jedis.exists(key);
}catch (Exception e){
log.info("JedisUtil.hasKey异常:"+e.getMessage());
return false;
}finally {
disConnect(jedis);
}
}
/**
* 设置key -value 形式数据
*
* @param key
* @param value
* @return
*/
public String set(String key, String value) {
Jedis jedis=null;
try{
jedis = getJedis();
return jedis.set(key, value);
}catch (Exception e){
log.info("JedisUtil.set(String key, String value)异常:"+e.getMessage());
return null;
}finally {
disConnect(jedis);
}
}
/**
* 设置 一个过期时间
*
* @param key
* @param value
* @param timeOut 单位秒
* @return
*/
public String set(String key, String value, int timeOut) {
Jedis jedis=null;
try{
jedis = getJedis();
return jedis.setex(key, timeOut, value);
}catch (Exception e){
log.info("JedisUtil.set(String key, String value, int timeOut)异常:"+e.getMessage());
return null;
}finally {
disConnect(jedis);
}
}
/**
* 根据key获取value
*
* @param key
* @return
*/
public String getByKey(String key) {
Jedis jedis=null;
try{
jedis = getJedis();
return jedis.get(key);
}catch (Exception e){
log.info("JedisUtil.getByKey(String key)异常:"+e.getMessage());
return null;
}finally {
disConnect(jedis);
}
}
/**
* 根据通配符获取所有匹配的key
* @param pattern
* @return
*/
public Set<String> getKesByPattern(String pattern) {
Jedis jedis=null;
try{
jedis = getJedis();
return jedis.keys(pattern);
}catch (Exception e){
log.info("JedisUtil.getKesByPattern(String pattern)异常:"+e.getMessage());
return null;
}finally {
disConnect(jedis);
}
}
/**
* 根据key删除
* @param key
*/
public void delByKey(String key) {
Jedis jedis=null;
try{
jedis = getJedis();
if (jedis.exists(key)) {
jedis.del(key);
}
}catch (Exception e){
log.info("JedisUtil.delByKey(String key)异常:"+e.getMessage());
}finally {
disConnect(jedis);
}
}
/**
* 根据key获取过期时间
*
* @param key
* @return
*/
public long getTimeOutByKey(String key) {
Jedis jedis=null;
try{
jedis = getJedis();
return jedis.ttl(key);
}catch (Exception e){
log.info("JedisUtil.getTimeOutByKey(String key)异常:"+e.getMessage());
return 0;
}finally {
disConnect(jedis);
}
}
/**
* 清空数据 【慎用啊!】
*/
public void flushDB(){
Jedis jedis=null;
try{
jedis = getJedis();
jedis.flushDB();
}catch (Exception e){
log.info("JedisUtil.flushDB() 异常:"+e.getMessage());
}finally {
disConnect(jedis);
}
}
/**
* 刷新过期时间
* @param key
* @param timeOut
* @return
*/
public long refreshLiveTime(String key, int timeOut) {
Jedis jedis=null;
try{
jedis = getJedis();
return jedis.expire(key, timeOut);
}catch (Exception e){
log.info("JedisUtil.hasKey异常:"+e.getMessage());
return -1;
}finally {
disConnect(jedis);
}
}
/**
* 释放资源
*/
public void disConnect(Jedis jedis) {
if (jedis!=null){
jedis.disconnect();
// jedis.close();
}
}
/**
* 静态注入JedisPool连接池
* 本来是正常注入JedisUtil,可以在Controller和Service层使用,但是重写Shiro的CustomCache无法注入JedisUtil
* 现在改为静态注入JedisPool连接池,JedisUtil直接调用静态方法即可
* https://blog.csdn.net/W_Z_W_888/article/details/79979103
*/
private static JedisPool jedisPool;
@Autowired
public void setJedisPool(JedisPool jedisPool) {
JedisUtil.jedisPool = jedisPool;
}
/**
* 获取Jedis实例
* @param
* @return redis.clients.jedis.Jedis
* @author dog_E
* @date 2018/9/4 15:47
*/
public static synchronized Jedis getResource() {
try {
if (jedisPool != null) {
return jedisPool.getResource();
} else {
return null;
}
} catch (Exception e) {
throw new CustomException("获取Jedis资源异常:" + e.getMessage());
}
}
/**
* 释放Jedis资源
* @param
* @return void
* @author dog_E
* @date 2018/9/5 9:16
*/
public static void closePool() {
try {
jedisPool.close();
} catch (Exception e) {
throw new CustomException("释放Jedis资源异常:" + e.getMessage());
}
}
/**
* 获取redis键值-object
* @param key
* @return java.lang.Object
* @author dog_E
* @date 2018/9/4 15:47
*/
public static Object getObject(String key) {
try (Jedis jedis = jedisPool.getResource()) {
String bytes = jedis.get(key);
if (StringUtils.isNotBlank(bytes)) {
return bytes;
}
} catch (Exception e) {
throw new CustomException("获取Redis键值getObject方法异常:key=" + key + " cause=" + e.getMessage());
}
return null;
}
/**
* 设置redis键值-object
* @param key
* @param value
* @return java.lang.String
* @author dog_E
* @date 2018/9/4 15:49
*/
public static String setObject(String key, Object value) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.set(key.getBytes(), SerializableUtil.serializable(value));
} catch (Exception e) {
throw new CustomException("设置Redis键值setObject方法异常:key=" + key + " value=" + value + " cause=" + e.getMessage());
}
}
/**
* 设置redis键值-object-expiretime
* @param key
* @param value
* @param expiretime
* @return java.lang.String
* @author dog_E
* @date 2018/9/4 15:50
*/
public static String setObject(String key, Object value, int expiretime) {
String result;
try (Jedis jedis = jedisPool.getResource()) {
result = jedis.set(key, String.valueOf(value));
if (Constant.RedisPrefixConstant.OK.equals(result)) {
jedis.expire(key.getBytes(), expiretime);
}
return result;
} catch (Exception e) {
throw new CustomException("设置Redis键值setObject方法异常:key=" + key + " value=" + value + " cause=" + e.getMessage());
}
}
/**
* 获取redis键值-Json
* @param key
* @return java.lang.Object
* @author dog_E
* @date 2018/9/4 15:47
*/
public static String getJson(String key) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.get(key);
} catch (Exception e) {
throw new CustomException("获取Redis键值getJson方法异常:key=" + key + " cause=" + e.getMessage());
}
}
/**
* 设置redis键值-Json
* @param key
* @param value
* @return java.lang.String
* @author dog_E
* @date 2018/9/4 15:49
*/
public static String setJson(String key, String value) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.set(key, value);
} catch (Exception e) {
throw new CustomException("设置Redis键值setJson方法异常:key=" + key + " value=" + value + " cause=" + e.getMessage());
}
}
/**
* 设置redis键值-Json-expiretime
* @param key
* @param value
* @param expiretime
* @return java.lang.String
* @author dog_E
* @date 2018/9/4 15:50
*/
public static String setJson(String key, String value, int expiretime) {
String result;
try (Jedis jedis = jedisPool.getResource()) {
result = jedis.set(key, value);
if (Constant.RedisPrefixConstant.OK.equals(result)) {
jedis.expire(key, expiretime);
}
return result;
} catch (Exception e) {
throw new CustomException("设置Redis键值setJson方法异常:key=" + key + " value=" + value + " cause=" + e.getMessage());
}
}
/**
* 删除key
* @param key
* @return java.lang.Long
* @author dog_E
* @date 2018/9/4 15:50
*/
public static Long delKey(String key) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.del(key.getBytes());
} catch (Exception e) {
throw new CustomException("删除Redis的键delKey方法异常:key=" + key + " cause=" + e.getMessage());
}
}
/**
* 删除key
* @param key
* @return java.lang.Long
* @author dog_E
* @date 2018/9/4 15:50
*/
public static Boolean delKeyBoolean(String key) {
try (Jedis jedis = jedisPool.getResource()) {
return true;
} catch (Exception e) {
return false;
}
}
/**
* key是否存在
* @param key
* @return java.lang.Boolean
* @author dog_E
* @date 2018/9/4 15:51
*/
public static Boolean exists(String key) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.exists(key);
} catch (Exception e) {
throw new CustomException("查询Redis的键是否存在exists方法异常:key=" + key + " cause=" + e.getMessage());
}
}
/**
* 模糊查询获取key集合(keys的速度非常快,但在一个大的数据库中使用它仍然可能造成性能问题,生产不推荐使用)
* @param key
* @return java.util.Set<java.lang.String>
* @author dog_E
* @date 2018/9/6 9:43
*/
public static Set<String> keysS(String key) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.keys(key);
} catch (Exception e) {
throw new CustomException("模糊查询Redis的键集合keysS方法异常:key=" + key + " cause=" + e.getMessage());
}
}
/**
* 模糊查询获取key集合(keys的速度非常快,但在一个大的数据库中使用它仍然可能造成性能问题,生产不推荐使用)
* @param key
* @return java.util.Set<java.lang.String>
* @author dog_E
* @date 2018/9/6 9:43
*/
public static Set<byte[]> keysB(String key) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.keys(key.getBytes());
} catch (Exception e) {
throw new CustomException("模糊查询Redis的键集合keysB方法异常:key=" + key + " cause=" + e.getMessage());
}
}
/**
* redis做hash的添加
*/
public static boolean hset(String key, String field, String value){
if(StringUtils.isBlank(key) || StringUtils.isBlank(field)){
return false;
}
try (Jedis jedis = jedisPool.getResource()) {
//If the field already exists, and the HSET just produced an update of the value, 0 is returned,
//otherwise if a new field is created 1 is returned.
Long statusCode = jedis.hset(key, field, value);
if(statusCode > -1){
return true;
}
} catch (Exception e) {
throw new CustomException("模糊查询Redis的键集合keysB方法异常:key=" + key + " cause=" + e.getMessage());
}
return false;
}
/**
* @Description: 获取hsah中field的value
* @Author: @Dog_Elder
* @Date: 2020/11/18 14:09
* @param key: key
* @param field: map中key
* @return: map中value
**/
public static String hget(String key, String field){
try (Jedis jedis = jedisPool.getResource()) {
return jedis.hget(key, field);
} catch (Exception e) {
throw new CustomException("获取hsah中field的value方法异常:key=" + key + "field=" + field + " cause=" + e.getMessage());
}
}
/**
* @Description: hash 值 增或加
* @Author: @Dog_Elder
* @Date: 2020/11/19 14:35
* @param key: key
* @param field: map中key
* @param value: 可以是正数 也可以是负数
* @return: java.lang.Long
**/
public static Long hincrBy(String key, String field,long value){
try (Jedis jedis = jedisPool.getResource()) {
return jedis.hincrBy(key,field,value);
} catch (Exception e) {
throw new CustomException("获取hsah中field的value方法异常:key=" + key + "field=" + field + " cause=" + e.getMessage());
}
}
/**
* 获取过期剩余时间
* @param key
* @return java.lang.String
* @author dog_E
* @date 2018/9/11 16:26
*/
public static Long ttl(String key) {
Long result = -2L;
try (Jedis jedis = jedisPool.getResource()) {
result = jedis.ttl(key);
return result;
} catch (Exception e) {
throw new CustomException("获取Redis键过期剩余时间ttl方法异常:key=" + key + " cause=" + e.getMessage());
}
}
}
四.控制器
package com.bdzl.controller.common;
import com.bdzl.common.redis.JedisUtil;
import com.bdzl.common.utils.param.R;
import com.bdzl.common.utils.string.StringUtils;
import com.bdzl.common.validation.SaveAction;
import com.bdzl.domain.vo.DraftBoxDTO;
import net.sf.json.util.JSONUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* @program: mse
* @description: 草稿箱
* @author: @Dog_Elder
* @create: 2021-03-24 17:26
**/
@Controller
@RequestMapping("/draftBox")
public class DraftBoxController {
@Autowired
JedisUtil jedisUtil;
/**
* @param dto: 草稿箱对象通用
* @Description: 保存草稿箱
* @Author: @Dog_Elder
* @Date: 2021-3-23 17:52
* @return: com.bdzl.common.utils.param.R
**/
@PostMapping
@ResponseBody
public R draftBox(@Validated(SaveAction.class) DraftBoxDTO dto) {
if (StringUtils.isNull(dto.getExpireDate())) {
JedisUtil.setJson(dto.getType() + dto.getId(), dto.getStr());
} else {
JedisUtil.setJson(dto.getType() + dto.getId(), dto.getStr(), dto.getExpireDate());
}
return R.ok();
}
/**
* @param dto: 草稿箱对象通用
* @Description: 获取草稿箱内容
* @Author: @Dog_Elder
* @Date: 2021-3-23 17:52
* @return: com.bdzl.common.utils.param.R
**/
@GetMapping
@ResponseBody
public R getDraftBox(DraftBoxDTO dto) {
String byKey = jedisUtil.getByKey(dto.getType() + dto.getId());
String s = JSONUtils.convertToJavaIdentifier(byKey);
return R.ok(s);
}
/**
* @param dto: 草稿箱对象通用
* @Description: 删除草稿箱
* @Author: @Dog_Elder
* @Date: 2021-3-23 17:52
* @return: com.bdzl.common.utils.param.R
**/
@PostMapping("/remove")
@ResponseBody
public R removeDraftBox(DraftBoxDTO dto) {
if (jedisUtil.hasKey(dto.getType() + dto.getId())) {
jedisUtil.delKey(dto.getType() + dto.getId());
}
return R.ok();
}
}
五.测试
ps: 使用form表单主要是后台只是中转不用再处理
让前端直接传json串即可 取的也是json串 取出的转义让前端处理即可