Fork me on GitHub

记毕业设计学习之路

前言

最近忙着公司的项目,没有时间来打理自己的小窝;毕业设计也开始了,在这里也慢慢记载一些做毕业设计过程当中使用到的、学习到的、值得思考的知识和细节。方便日后学习、同时也分享给大家。对了,顺便附上这个项目的仓库吧.传送门

maven 环境隔离

实际项目开发当中我们会用到不止一下三种环境,开发环境、测试环境、生产环境。使用maven将各个环境进行隔离,方便开发、同时也方便上线。让因为配置文件不一致、环境没有更换这些问题导致项目异常不存在。

  • dev(开发环境)
  • beta(测试环境)
  • prod(生产环境)

Redis学习

redis安装(window/linux)

关于redis的安装,可以参考前一篇文章如何安装redis和简单使用

redis数据结构/基本命令

键命令

PropertiesUtil工具类

对PropertiesUtil进行了优化性的封装,提供获取Integer Boolean String等不同类型配置文件value的方法

redisPool连接池

redisPool连接池封装

  • redisPool连接池的完善
  • 获取jedis对象getRedis()
  • 返回资源returnResource()
  • returnBrokenResource()使用

学习jedis源码

lombok工具

IDE工具安装lombok工具

引入其依赖,使用注解

使用lombok注解

  • @Sl4j
  • @Setter
  • @Getter
  • @Data
  • 区分@Data@Setter``@Getter使用有什么区别,各自含义

RedisPoolUtil工具类

RedisPoolUtil工具类封装

提供对Redis的set get del setEx expire等操作的方法

JsonUtil工具类

JsonUtil工具类封装

封装JsonUtil工具类,提供json和object之间相互转换方法,同时提供json转List Map等复杂集合对象的转换方法

  • json和object之间相互转换方法

  • json转List Map等复杂集合对象的转换方法

JsonUtil中objectMapper当中各种属性的配置

  • objectMapper.setSerializationInclusion(Inclusion.ALWAYS); 对象的所有字段全部列入序列化
  • objectMapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false); 取消默认转换timestamps
  • objectMapper.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS, false); 忽略空bean转json错误
  • objectMapper.setDateFormat(new SimpleDateFormat(DateTimeUtil.STANDARD_FORMAT)); 所有的日期格式都统一为以下格式:yyyy-MM-dd HH:mm:ss
  • objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); 反序列化时,忽略在json字符串当中存在,但是在java对象当中不存在的对应属性的情况,防止错误

Tomcat集群

IDEA当中启动两个Tomcat,来模拟Tomcat集群。

CookieUtil工具类封装

熟悉在客户端种cookie的domain跨域问题

封装CookieUtil

封装常用对cookie操作的read write del方法

  • String readLoginToken(HttpServletRequest request) 读cookie操作
  • void writeLoginToken(HttpServletResponse response, String token) 写cookie操作
  • void delLoginToken(HttpServletRequest request, HttpServletResponse response) 删除cookie操作

单点登录Session共享

单点登录

  • 登录操作

    将用户登录成功之后的sessionId存入cookie取名为loginToken,同时将其存入redis当中,key=sessionId value=User实体的Json字符串,同时设置redis当中数据过期时间(用户登录过期时间)

  • 查看用户信息

    从cookie当中获取loginToken,如果loginToken为null则说明用户未登录,直接返回,然后从redis当中获取key=loginToken的value,并将其Json反序列化成User对象,然后返回

  • 登出操作

    从cookie当中获取到loginToken,然后从redis当中key=loginToken的value

  • 存在问题

    loginToken存储在cookie当中存在有效时间,现在不能满足,用户进行除登出操作之外的其他请求时自动刷新loginToken的过期时间,用户登录一定时间到期后(期间无论是否进行其他操作)
    都会让用户再次登录。而我们需要的是,在有效期之内只要用户发送了除登出操作之外的请求,都会自动更新这个过期时间

解决上述单点登录存在问题

  • 使用原生过滤器

    SessionExpireFilter就是为了解决用发送请求时重置种下的loginToken 过期时间,这样就可以避免用户登录后30分钟有需要再次重新登录。
    现在只存在登录成功后30分钟之内不发送任何请求,redis当中的loginToken则会过期

Redis分布式

Redis分布式算法原理(一致性算法)

  • 传统分布式算法
  • Consistent hashing 一致性算法原理
  • Hash倾斜性
  • 虚拟节点
  • Consistent hashing命中率

Redis分布式环境配置

Redis分布式服务端及客户端启动

封装分布式Shared Redis API

集群和分布式概念区分

Spring-session 学习

查看spring-session 官方文档

spring-session-data-redis 学习

springMVC 全局异常

使用ModelAndView

使用ModelAndView返回jackson数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Slf4j
@Component
public class ExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
log.error("{} Exception", httpServletRequest.getRequestURI(), e);
ModelAndView modelAndView = new ModelAndView(new MappingJacksonJsonView());
/*当时用jackson2.x时使用MappingJackson2JsonView 在这里使用Jackson1.9.12*/

modelAndView.addObject("status", ResponseCode.ERROR.getCode());
modelAndView.addObject("msg", "接口异常,服务端接口异常信息");
modelAndView.addObject("data",e.toString());
return modelAndView;
}
}

SpringMVC 拦截器

使用配置文件拦截器

1
2
3
4
<!--指定拦截-->
<mvc:mapping path="/manage/**"/>
<!--排除不走拦截器的请求-->
<mvc:exclude-mapping path="/manage/user/login.do"/>

各属性的含义

  • /
  • /**
  • /*

使用request当中获取className和methodName进行指定拦截

1
2
3
4
5
6
7
8
9
10
/*请求中的方法名*/
HandlerMethod handlerMethod = (HandlerMethod) handler;
String methodName = handlerMethod.getMethod().getName();
String className = handlerMethod.getBean().getClass().getSimpleName();
/*使用代码进行拦截*/
if (StringUtils.equals(className,"UserManageController") && StringUtils.equals(methodName,"login")){
log.info("拦截器拦截到请求,className:{},methodName:{}",className,methodName);
/*如果是拦截登录请求,不打印参数,因为参数之中存在账户名和密码的信息*/
return true;
}

response进行重置

RESTful接口设计

RESTful接口设计原理

该风格适用哪些请求,怎样请求不合适

Spring Schedule

Cron表达式

Cron表达式生成器

spring schedule配置

MySQL 行锁 表锁

Redis 分布式锁

Redis 分布式锁命令

  • setnx ==> 具有原子性,set的同时能够判断是否存在 setnx(lockkey,currenttime+timeout)
  • getset ==> 具有原子性,获取旧的值,设置新的值
  • expire ==> 设置过期时间
  • del ==> 删除

    • 与实践戳的结合
    • Redis分布式锁的流程图
    • Redis分布式锁优化版流程图

联系

聪聪的独立博客 ,一个喜欢技术,喜欢钻研的95后。如果你看到这篇文章,千里之外,我在等你联系。

坚持原创技术分享,您的支持将鼓励我继续创作!