对于程序中一些字典信息、配置信息应该在程序启动时加载到缓存中,用时先到缓存中取,如果没有命中,再到数据库中获取同时放到缓存中,这样做可以减轻数据库层的压力。目前暂时先整合ehcache缓存,同时预留了集成redis和memcached的接口。

先开发两个最基本的功能,就是注册和登录,对于页面几乎就是直接用bootstrap的风格,目前没有过多的设计。

1、整合ehcache

在spring boot中整合ehcache还是很方便的,首先添加依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId>
</dependency><dependency><groupId>net.sf.ehcache</groupId><artifactId>ehcache</artifactId><version>2.10.2</version>
</dependency>

新增ehcache的配置文件,ehcache.xml,即:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="false"monitoring="autodetect" dynamicConfig="true"><diskStore path="java.io.tmpdir" /><!-- 系统临时缓存(十分钟) -->
<cache name="SystemTempCache" maxEntriesLocalHeap="0"maxEntriesLocalDisk="10000000"eternal="false"timeToIdleSeconds="0" timeToLiveSeconds="600" overflowToDisk="false"diskPersistent="false"diskExpiryThreadIntervalSeconds="120"diskSpoolBufferSizeMB="30"memoryStoreEvictionPolicy="LRU">
</cache> <!-- 系统永久缓存 -->
<cache name="SystemEternalCache" maxEntriesLocalHeap="0"maxEntriesLocalDisk="10000000"eternal="true"overflowToDisk="false"diskPersistent="false"diskExpiryThreadIntervalSeconds="120"diskSpoolBufferSizeMB="30"memoryStoreEvictionPolicy="LRU">
</cache></ehcache>

其中设置了两种缓存类型,一个是临时缓存,另一个是永久缓存。

此处使用缓存方式不是基于注解的,虽然基于注解的方式也很方便,但是个人觉得还是自己程序控制缓存好一些。

程序中会将站点的配置信息加载到缓存中,那么使用方式如下:

(1)、首先定义一个缓存接口,本程序中需要用到缓存的,必须实现该接口,即:

package com.swnote.common.cache;/*** 缓存接口** @author lzj* @since 1.0* @date [2019-04-27]*/
public interface ICache<T> {/*** 根据key获取缓存数据** @param key* @return*/public T get(Object key);/*** 存放缓存数据** @param key* @param value*/public void put(Object key, T value);/*** 根据key移除内容** @param key*/public void remove(Object key);
}

(2)、站点配置信息缓存ConfigCache,实现该接口,即:

package com.swnote.common.cache;import com.swnote.common.domain.Config;
import com.swnote.common.service.IConfigService;
import com.swnote.common.util.Const;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import java.util.List;/*** 缓存配置信息* 配置信息放到系统永久缓存中,存放形式为:"_CONFIG" + configId为key,value为配置信息对象** @author lzj* @since 1.0* @date [2019-04-27]*/
@Slf4j
@DependsOn("configService")
@Component("configCache")
public class ConfigCache implements ICache<Config> {/*** 注入基于Spring提供的Cache接口实例,默认由Ehcache实现* TODO 以后也可以是Redis、Memcached提供实现*/@Autowiredprivate CacheManager cacheManager;@Autowiredprivate IConfigService configService;/*** 系统临时缓存实例*/private Cache cache;/*** key的前缀*/private String keyPrefix = "_CONFIG";@PostConstructpublic void init() {// 获取系统永久缓存实例cache = cacheManager.getCache(Const.CACHE_SYSTEM_ETERNAL);log.info("获取系统永久缓存实例");log.info("开始加载所有配置信息");List<Config> configs = configService.list();if (configs != null && !configs.isEmpty()) {configs.stream().forEach(config -> cache.put(keyPrefix + config.getConfigId(), config));}log.info("加载完毕所有配置信息");}@Overridepublic Config get(Object key) {Cache.ValueWrapper valueWrapper = cache.get(keyPrefix + key);if (valueWrapper == null) {// 此时从数据库重新加载一次Config config = configService.getById((String) key);if (config == null) {return null;}// 再次放到缓存中cache.put(keyPrefix + config.getConfigId(), config);return config;}return (Config) valueWrapper.get();}@Overridepublic void put(Object key, Config value) {cache.put(keyPrefix + key, value);}@Overridepublic void remove(Object key) {cache.evict(keyPrefix + key);}
}

2、注册功能

注册页面效果如下:

页面风格很素,这个暂时先这样。

主要看一下UserController中处理注册信息的关键代码,即:

/*** 保存注册信息* * @param model* @param request* @return*/
@RequestMapping(value = "/auth/signup", method = RequestMethod.POST)
@ResponseBody
public Result signup(Model model, HttpServletRequest request) {Result result = new Result();try {// 接收参数String name = request.getParameter("name");String email = request.getParameter("email");String password = request.getParameter("password");// 简单校验if (StringUtils.isEmpty(name) || StringUtils.isEmpty(email) || StringUtils.isEmpty(password)) {throw new TipException("缺少必要请求参数");}if (!StringUtil.isEmail(email)) {throw new TipException("邮箱不符全规范");}// 校验用户名User tempUser = userService.getByName(name);if (tempUser != null && !StringUtils.isEmpty(tempUser.getUserId())) {throw new TipException("该用户已经注册了");}// 校验邮箱tempUser = userService.getByEmail(email);if (tempUser != null && !StringUtils.isEmpty(tempUser.getUserId())) {throw new TipException("该邮箱已经注册了");}// 获取用户ipString ip = HttpUtil.getIpAddr(request);// 构建用户信息User user = new User();user.setLoginName(name);user.setEmail(email);user.setPassword(StringUtil.md5(password));user.setCreateIp(ip);// 保存用户信息boolean flag = userService.create(user);if (!flag) {throw new TipException("用户创建失败");}result.setCode(Result.CODE_SUCCESS);result.setMsg("用户创建成功");} catch (Exception e) {log.error("用户创建失败", e);result.setCode(Result.CODE_EXCEPTION);result.setMsg("用户创建失败");}return result;
}

在UserService中有一个create方法,即:

@Override
public boolean create(User user) {// 获取当前时间Date now = new Date();// 设置主键user.setUserId(IdGenarator.guid());// 设置未实名认证user.setRealStatus(User.REAL_STATUS_NO);// 用户是否需要激活Config config = configCache.get(Const.CONFIG_USER_ACTIVE);if (config != null && "1".equals(config.getConfigValue())) {// TODO 发送激活邮件信息// 说明需要激活user.setIsActive(User.ACTIVE_NO);} else {// 说明不需要激活,默认激活user.setIsActive(User.ACTIVE_YES);}// 设置启用账号状态user.setStatus(User.STATUS_YES);// 设置创建时间user.setCreateTime(now);// 设置关注数为0user.setFollows(0);// 设置粉丝数为0user.setFans(0);return save(user);
}

此处有一个还没有实现的功能,就是发送激活邮件信息,这个功能后面会补上,这里先处于TODO状态。

3、登录功能

登录页面效果如下:

UserController中关键的代码如下:

/*** 处理登录信息** @param request* @return*/
@RequestMapping(value = "/auth/login", method = RequestMethod.POST)
@ResponseBody
public Result login(HttpServletRequest request, HttpSession session) {Result result = new Result();try {// 接收参数String name = request.getParameter("name");String password = request.getParameter("password");if (StringUtils.isEmpty(name) || StringUtils.isEmpty(password)) {throw new TipException("缺少必要请求参数");}// 获取用户ipString ip = HttpUtil.getIpAddr(request);User user = userService.verifyUser(name, password, ip);if (user == null) {throw new TipException("用户名或密码错误");}// 放置session信息session.setAttribute(Const.SESSION_USER, user);// TODO 还有一些相关统计信息,后面再加上result.setCode(Result.CODE_SUCCESS);result.setMsg("登录成功");} catch (TipException e) {result.setCode(Result.CODE_EXCEPTION);result.setMsg(e.getMessage());} catch (Exception e) {log.error("登录失败", e);result.setCode(Result.CODE_EXCEPTION);result.setMsg("登录失败");}return result;
}

当用户登录时,还有一些相关统计信息,这里由于其它功能还没有开发完,所以获取统计信息的代码后面再加上。

关注我

以你最方便的方式关注我:
微信公众号:

转载于:https://www.cnblogs.com/atcloud/p/10831548.html

基于SpringBoot从零构建博客网站 - 整合ehcache和开发注册登录功能相关推荐

  1. 基于SpringBoot从零构建博客网站 - 开发设置主页标识和修改个人信息功能

    由于守望博客系统中支持由用户自己设置个人主页的URL的后半段,所以必须要用户设置该标识的功能,而且是用户注册登录之后自动弹出的页面,如果用户没有设置该标识,其它的操作是不能够操作的,同时要求主页标识只 ...

  2. springboot分页展示功能_基于SpringBoot从零构建博客网站 - 分页显示文章列表功能...

    显示文章列表一般都是采用分页显示,比如每页10篇文章显示.这样就不用每次就将所有的文章查询出来,而且当文章数量特别多的时候,如果一次性查询出来很容易出现OOM异常. 后台的分页插件采用的是mybati ...

  3. 一步步开发自己的博客 .NET版(3、注册登录功能)

    前言 这次开发的博客主要功能或特点:     第一:可以兼容各终端,特别是手机端.     第二:到时会用到大量html5,炫啊.     第三:导入博客园的精华文章,并做分类.(不要封我)     ...

  4. 基于springboot + vue 的个人博客搭建过程(续)

    承接上文:基于springboot + vue 的个人博客搭建过程 目录 1. 评论列表 1.1 接口说明 1.2 controller 1.3 service 1.4 mapper 1.5 实体类 ...

  5. 基于springboot搭建的个人博客系统

    源码下载地址:blog blog是基于springboot搭建的个人博客,响应式 前端技术:html.css.js.jq.bootstrap 后台技术:springboot.thymeleaf.myb ...

  6. 基于springboot + vue 的个人博客搭建过程(上线)

    承接上文: 基于springboot + vue 的个人博客搭建过程(续) 目录 1. 搭建环境 1. 安装docker 2. 拉取并运行 2.1 拉取服务 2.2 部署运行mysql 2.3 部署运 ...

  7. 基于Java/Mysql的个人博客网站

    3年前写的一个技术博客...纪念一下. OpenIdea Blog - 开源灵感博客 a personal blog site based on Java/Mysql - 基于Java/Mysql的个 ...

  8. SpringBoot之从零搭建博客网站

    前言 为什么想要搭建这个博客? 程序员从业8年,期间学过一些东西,用过一些东西,然后遗忘,然后再次翻书,周而复始,少有总结的时候. 少时学编程,有时颇有趣味.有所悟.有所得.豁然开朗.别有洞天的感觉, ...

  9. SpringBoot之从零搭建博客网站(可提供源码)

    文字不够,图片来凑. 前言 为什么想要搭建这个博客? 我还记得,在大二寒假的某天,同往常一样的在家解决这某个bug,不停地问度娘,很巧的碰到了一个同行在他的博客中完美的记录了我的bug的解决方案,随后 ...

最新文章

  1. Nginx 使用中文URL,中文目录路径
  2. java mcrypt encrypt_PHP mcrypt_encrypt加密,使用java解密
  3. 前端将二进制数据流转为文件_前端通过二进制流下载文件
  4. Feature Engineering 特征工程 1. Baseline Model
  5. 计算机硬件教学设计高中信息,重大版信息技术七上《计算机硬件系统》教学设计.doc...
  6. 【C语言】如何安装CLion并在CLion中Run一个程序
  7. 矩阵乘法Strassen算法
  8. 温度湿度传感器流程图_为什么温湿度传感器用一段时间就会漂移?
  9. exe电子书转换txt 下载_网站能经常看到的主流电子书格式
  10. (开源)微信小程序实时控制stc89c51,通过esp8266
  11. DynamipsGUI2.7使用介绍
  12. 基于FPGA的RS485通信接口实验手册
  13. CF918D: MADMAX 题解
  14. 【编程题】【Scratch一级】2022.03 飞翔的小猫
  15. html css二级下拉菜单,下拉导航 - 两级菜单(CSS/HTML)
  16. 【Day5.7】美食街实在吃不下去,回暹罗商圈再晚餐
  17. 红蓝出屏3D图片,请使用红蓝眼镜观看
  18. MDS(多维尺度变换)降维算法
  19. 2021年跨境电商行业相关数据
  20. 小鸡手柄和劲玩X3蓝牙手柄对比

热门文章

  1. 从零开始学java(2)--java中命名的明规则与潜规则
  2. [转]itertools --- 为高效循环而创建迭代器的函数
  3. 量化策略回测ATRRSI
  4. Logistic逻辑回归用初等数学解读逻辑回归
  5. android 触摸监听重写_第六十四回:Android中UI控件之SeekBar
  6. 别再用代码开发了,整理了30套实用可视化大屏模板,无套路直接领
  7. 数据分析角度拆解可怕的庞氏骗局,究竟是怎么骗到人的?
  8. python多元回归 导出参数统计结果_如何从统计模型中WLS回归的二维参数得到检验的预测...
  9. ajax前端取消用户发送重复请求
  10. 返回的图片 buffer 怎么接收_面试题:Kafka 会不会丢消息?怎么处理的?