From f536825045754161fc56c763e9ab1e5425b412e8 Mon Sep 17 00:00:00 2001 From: lcg0124 <1992lcg@163.com> Date: Fri, 15 Dec 2017 17:32:58 +0800 Subject: [PATCH 01/18] =?UTF-8?q?1.6.4=20=E4=BF=AE=E5=A4=8D=E6=9B=B4?= =?UTF-8?q?=E6=96=B0bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/bootdo/system/controller/DeptController.java | 4 +--- bootdo/src/main/java/com/bootdo/system/domain/UserDO.java | 4 +++- bootdo/src/main/resources/mybatis/system/UserMapper.xml | 3 +++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/bootdo/src/main/java/com/bootdo/system/controller/DeptController.java b/bootdo/src/main/java/com/bootdo/system/controller/DeptController.java index 89e1011..3629905 100644 --- a/bootdo/src/main/java/com/bootdo/system/controller/DeptController.java +++ b/bootdo/src/main/java/com/bootdo/system/controller/DeptController.java @@ -6,8 +6,6 @@ import com.bootdo.common.domain.Tree; import com.bootdo.common.utils.R; import com.bootdo.system.domain.DeptDO; import com.bootdo.system.service.DeptService; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.springframework.beans.factory.annotation.Autowired; @@ -41,7 +39,7 @@ public class DeptController extends BaseController { } @ApiOperation(value="获取部门列表", notes="") - @RequestMapping(value={""}) +// @RequestMapping(value={""}) @ResponseBody @GetMapping("/list") @RequiresPermissions("system:sysDept:sysDept") diff --git a/bootdo/src/main/java/com/bootdo/system/domain/UserDO.java b/bootdo/src/main/java/com/bootdo/system/domain/UserDO.java index 650b426..a71c106 100644 --- a/bootdo/src/main/java/com/bootdo/system/domain/UserDO.java +++ b/bootdo/src/main/java/com/bootdo/system/domain/UserDO.java @@ -1,6 +1,6 @@ package com.bootdo.system.domain; -import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; import java.io.Serializable; import java.util.Date; @@ -37,6 +37,7 @@ public class UserDO implements Serializable { //性别 private Long sex; //出身日期 + @DateTimeFormat(pattern = "yyyy-MM-dd") private Date birth; //图片ID private Long picId; @@ -50,6 +51,7 @@ public class UserDO implements Serializable { private String city; //所在地区 private String district; + /** * 设置: */ diff --git a/bootdo/src/main/resources/mybatis/system/UserMapper.xml b/bootdo/src/main/resources/mybatis/system/UserMapper.xml index 54379e0..99a0e2a 100644 --- a/bootdo/src/main/resources/mybatis/system/UserMapper.xml +++ b/bootdo/src/main/resources/mybatis/system/UserMapper.xml @@ -149,4 +149,7 @@ + \ No newline at end of file -- Gitee From 455b047a271060b44a9c49bb04a4c76aaab49732 Mon Sep 17 00:00:00 2001 From: lovewinner Date: Wed, 20 Dec 2017 00:08:26 +0800 Subject: [PATCH 02/18] =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=91=98=E9=87=8D?= =?UTF-8?q?=E7=BD=AE=E7=94=A8=E6=88=B7=E5=AF=86=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/controller/UserController.java | 17 ++++++++++++++++- .../com/bootdo/system/service/UserService.java | 2 +- .../system/service/impl/UserServiceImpl.java | 11 +++++++++++ .../templates/system/user/reset_pwd.html | 8 ++++---- 4 files changed, 32 insertions(+), 6 deletions(-) diff --git a/bootdo/src/main/java/com/bootdo/system/controller/UserController.java b/bootdo/src/main/java/com/bootdo/system/controller/UserController.java index 8c2c5ac..02b686e 100644 --- a/bootdo/src/main/java/com/bootdo/system/controller/UserController.java +++ b/bootdo/src/main/java/com/bootdo/system/controller/UserController.java @@ -178,7 +178,22 @@ public class UserController extends BaseController { } } - + @RequiresPermissions("sys:user:resetPwd") + @Log("admin提交更改用户密码") + @PostMapping("/adminResetPwd") + @ResponseBody + R adminResetPwd(UserVO userVO) { + if (Constant.DEMO_ACCOUNT.equals(getUsername())) { + return R.error(1, "演示系统不允许修改,完整体验请部署程序"); + } + try{ + userService.adminResetPwd(userVO); + return R.ok(); + }catch (Exception e){ + return R.error(1,e.getMessage()); + } + + } @GetMapping("/tree") @ResponseBody public Tree tree() { diff --git a/bootdo/src/main/java/com/bootdo/system/service/UserService.java b/bootdo/src/main/java/com/bootdo/system/service/UserService.java index e3430db..da1b500 100644 --- a/bootdo/src/main/java/com/bootdo/system/service/UserService.java +++ b/bootdo/src/main/java/com/bootdo/system/service/UserService.java @@ -32,7 +32,7 @@ public interface UserService { Set listRoles(Long userId); int resetPwd(UserVO userVO,UserDO userDO) throws Exception; - + int adminResetPwd(UserVO userVO) throws Exception; Tree getTree(); /** diff --git a/bootdo/src/main/java/com/bootdo/system/service/impl/UserServiceImpl.java b/bootdo/src/main/java/com/bootdo/system/service/impl/UserServiceImpl.java index def9bf7..507c74b 100644 --- a/bootdo/src/main/java/com/bootdo/system/service/impl/UserServiceImpl.java +++ b/bootdo/src/main/java/com/bootdo/system/service/impl/UserServiceImpl.java @@ -121,6 +121,17 @@ public class UserServiceImpl implements UserService { throw new Exception("你修改的不是你登录的账号!"); } } + @Override + public int adminResetPwd(UserVO userVO) throws Exception { + UserDO userDO =get(userVO.getUserDO().getUserId()); + if("admin".equals(userDO.getUsername())){ + throw new Exception("超级管理员的账号不允许直接重置!"); + } + userDO.setPassword(MD5Utils.encrypt(userDO.getUsername(), userVO.getPwdNew())); + return userMapper.update(userDO); + + + } @Transactional @Override diff --git a/bootdo/src/main/resources/templates/system/user/reset_pwd.html b/bootdo/src/main/resources/templates/system/user/reset_pwd.html index 08ce46e..58683d4 100644 --- a/bootdo/src/main/resources/templates/system/user/reset_pwd.html +++ b/bootdo/src/main/resources/templates/system/user/reset_pwd.html @@ -12,13 +12,13 @@
-
- +
@@ -63,7 +63,7 @@ $.ajax({ cache : true, type : "POST", - url : "/sys/user/resetPwd", + url : "/sys/user/adminResetPwd", data : $('#signupForm').serialize(),// 你的formid async : false, error : function(request) { -- Gitee From 93d93ff552d6efaa67d46fbaa7e0ed1130b86f26 Mon Sep 17 00:00:00 2001 From: lcg0124 <1992lcg@163.com> Date: Mon, 25 Dec 2017 15:21:41 +0800 Subject: [PATCH 03/18] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20README.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index d5587a2..414b71e 100644 --- a/README.md +++ b/README.md @@ -44,14 +44,13 @@ BootDo 提供了常用工具进行封装,包括日志工具、缓存工具、 * 数据库连接池:Alibaba Druid * 缓存框架:Ehcache 、Redis * 日志管理:SLF4J -* 工具类:Apache Commons、Jackson 、Xstream 1.4、Dozer 5.3、POI 3.9 +* 工具类:Apache Commons、Jackson 2、前端 * JS框架:jQuery * 客户端验证:JQuery Validation * 富文本在线编辑:summernote -* 在线文件管理:CKFinder * 数据表格:bootstrapTable * 弹出层:layer * 树结构控件:jsTree @@ -59,8 +58,7 @@ BootDo 提供了常用工具进行封装,包括日志工具、缓存工具、 4、平台 * 服务器中间件:SpringBoot内置 -* 数据库支持:目前仅提供MySql数据库的支持,但不限于数据库,平台留有其它数据库支持接口, -你可以很方便的更改为其它数据库,如:SqlServer 2008、MySql 5.5、H2等 +* 数据库支持:目前仅提供MySql数据库的支持,但不限于数据库 * 开发环境:Java、Eclipse Java EE 、Maven 、Git ## 安全考虑 -- Gitee From 213e50bbf85268bdff70c9713d5eb7cb5b2ee26c Mon Sep 17 00:00:00 2001 From: lcg0124 <1992lcg@163.com> Date: Tue, 2 Jan 2018 08:52:58 +0800 Subject: [PATCH 04/18] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=80=9A=E7=9F=A5?= =?UTF-8?q?=E5=85=AC=E5=91=8A=E5=9C=A8=E7=BA=BF=E6=B6=88=E6=81=AF=E6=8F=90?= =?UTF-8?q?=E9=86=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/bootdo/common/task/WelcomeJob.java | 3 + .../com/bootdo/common/utils/ShiroUtils.java | 43 ++-- .../com/bootdo/oa/config/WebSocketConfig.java | 51 +++-- .../oa/controller/NotifyController.java | 4 + .../oa/controller/WebSocketController.java | 108 +++++----- .../oa/service/impl/NotifyServiceImpl.java | 189 +++++++++--------- .../system/controller/SessionController.java | 3 + .../bootdo/system/service/SessionService.java | 5 + .../service/impl/SessionServiceImpl.java | 101 ++++++---- .../resources/mybatis/oa/NotifyMapper.xml | 2 +- .../main/resources/templates/index_v1.html | 43 +++- .../src/main/resources/templates/login.html | 2 +- 12 files changed, 339 insertions(+), 215 deletions(-) diff --git a/bootdo/src/main/java/com/bootdo/common/task/WelcomeJob.java b/bootdo/src/main/java/com/bootdo/common/task/WelcomeJob.java index 41fbd44..2ba86ed 100644 --- a/bootdo/src/main/java/com/bootdo/common/task/WelcomeJob.java +++ b/bootdo/src/main/java/com/bootdo/common/task/WelcomeJob.java @@ -9,6 +9,8 @@ import org.springframework.stereotype.Component; import com.bootdo.oa.domain.Response; +import java.security.Principal; + @Component public class WelcomeJob implements Job{ @Autowired @@ -17,6 +19,7 @@ public class WelcomeJob implements Job{ @Override public void execute(JobExecutionContext arg0) throws JobExecutionException { template.convertAndSend("/topic/getResponse", new Response("欢迎体验bootdo,这是一个任务计划,使用了websocket和quzrtz技术,可以在计划列表中取消,欢迎您加入qq群交流学习!" )); + } } \ No newline at end of file diff --git a/bootdo/src/main/java/com/bootdo/common/utils/ShiroUtils.java b/bootdo/src/main/java/com/bootdo/common/utils/ShiroUtils.java index 723e68c..efe551c 100644 --- a/bootdo/src/main/java/com/bootdo/common/utils/ShiroUtils.java +++ b/bootdo/src/main/java/com/bootdo/common/utils/ShiroUtils.java @@ -1,21 +1,40 @@ package com.bootdo.common.utils; import org.apache.shiro.SecurityUtils; +import org.apache.shiro.session.Session; +import org.apache.shiro.session.mgt.eis.SessionDAO; import org.apache.shiro.subject.Subject; import com.bootdo.system.domain.UserDO; +import org.springframework.beans.factory.annotation.Autowired; + +import java.security.Principal; +import java.util.Collection; +import java.util.List; public class ShiroUtils { - public static Subject getSubjct() { - return SecurityUtils.getSubject(); - } - public static UserDO getUser() { - return (UserDO)getSubjct().getPrincipal(); - } - public static Long getUserId() { - return getUser().getUserId(); - } - public static void logout() { - getSubjct().logout(); - } + @Autowired + private static SessionDAO sessionDAO; + + public static Subject getSubjct() { + return SecurityUtils.getSubject(); + } + + public static UserDO getUser() { + return (UserDO) getSubjct().getPrincipal(); + } + + public static Long getUserId() { + return getUser().getUserId(); + } + + public static void logout() { + getSubjct().logout(); + } + + public static List getPrinciples() { + List principals = null; + Collection sessions = sessionDAO.getActiveSessions(); + return principals; + } } diff --git a/bootdo/src/main/java/com/bootdo/oa/config/WebSocketConfig.java b/bootdo/src/main/java/com/bootdo/oa/config/WebSocketConfig.java index 8fb8bc4..d83b1ba 100644 --- a/bootdo/src/main/java/com/bootdo/oa/config/WebSocketConfig.java +++ b/bootdo/src/main/java/com/bootdo/oa/config/WebSocketConfig.java @@ -6,31 +6,46 @@ import org.springframework.web.socket.config.annotation.AbstractWebSocketMessage import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; import org.springframework.web.socket.config.annotation.StompEndpointRegistry; -@Configuration -@EnableWebSocketMessageBroker /** * 通过EnableWebSocketMessageBroker 开启使用STOMP协议来传输基于代理(message broker)的消息,此时浏览器支持使用@MessageMapping 就像支持@RequestMapping一样。 */ +@Configuration +@EnableWebSocketMessageBroker +public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { -public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer{ - - /** - * endPoint 注册协议节点,并映射指定的URl - * @param registry - */ + // /** +// * endPoint 注册协议节点,并映射指定的URl +// * +// * @param registry +// */ +// @Override +// public void registerStompEndpoints(StompEndpointRegistry registry) { +// //注册一个Stomp 协议的endpoint,并指定 SockJS协议。 +// registry.addEndpoint("/endpointWisely").withSockJS(); +// } +// +// /** +// * 配置消息代理(message broker) +// * +// * @param registry +// */ +// @Override +// public void configureMessageBroker(MessageBrokerRegistry registry) { +// //广播式应配置一个/topic 消息代理 +// registry.enableSimpleBroker("/topic"); +// } @Override - public void registerStompEndpoints(StompEndpointRegistry registry) { - //注册一个Stomp 协议的endpoint,并指定 SockJS协议。 - registry.addEndpoint("/endpointWisely").withSockJS(); + public void registerStompEndpoints(StompEndpointRegistry registry) { //endPoint 注册协议节点,并映射指定的URl + + //注册一个名字为"endpointChat" 的endpoint,并指定 SockJS协议。 点对点-用 + registry.addEndpoint("/endpointChat").withSockJS(); } - /** - * 配置消息代理(message broker) - * @param registry - */ + @Override - public void configureMessageBroker(MessageBrokerRegistry registry) { - //广播式应配置一个/topic 消息代理 - registry.enableSimpleBroker("/topic"); + public void configureMessageBroker(MessageBrokerRegistry registry) {//配置消息代理(message broker) + //点对点式增加一个/queue 消息代理 + registry.enableSimpleBroker("/queue", "/topic"); + } } diff --git a/bootdo/src/main/java/com/bootdo/oa/controller/NotifyController.java b/bootdo/src/main/java/com/bootdo/oa/controller/NotifyController.java index d023e63..cb4c838 100644 --- a/bootdo/src/main/java/com/bootdo/oa/controller/NotifyController.java +++ b/bootdo/src/main/java/com/bootdo/oa/controller/NotifyController.java @@ -15,6 +15,7 @@ import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; +import java.security.Principal; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -169,4 +170,7 @@ public class NotifyController extends BaseController { model.addAttribute("notify", notify); return "oa/notify/read"; } + + + } diff --git a/bootdo/src/main/java/com/bootdo/oa/controller/WebSocketController.java b/bootdo/src/main/java/com/bootdo/oa/controller/WebSocketController.java index 69446cd..6f0ca6a 100644 --- a/bootdo/src/main/java/com/bootdo/oa/controller/WebSocketController.java +++ b/bootdo/src/main/java/com/bootdo/oa/controller/WebSocketController.java @@ -1,48 +1,60 @@ -//package com.bootdo.oa.controller; -// -//import org.springframework.beans.factory.annotation.Autowired; -//import org.springframework.messaging.handler.annotation.MessageMapping; -//import org.springframework.messaging.handler.annotation.SendTo; -//import org.springframework.messaging.simp.SimpMessagingTemplate; -//import org.springframework.stereotype.Controller; -//import org.springframework.web.bind.annotation.GetMapping; -//import org.springframework.web.bind.annotation.RequestMapping; -//import org.springframework.web.bind.annotation.ResponseBody; -// -//import com.bootdo.common.task.WelcomeTask; -//import com.bootdo.common.utils.R; -//import com.bootdo.oa.domain.Message; -//import com.bootdo.oa.domain.Response; -// -//@Controller -//public class WebSocketController { -// @Autowired -// SimpMessagingTemplate template; -// -// @Autowired -// WelcomeTask welcomeTask; -// -// @MessageMapping("/welcome") // 浏览器发送请求通过@messageMapping 映射/welcome 这个地址。 -// @SendTo("/topic/getResponse") // 服务器端有消息时,会订阅@SendTo 中的路径的浏览器发送消息。 -// public Response say(Message message) throws Exception { -// Thread.sleep(1000); -// return new Response("Welcome, " + message.getName() + "!"); -// } -// -// @GetMapping("/test") -// String test() { -// return "test"; -// } -// -// @RequestMapping("/welcome") -// @ResponseBody -// public R say02() { -// try { -// welcomeTask.sayWelcome(); -// } catch (Exception e) { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// return R.ok(); -// } -//} \ No newline at end of file +package com.bootdo.oa.controller; + +import com.bootdo.system.service.SessionService; +import org.apache.shiro.session.mgt.eis.SessionDAO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.handler.annotation.MessageMapping; +import org.springframework.messaging.handler.annotation.SendTo; +import org.springframework.messaging.simp.SimpMessagingTemplate; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import com.bootdo.common.utils.R; +import com.bootdo.oa.domain.Message; +import com.bootdo.oa.domain.Response; + +import java.security.Principal; + +@Controller +public class WebSocketController { + @Autowired + SimpMessagingTemplate template; + + @Autowired + SessionService sessionService; + + /*@Autowired + WelcomeTask welcomeTask; + + @MessageMapping("/welcome") // 浏览器发送请求通过@messageMapping 映射/welcome 这个地址。 + @SendTo("/topic/getResponse") // 服务器端有消息时,会订阅@SendTo 中的路径的浏览器发送消息。 + public Response say(Message message) throws Exception { + Thread.sleep(1000); + return new Response("Welcome, " + message.getName() + "!"); + } + + @GetMapping("/test") + String test() { + return "test"; + } + + @RequestMapping("/welcome") + @ResponseBody + public R say02() { + try { + welcomeTask.sayWelcome(); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return R.ok(); + }*/ +// @ResponseBody +// @GetMapping("/chat") +// public String handleChat(Principal principal, String msg) { +// template.convertAndSendToUser(sessionService.listPrincipal().get(0).toString(), "/queue/notifications", principal.getName() + "给您发来了消息:" + msg); +// return sessionService.listPrincipal().get(0).toString(); +// } +} \ No newline at end of file diff --git a/bootdo/src/main/java/com/bootdo/oa/service/impl/NotifyServiceImpl.java b/bootdo/src/main/java/com/bootdo/oa/service/impl/NotifyServiceImpl.java index 6f67506..cd22b86 100644 --- a/bootdo/src/main/java/com/bootdo/oa/service/impl/NotifyServiceImpl.java +++ b/bootdo/src/main/java/com/bootdo/oa/service/impl/NotifyServiceImpl.java @@ -1,14 +1,18 @@ package com.bootdo.oa.service.impl; +import com.bootdo.system.domain.UserDO; +import com.bootdo.system.service.SessionService; +import org.apache.shiro.session.Session; +import org.apache.shiro.session.mgt.eis.SessionDAO; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; import com.bootdo.common.service.DictService; import com.bootdo.common.utils.DateUtils; @@ -23,99 +27,104 @@ import com.bootdo.system.dao.UserDao; @Service public class NotifyServiceImpl implements NotifyService { - @Autowired - private NotifyDao notifyDao; - @Autowired - private NotifyRecordDao recordDao; - @Autowired - private UserDao userDao; - @Autowired - private DictService dictService; + @Autowired + private NotifyDao notifyDao; + @Autowired + private NotifyRecordDao recordDao; + @Autowired + private UserDao userDao; + @Autowired + private DictService dictService; + @Autowired + private SessionService sessionService; + @Autowired + private SimpMessagingTemplate template; - @Override - public NotifyDO get(Long id) { - NotifyDO rDO = notifyDao.get(id); - rDO.setType(dictService.getName("oa_notify_type", rDO.getType()) ); - return rDO; - } + @Override + public NotifyDO get(Long id) { + NotifyDO rDO = notifyDao.get(id); + rDO.setType(dictService.getName("oa_notify_type", rDO.getType())); + return rDO; + } - @Override - public List list(Map map) { - List notifys = notifyDao.list(map); - for (NotifyDO notifyDO : notifys) { - notifyDO.setType(dictService.getName("oa_notify_type", notifyDO.getType()) ); - } - return notifys; - } + @Override + public List list(Map map) { + List notifys = notifyDao.list(map); + for (NotifyDO notifyDO : notifys) { + notifyDO.setType(dictService.getName("oa_notify_type", notifyDO.getType())); + } + return notifys; + } - @Override - public int count(Map map) { - return notifyDao.count(map); - } + @Override + public int count(Map map) { + return notifyDao.count(map); + } - @Transactional(rollbackFor = Exception.class) - @Override - public int save(NotifyDO notify) { - notify.setUpdateDate(new Date()); - int r = notifyDao.save(notify); - // 保存到接受者列表中 - Long[] userIds = notify.getUserIds(); - Long notifyId = notify.getId(); - List records = new ArrayList<>(); - for (Long userId : userIds) { - NotifyRecordDO record = new NotifyRecordDO(); - record.setNotifyId(notifyId); - record.setUserId(userId); - record.setIsRead(0); - records.add(record); - } - recordDao.batchSave(records); - return r; + @Transactional(rollbackFor = Exception.class) + @Override + public int save(NotifyDO notify) { + notify.setUpdateDate(new Date()); + int r = notifyDao.save(notify); + // 保存到接受者列表中 + Long[] userIds = notify.getUserIds(); + Long notifyId = notify.getId(); + List records = new ArrayList<>(); + for (Long userId : userIds) { + NotifyRecordDO record = new NotifyRecordDO(); + record.setNotifyId(notifyId); + record.setUserId(userId); + record.setIsRead(0); + records.add(record); + } + recordDao.batchSave(records); + //给在线用户发送通知 + ThreadPoolExecutor executor = new ThreadPoolExecutor(1,1,0, TimeUnit.MILLISECONDS,new LinkedBlockingDeque<>()); + executor.execute(new Runnable() { + @Override + public void run() { + for (UserDO userDO : sessionService.listOnlineUser()) { + for (Long userId : userIds) { + if (userId.equals(userDO.getUserId())) { + template.convertAndSendToUser(userDO.toString(), "/queue/notifications", "新消息:" + notify.getTitle()); + } + } + } + } + }); + executor.shutdown(); + return r; + } - } + @Override + public int update(NotifyDO notify) { + return notifyDao.update(notify); + } - @Override - public int update(NotifyDO notify) { - return notifyDao.update(notify); - } + @Transactional + @Override + public int remove(Long id) { + recordDao.removeByNotifbyId(id); + return notifyDao.remove(id); + } - @Transactional - @Override - public int remove(Long id) { - recordDao.removeByNotifbyId(id); - return notifyDao.remove(id); - } + @Transactional + @Override + public int batchRemove(Long[] ids) { + recordDao.batchRemoveByNotifbyId(ids); + return notifyDao.batchRemove(ids); + } - @Transactional - @Override - public int batchRemove(Long[] ids) { - recordDao.batchRemoveByNotifbyId(ids); - return notifyDao.batchRemove(ids); - } -// @Override -// public Map message(Long userId) { -// Map param = new HashMap<>(16); -// Map map = new HashMap<>(16); -// param.put("userId", userId); -// param.put("isRead", 0); -// int messageNum = recordDao.count(param); -// Long[] notifyIds = recordDao.listNotifyIds(param); -// List messages = notifyDao.listByIds(notifyIds); -// map.put("messageNum", messageNum); -// map.put("messages", messages); -// return map; -// } - - @Override - public PageUtils selfList(Map map) { - List rows = notifyDao.listDTO(map); - for (NotifyDTO notifyDTO : rows) { - notifyDTO.setBefore(DateUtils.getTimeBefore(notifyDTO.getUpdateDate())); - notifyDTO.setSender(userDao.get(notifyDTO.getCreateBy()).getName()); - } - PageUtils page = new PageUtils(rows, notifyDao.countDTO(map)); - return page; - } + @Override + public PageUtils selfList(Map map) { + List rows = notifyDao.listDTO(map); + for (NotifyDTO notifyDTO : rows) { + notifyDTO.setBefore(DateUtils.getTimeBefore(notifyDTO.getUpdateDate())); + notifyDTO.setSender(userDao.get(notifyDTO.getCreateBy()).getName()); + } + PageUtils page = new PageUtils(rows, notifyDao.countDTO(map)); + return page; + } } diff --git a/bootdo/src/main/java/com/bootdo/system/controller/SessionController.java b/bootdo/src/main/java/com/bootdo/system/controller/SessionController.java index b811d88..48e5a87 100644 --- a/bootdo/src/main/java/com/bootdo/system/controller/SessionController.java +++ b/bootdo/src/main/java/com/bootdo/system/controller/SessionController.java @@ -1,5 +1,6 @@ package com.bootdo.system.controller; +import java.security.Principal; import java.util.Collection; import java.util.List; @@ -51,4 +52,6 @@ public class SessionController { public Collection sessionList() { return sessionService.sessionList(); } + + } diff --git a/bootdo/src/main/java/com/bootdo/system/service/SessionService.java b/bootdo/src/main/java/com/bootdo/system/service/SessionService.java index a46cf1c..8e91721 100644 --- a/bootdo/src/main/java/com/bootdo/system/service/SessionService.java +++ b/bootdo/src/main/java/com/bootdo/system/service/SessionService.java @@ -1,8 +1,11 @@ package com.bootdo.system.service; +import java.io.PrintStream; +import java.security.Principal; import java.util.Collection; import java.util.List; +import com.bootdo.system.domain.UserDO; import org.apache.shiro.session.Session; import org.springframework.stereotype.Service; @@ -12,6 +15,8 @@ import com.bootdo.system.domain.UserOnline; public interface SessionService { List list(); + List listOnlineUser(); + Collection sessionList(); boolean forceLogout(String sessionId); diff --git a/bootdo/src/main/java/com/bootdo/system/service/impl/SessionServiceImpl.java b/bootdo/src/main/java/com/bootdo/system/service/impl/SessionServiceImpl.java index d472fc1..fc4507c 100644 --- a/bootdo/src/main/java/com/bootdo/system/service/impl/SessionServiceImpl.java +++ b/bootdo/src/main/java/com/bootdo/system/service/impl/SessionServiceImpl.java @@ -10,56 +10,79 @@ import org.apache.shiro.subject.support.DefaultSubjectContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.security.Principal; import java.util.ArrayList; import java.util.Collection; import java.util.List; /** * 待完善 - * - * @author bootdo * + * @author bootdo */ @Service public class SessionServiceImpl implements SessionService { - @Autowired - private SessionDAO sessionDAO; + private final SessionDAO sessionDAO; + + @Autowired + public SessionServiceImpl(SessionDAO sessionDAO) { + this.sessionDAO = sessionDAO; + } + + @Override + public List list() { + List list = new ArrayList<>(); + Collection sessions = sessionDAO.getActiveSessions(); + for (Session session : sessions) { + UserOnline userOnline = new UserOnline(); + UserDO userDO = new UserDO(); + SimplePrincipalCollection principalCollection = new SimplePrincipalCollection(); + if (session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY) == null) { + continue; + } else { + principalCollection = (SimplePrincipalCollection) session + .getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY); + userDO = (UserDO) principalCollection.getPrimaryPrincipal(); + userOnline.setUsername(userDO.getUsername()); + } + userOnline.setId((String) session.getId()); + userOnline.setHost(session.getHost()); + userOnline.setStartTimestamp(session.getStartTimestamp()); + userOnline.setLastAccessTime(session.getLastAccessTime()); + userOnline.setTimeout(session.getTimeout()); + list.add(userOnline); + } + return list; + } - @Override - public List list() { - List list = new ArrayList<>(); - Collection sessions = sessionDAO.getActiveSessions(); - for (Session session : sessions) { - UserOnline userOnline = new UserOnline(); - UserDO userDO = new UserDO(); - SimplePrincipalCollection principalCollection = new SimplePrincipalCollection(); - if (session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY) == null) { - continue; - } else { - principalCollection = (SimplePrincipalCollection) session - .getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY); - userDO = (UserDO) principalCollection.getPrimaryPrincipal(); - userOnline.setUsername(userDO.getUsername()); - } - userOnline.setId((String) session.getId()); - userOnline.setHost(session.getHost()); - userOnline.setStartTimestamp(session.getStartTimestamp()); - userOnline.setLastAccessTime(session.getLastAccessTime()); - userOnline.setTimeout(session.getTimeout()); - list.add(userOnline); - } - return list; - } + @Override + public List listOnlineUser() { + List list = new ArrayList<>(); + UserDO userDO; + Collection sessions = sessionDAO.getActiveSessions(); + for (Session session : sessions) { + SimplePrincipalCollection principalCollection = new SimplePrincipalCollection(); + if (session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY) == null) { + continue; + } else { + principalCollection = (SimplePrincipalCollection) session + .getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY); + userDO = (UserDO) principalCollection.getPrimaryPrincipal(); + list.add(userDO); + } + } + return list; + } - @Override - public Collection sessionList() { - return sessionDAO.getActiveSessions(); - } + @Override + public Collection sessionList() { + return sessionDAO.getActiveSessions(); + } - @Override - public boolean forceLogout(String sessionId) { - Session session = sessionDAO.readSession(sessionId); - session.setTimeout(0); - return true; - } + @Override + public boolean forceLogout(String sessionId) { + Session session = sessionDAO.readSession(sessionId); + session.setTimeout(0); + return true; + } } diff --git a/bootdo/src/main/resources/mybatis/oa/NotifyMapper.xml b/bootdo/src/main/resources/mybatis/oa/NotifyMapper.xml index 1756cba..e223632 100644 --- a/bootdo/src/main/resources/mybatis/oa/NotifyMapper.xml +++ b/bootdo/src/main/resources/mybatis/oa/NotifyMapper.xml @@ -151,7 +151,7 @@ and r.user_id = #{userId} and r.read_date = #{readDate} - order by is_read ASC, create_date DESC + order by is_read ASC, update_date DESC limit #{offset}, #{limit} diff --git a/bootdo/src/main/resources/templates/index_v1.html b/bootdo/src/main/resources/templates/index_v1.html index e5d6576..f8dd537 100644 --- a/bootdo/src/main/resources/templates/index_v1.html +++ b/bootdo/src/main/resources/templates/index_v1.html @@ -306,11 +306,38 @@ }); function connect() { - var socket = new SockJS('/endpointWisely'); //链接SockJS 的endpoint 名称为"/endpointWisely" - stompClient = Stomp.over(socket);//使用stomp子协议的WebSocket 客户端 - stompClient.connect({}, function (frame) {//链接Web Socket的服务端。 - console.log('Connected: ' + frame); - stompClient.subscribe('/topic/getResponse', function (response) { //订阅/topic/getResponse 目标发送的消息。这个是在控制器的@SendTo中定义的。 +// var socket = new SockJS('/endpointWisely'); //链接SockJS 的endpoint 名称为"/endpointWisely" +// stompClient = Stomp.over(socket);//使用stomp子协议的WebSocket 客户端 +// stompClient.connect({}, function (frame) {//链接Web Socket的服务端。 +// stompClient.subscribe('/topic/getResponse', function (response) { //订阅/topic/getResponse 目标发送的消息。这个是在控制器的@SendTo中定义的。 +// toastr.options = { +// "closeButton": true, +// "debug": false, +// "progressBar": true, +// "positionClass": "toast-bottom-right", +// "onclick": null, +// "showDuration": "400", +// "hideDuration": "1000", +// "timeOut": "7000", +// "extendedTimeOut": "1000", +// "showEasing": "swing", +// "hideEasing": "linear", +// "showMethod": "fadeIn", +// "hideMethod": "fadeOut" +// } +// toastr.info(JSON.parse(response.body).responseMessage); +// }); +// }); + //链接endpoint名称为 "/endpointChat" 的endpoint。 + var sock = new SockJS("/endpointChat"); + var stomp = Stomp.over(sock); + stomp.connect('guest', 'guest', function(frame) { + + /**
 订阅了/user/queue/notifications 发送的消息,这里雨在控制器的 convertAndSendToUser 定义的地址保持一致,
 + * 这里多用了一个/user,并且这个user 是必须的,使用user 才会发送消息到指定的用户。
 + * */ + stomp.subscribe("/user/queue/notifications", handleNotification); + stomp.subscribe('/topic/getResponse', function (response) { //订阅/topic/getResponse 目标发送的消息。这个是在控制器的@SendTo中定义的。 toastr.options = { "closeButton": true, "debug": false, @@ -329,6 +356,10 @@ toastr.info(JSON.parse(response.body).responseMessage); }); }); + function handleNotification(message) { + wrapper.notify(); + toastr.info(message.body); + } } var wrapper = new Vue({ @@ -350,7 +381,7 @@ title: '个人设置', maxmin: true, shadeClose: false, - area: ['1024px', '720px'], + area: ['800px', '600px'], content: '/sys/user/personal' }); } diff --git a/bootdo/src/main/resources/templates/login.html b/bootdo/src/main/resources/templates/login.html index 6e5a908..182db6d 100644 --- a/bootdo/src/main/resources/templates/login.html +++ b/bootdo/src/main/resources/templates/login.html @@ -59,7 +59,7 @@

用户登录

欢迎登录bootdo后台管理系统

+ value="test"/> -- Gitee From b3461c95a242312f2bb0b5385d50a056e048016d Mon Sep 17 00:00:00 2001 From: lcg0124 <1992lcg@163.com> Date: Tue, 2 Jan 2018 08:54:09 +0800 Subject: [PATCH 05/18] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=80=9A=E7=9F=A5?= =?UTF-8?q?=E5=85=AC=E5=91=8A=E5=9C=A8=E7=BA=BF=E6=B6=88=E6=81=AF=E6=8F=90?= =?UTF-8?q?=E9=86=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bootdo/src/main/resources/templates/login.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bootdo/src/main/resources/templates/login.html b/bootdo/src/main/resources/templates/login.html index 182db6d..c7bf23f 100644 --- a/bootdo/src/main/resources/templates/login.html +++ b/bootdo/src/main/resources/templates/login.html @@ -59,9 +59,9 @@

用户登录

欢迎登录bootdo后台管理系统

+ value="admin"/> + class="form-control pword m-b" value="123456"/> -
- -
- -
-
+
diff --git a/bootdo/src/main/resources/templates/common/sysDict/edit.html b/bootdo/src/main/resources/templates/common/sysDict/edit.html index 9a19c2c..45e9d19 100644 --- a/bootdo/src/main/resources/templates/common/sysDict/edit.html +++ b/bootdo/src/main/resources/templates/common/sysDict/edit.html @@ -63,13 +63,6 @@ th:value="${sysDict.remarks}" class="form-control" type="text">
-
- -
- -
-
diff --git a/bootdo/src/main/resources/templates/index_v1.html b/bootdo/src/main/resources/templates/index_v1.html index f8dd537..eef180c 100644 --- a/bootdo/src/main/resources/templates/index_v1.html +++ b/bootdo/src/main/resources/templates/index_v1.html @@ -306,29 +306,6 @@ }); function connect() { -// var socket = new SockJS('/endpointWisely'); //链接SockJS 的endpoint 名称为"/endpointWisely" -// stompClient = Stomp.over(socket);//使用stomp子协议的WebSocket 客户端 -// stompClient.connect({}, function (frame) {//链接Web Socket的服务端。 -// stompClient.subscribe('/topic/getResponse', function (response) { //订阅/topic/getResponse 目标发送的消息。这个是在控制器的@SendTo中定义的。 -// toastr.options = { -// "closeButton": true, -// "debug": false, -// "progressBar": true, -// "positionClass": "toast-bottom-right", -// "onclick": null, -// "showDuration": "400", -// "hideDuration": "1000", -// "timeOut": "7000", -// "extendedTimeOut": "1000", -// "showEasing": "swing", -// "hideEasing": "linear", -// "showMethod": "fadeIn", -// "hideMethod": "fadeOut" -// } -// toastr.info(JSON.parse(response.body).responseMessage); -// }); -// }); - //链接endpoint名称为 "/endpointChat" 的endpoint。 var sock = new SockJS("/endpointChat"); var stomp = Stomp.over(sock); stomp.connect('guest', 'guest', function(frame) { diff --git a/bootdo/src/main/resources/templates/login.html b/bootdo/src/main/resources/templates/login.html index c7bf23f..6e5a908 100644 --- a/bootdo/src/main/resources/templates/login.html +++ b/bootdo/src/main/resources/templates/login.html @@ -61,7 +61,7 @@ + class="form-control pword m-b" value="111111"/> diff --git a/bootdo/src/main/resources/templates/act/process/add.html b/bootdo/src/main/resources/templates/act/process/add.html index 61c722d..49fa007 100644 --- a/bootdo/src/main/resources/templates/act/process/add.html +++ b/bootdo/src/main/resources/templates/act/process/add.html @@ -7,7 +7,7 @@
-
+
@@ -15,7 +15,7 @@
- +
@@ -42,12 +42,6 @@
-测试代码 - - - - -
diff --git a/bootdo/src/main/resources/templates/system/dept/dept.html b/bootdo/src/main/resources/templates/system/dept/dept.html index 5749613..fa8de54 100644 --- a/bootdo/src/main/resources/templates/system/dept/dept.html +++ b/bootdo/src/main/resources/templates/system/dept/dept.html @@ -3,60 +3,67 @@ -
-
-
-
-
-
- -
- - - -
-
-
-
-
-
-
- -
- -
-
- -
-
- -
-
- -
-
- -
- -
- +
+
+
+
+
+
+ + +
+
+ +
+ +
+ +
+
+ +
+
+
+
+
+ +
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+ +
+ \ No newline at end of file -- Gitee From 311c00d142731d3e0843f6f086bcb771f25e43b1 Mon Sep 17 00:00:00 2001 From: lcg0124 <1992lcg@163.com> Date: Mon, 8 Jan 2018 13:17:59 +0800 Subject: [PATCH 14/18] =?UTF-8?q?=E5=8E=BB=E9=99=A4redis-shiro=20jar?= =?UTF-8?q?=E4=BE=9D=E8=B5=96=EF=BC=8C=E4=BB=A3=E7=A0=81=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bootdo/pom.xml | 10 +- .../controller/ProcessController.java | 10 +- .../bootdo/common/redis/shiro/RedisCache.java | 195 +++++++++++++++++ .../common/redis/shiro/RedisCacheManager.java | 78 +++++++ .../common/redis/shiro/RedisManager.java | 201 ++++++++++++++++++ .../common/redis/shiro/RedisSessionDAO.java | 140 ++++++++++++ .../common/redis/shiro/SerializeUtils.java | 89 ++++++++ 7 files changed, 717 insertions(+), 6 deletions(-) create mode 100644 bootdo/src/main/java/com/bootdo/common/redis/shiro/RedisCache.java create mode 100644 bootdo/src/main/java/com/bootdo/common/redis/shiro/RedisCacheManager.java create mode 100644 bootdo/src/main/java/com/bootdo/common/redis/shiro/RedisManager.java create mode 100644 bootdo/src/main/java/com/bootdo/common/redis/shiro/RedisSessionDAO.java create mode 100644 bootdo/src/main/java/com/bootdo/common/redis/shiro/SerializeUtils.java diff --git a/bootdo/pom.xml b/bootdo/pom.xml index fd5fe83..fe1422e 100644 --- a/bootdo/pom.xml +++ b/bootdo/pom.xml @@ -208,11 +208,11 @@ 1.9.2 - - org.crazycake - shiro-redis - 2.4.2.1-RELEASE - + + + + + diff --git a/bootdo/src/main/java/com/bootdo/activiti/controller/ProcessController.java b/bootdo/src/main/java/com/bootdo/activiti/controller/ProcessController.java index 4e54689..056808a 100644 --- a/bootdo/src/main/java/com/bootdo/activiti/controller/ProcessController.java +++ b/bootdo/src/main/java/com/bootdo/activiti/controller/ProcessController.java @@ -2,6 +2,8 @@ package com.bootdo.activiti.controller; import com.bootdo.activiti.service.ProcessService; import com.bootdo.activiti.vo.ProcessVO; +import com.bootdo.common.config.Constant; +import com.bootdo.common.controller.BaseController; import com.bootdo.common.utils.PageUtils; import com.bootdo.common.utils.R; import org.activiti.engine.ActivitiException; @@ -27,7 +29,7 @@ import java.util.zip.ZipInputStream; @RequestMapping("activiti/process") @RestController -public class ProcessController { +public class ProcessController extends BaseController{ @Autowired private RepositoryService repositoryService; @@ -114,6 +116,9 @@ public class ProcessController { */ @RequestMapping(value = "/convertToModel/{procDefId}") public R convertToModel(@PathVariable("procDefId") String procDefId, RedirectAttributes redirectAttributes) throws UnsupportedEncodingException, XMLStreamException { + if (Constant.DEMO_ACCOUNT.equals(getUsername())) { + return R.error(1, "演示系统不允许修改,完整体验请部署程序"); + } org.activiti.engine.repository.Model modelData = null; try { modelData = processService.convertToModel(procDefId); @@ -137,6 +142,9 @@ public class ProcessController { @PostMapping("/remove") public R remove(String id){ + if (Constant.DEMO_ACCOUNT.equals(getUsername())) { + return R.error(1, "演示系统不允许修改,完整体验请部署程序"); + } repositoryService.deleteDeployment(id,true); return R.ok(); } diff --git a/bootdo/src/main/java/com/bootdo/common/redis/shiro/RedisCache.java b/bootdo/src/main/java/com/bootdo/common/redis/shiro/RedisCache.java new file mode 100644 index 0000000..c7be6b1 --- /dev/null +++ b/bootdo/src/main/java/com/bootdo/common/redis/shiro/RedisCache.java @@ -0,0 +1,195 @@ +package com.bootdo.common.redis.shiro; + +/** + * @author bootdo 1992lcg@163.com + * @version V1.0 + */ +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.shiro.cache.Cache; +import org.apache.shiro.cache.CacheException; +import org.apache.shiro.util.CollectionUtils; +import org.crazycake.shiro.RedisManager; +import org.crazycake.shiro.SerializeUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class RedisCache implements Cache { + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + /** + * The wrapped Jedis instance. + */ + private RedisManager cache; + + /** + * The Redis key prefix for the sessions + */ + private String keyPrefix = "shiro_redis_session:"; + + /** + * Returns the Redis session keys + * prefix. + * @return The prefix + */ + public String getKeyPrefix() { + return keyPrefix; + } + + /** + * Sets the Redis sessions key + * prefix. + * @param keyPrefix The prefix + */ + public void setKeyPrefix(String keyPrefix) { + this.keyPrefix = keyPrefix; + } + + /** + * 通过一个JedisManager实例构造RedisCache + */ + public RedisCache(RedisManager cache){ + if (cache == null) { + throw new IllegalArgumentException("Cache argument cannot be null."); + } + this.cache = cache; + } + + /** + * Constructs a cache instance with the specified + * Redis manager and using a custom key prefix. + * @param cache The cache manager instance + * @param prefix The Redis key prefix + */ + public RedisCache(RedisManager cache, + String prefix){ + + this( cache ); + + // set the prefix + this.keyPrefix = prefix; + } + + /** + * 获得byte[]型的key + * @param key + * @return + */ + private byte[] getByteKey(K key){ + if(key instanceof String){ + String preKey = this.keyPrefix + key; + return preKey.getBytes(); + }else{ + return SerializeUtils.serialize(key); + } + } + + @Override + public V get(K key) throws CacheException { + logger.debug("根据key从Redis中获取对象 key [" + key + "]"); + try { + if (key == null) { + return null; + }else{ + byte[] rawValue = cache.get(getByteKey(key)); + @SuppressWarnings("unchecked") + V value = (V)SerializeUtils.deserialize(rawValue); + return value; + } + } catch (Throwable t) { + throw new CacheException(t); + } + + } + + @Override + public V put(K key, V value) throws CacheException { + logger.debug("根据key从存储 key [" + key + "]"); + try { + cache.set(getByteKey(key), SerializeUtils.serialize(value)); + return value; + } catch (Throwable t) { + throw new CacheException(t); + } + } + + @Override + public V remove(K key) throws CacheException { + logger.debug("从redis中删除 key [" + key + "]"); + try { + V previous = get(key); + cache.del(getByteKey(key)); + return previous; + } catch (Throwable t) { + throw new CacheException(t); + } + } + + @Override + public void clear() throws CacheException { + logger.debug("从redis中删除所有元素"); + try { + cache.flushDB(); + } catch (Throwable t) { + throw new CacheException(t); + } + } + + @Override + public int size() { + try { + Long longSize = new Long(cache.dbSize()); + return longSize.intValue(); + } catch (Throwable t) { + throw new CacheException(t); + } + } + + @SuppressWarnings("unchecked") + @Override + public Set keys() { + try { + Set keys = cache.keys(this.keyPrefix + "*"); + if (CollectionUtils.isEmpty(keys)) { + return Collections.emptySet(); + }else{ + Set newKeys = new HashSet(); + for(byte[] key:keys){ + newKeys.add((K)key); + } + return newKeys; + } + } catch (Throwable t) { + throw new CacheException(t); + } + } + + @Override + public Collection values() { + try { + Set keys = cache.keys(this.keyPrefix + "*"); + if (!CollectionUtils.isEmpty(keys)) { + List values = new ArrayList(keys.size()); + for (byte[] key : keys) { + @SuppressWarnings("unchecked") + V value = get((K)key); + if (value != null) { + values.add(value); + } + } + return Collections.unmodifiableList(values); + } else { + return Collections.emptyList(); + } + } catch (Throwable t) { + throw new CacheException(t); + } + } + +} diff --git a/bootdo/src/main/java/com/bootdo/common/redis/shiro/RedisCacheManager.java b/bootdo/src/main/java/com/bootdo/common/redis/shiro/RedisCacheManager.java new file mode 100644 index 0000000..c7a2d7a --- /dev/null +++ b/bootdo/src/main/java/com/bootdo/common/redis/shiro/RedisCacheManager.java @@ -0,0 +1,78 @@ +package com.bootdo.common.redis.shiro; + +/** + * @author bootdo 1992lcg@163.com + * @version V1.0 + */ +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import org.apache.shiro.cache.Cache; +import org.apache.shiro.cache.CacheException; +import org.apache.shiro.cache.CacheManager; +import org.crazycake.shiro.RedisManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class RedisCacheManager implements CacheManager { + + private static final Logger logger = LoggerFactory + .getLogger(RedisCacheManager.class); + + // fast lookup by name map + private final ConcurrentMap caches = new ConcurrentHashMap(); + + private RedisManager redisManager; + + /** + * The Redis key prefix for caches + */ + private String keyPrefix = "shiro_redis_cache:"; + + /** + * Returns the Redis session keys + * prefix. + * @return The prefix + */ + public String getKeyPrefix() { + return keyPrefix; + } + + /** + * Sets the Redis sessions key + * prefix. + * @param keyPrefix The prefix + */ + public void setKeyPrefix(String keyPrefix) { + this.keyPrefix = keyPrefix; + } + + @Override + public Cache getCache(String name) throws CacheException { + logger.debug("获取名称为: " + name + " 的RedisCache实例"); + + Cache c = caches.get(name); + + if (c == null) { + + // initialize the Redis manager instance + redisManager.init(); + + // create a new cache instance + c = new RedisCache(redisManager, keyPrefix); + + // add it to the cache collection + caches.put(name, c); + } + return c; + } + + public RedisManager getRedisManager() { + return redisManager; + } + + public void setRedisManager(RedisManager redisManager) { + this.redisManager = redisManager; + } + +} diff --git a/bootdo/src/main/java/com/bootdo/common/redis/shiro/RedisManager.java b/bootdo/src/main/java/com/bootdo/common/redis/shiro/RedisManager.java new file mode 100644 index 0000000..8f50ea8 --- /dev/null +++ b/bootdo/src/main/java/com/bootdo/common/redis/shiro/RedisManager.java @@ -0,0 +1,201 @@ +package com.bootdo.common.redis.shiro; + +/** + * @author bootdo 1992lcg@163.com + * @version V1.0 + */ +import java.util.Set; + +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.JedisPoolConfig; + +public class RedisManager { + + private String host = "127.0.0.1"; + + private int port = 6379; + + // 0 - never expire + private int expire = 0; + + //timeout for jedis try to connect to redis server, not expire time! In milliseconds + private int timeout = 0; + + private String password = ""; + + private static JedisPool jedisPool = null; + + public RedisManager(){ + + } + + /** + * 初始化方法 + */ + public void init(){ + if(jedisPool == null){ + if(password != null && !"".equals(password)){ + jedisPool = new JedisPool(new JedisPoolConfig(), host, port, timeout, password); + }else if(timeout != 0){ + jedisPool = new JedisPool(new JedisPoolConfig(), host, port,timeout); + }else{ + jedisPool = new JedisPool(new JedisPoolConfig(), host, port); + } + + } + } + + /** + * get value from redis + * @param key + * @return + */ + public byte[] get(byte[] key){ + byte[] value = null; + Jedis jedis = jedisPool.getResource(); + try{ + value = jedis.get(key); + }finally{ + jedisPool.returnResource(jedis); + } + return value; + } + + /** + * set + * @param key + * @param value + * @return + */ + public byte[] set(byte[] key,byte[] value){ + Jedis jedis = jedisPool.getResource(); + try{ + jedis.set(key,value); + if(this.expire != 0){ + jedis.expire(key, this.expire); + } + }finally{ + jedisPool.returnResource(jedis); + } + return value; + } + + /** + * set + * @param key + * @param value + * @param expire + * @return + */ + public byte[] set(byte[] key,byte[] value,int expire){ + Jedis jedis = jedisPool.getResource(); + try{ + jedis.set(key,value); + if(expire != 0){ + jedis.expire(key, expire); + } + }finally{ + jedisPool.returnResource(jedis); + } + return value; + } + + /** + * del + * @param key + */ + public void del(byte[] key){ + Jedis jedis = jedisPool.getResource(); + try{ + jedis.del(key); + }finally{ + jedisPool.returnResource(jedis); + } + } + + /** + * flush + */ + public void flushDB(){ + Jedis jedis = jedisPool.getResource(); + try{ + jedis.flushDB(); + }finally{ + jedisPool.returnResource(jedis); + } + } + + /** + * size + */ + public Long dbSize(){ + Long dbSize = 0L; + Jedis jedis = jedisPool.getResource(); + try{ + dbSize = jedis.dbSize(); + }finally{ + jedisPool.returnResource(jedis); + } + return dbSize; + } + + /** + * keys + * @param regex + * @return + */ + public Set keys(String pattern){ + Set keys = null; + Jedis jedis = jedisPool.getResource(); + try{ + keys = jedis.keys(pattern.getBytes()); + }finally{ + jedisPool.returnResource(jedis); + } + return keys; + } + + 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 int getExpire() { + return expire; + } + + public void setExpire(int expire) { + this.expire = expire; + } + + public int getTimeout() { + return timeout; + } + + public void setTimeout(int timeout) { + this.timeout = timeout; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + + +} diff --git a/bootdo/src/main/java/com/bootdo/common/redis/shiro/RedisSessionDAO.java b/bootdo/src/main/java/com/bootdo/common/redis/shiro/RedisSessionDAO.java new file mode 100644 index 0000000..39bc964 --- /dev/null +++ b/bootdo/src/main/java/com/bootdo/common/redis/shiro/RedisSessionDAO.java @@ -0,0 +1,140 @@ +package com.bootdo.common.redis.shiro; + +import org.apache.shiro.session.Session; +import org.apache.shiro.session.UnknownSessionException; +import org.apache.shiro.session.mgt.eis.AbstractSessionDAO; +import org.crazycake.shiro.SerializeUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.Serializable; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +/** + * @author bootdo 1992lcg@163.com + * @version V1.0 + */ +public class RedisSessionDAO extends AbstractSessionDAO { + + private static Logger logger = LoggerFactory.getLogger(RedisSessionDAO.class); + /** + * shiro-redis的session对象前缀 + */ + private RedisManager redisManager; + + /** + * The Redis key prefix for the sessions + */ + private String keyPrefix = "shiro_redis_session:"; + + @Override + public void update(Session session) throws UnknownSessionException { + this.saveSession(session); + } + + /** + * save session + * @param session + * @throws UnknownSessionException + */ + private void saveSession(Session session) throws UnknownSessionException{ + if(session == null || session.getId() == null){ + logger.error("session or session id is null"); + return; + } + + byte[] key = getByteKey(session.getId()); + byte[] value = SerializeUtils.serialize(session); + session.setTimeout(redisManager.getExpire()*1000); + this.redisManager.set(key, value, redisManager.getExpire()); + } + + @Override + public void delete(Session session) { + if(session == null || session.getId() == null){ + logger.error("session or session id is null"); + return; + } + redisManager.del(this.getByteKey(session.getId())); + + } + + @Override + public Collection getActiveSessions() { + Set sessions = new HashSet(); + + Set keys = redisManager.keys(this.keyPrefix + "*"); + if(keys != null && keys.size()>0){ + for(byte[] key:keys){ + Session s = (Session)SerializeUtils.deserialize(redisManager.get(key)); + sessions.add(s); + } + } + + return sessions; + } + + @Override + protected Serializable doCreate(Session session) { + Serializable sessionId = this.generateSessionId(session); + this.assignSessionId(session, sessionId); + this.saveSession(session); + return sessionId; + } + + @Override + protected Session doReadSession(Serializable sessionId) { + if(sessionId == null){ + logger.error("session id is null"); + return null; + } + + Session s = (Session)SerializeUtils.deserialize(redisManager.get(this.getByteKey(sessionId))); + return s; + } + + /** + * 获得byte[]型的key + * @param key + * @return + */ + private byte[] getByteKey(Serializable sessionId){ + String preKey = this.keyPrefix + sessionId; + return preKey.getBytes(); + } + + public RedisManager getRedisManager() { + return redisManager; + } + + public void setRedisManager(RedisManager redisManager) { + this.redisManager = redisManager; + + /** + * 初始化redisManager + */ + this.redisManager.init(); + } + + /** + * Returns the Redis session keys + * prefix. + * @return The prefix + */ + public String getKeyPrefix() { + return keyPrefix; + } + + /** + * Sets the Redis sessions key + * prefix. + * @param keyPrefix The prefix + */ + public void setKeyPrefix(String keyPrefix) { + this.keyPrefix = keyPrefix; + } + + +} \ No newline at end of file diff --git a/bootdo/src/main/java/com/bootdo/common/redis/shiro/SerializeUtils.java b/bootdo/src/main/java/com/bootdo/common/redis/shiro/SerializeUtils.java new file mode 100644 index 0000000..68db5a9 --- /dev/null +++ b/bootdo/src/main/java/com/bootdo/common/redis/shiro/SerializeUtils.java @@ -0,0 +1,89 @@ +package com.bootdo.common.redis.shiro; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author bootdo 1992lcg@163.com + * @version V1.0 + */ +public class SerializeUtils { + + private static Logger logger = LoggerFactory.getLogger(SerializeUtils.class); + + /** + * 反序列化 + * @param bytes + * @return + */ + public static Object deserialize(byte[] bytes) { + + Object result = null; + + if (isEmpty(bytes)) { + return null; + } + + try { + ByteArrayInputStream byteStream = new ByteArrayInputStream(bytes); + try { + ObjectInputStream objectInputStream = new ObjectInputStream(byteStream); + try { + result = objectInputStream.readObject(); + } + catch (ClassNotFoundException ex) { + throw new Exception("Failed to deserialize object type", ex); + } + } + catch (Throwable ex) { + throw new Exception("Failed to deserialize", ex); + } + } catch (Exception e) { + logger.error("Failed to deserialize",e); + } + return result; + } + + public static boolean isEmpty(byte[] data) { + return (data == null || data.length == 0); + } + + /** + * 序列化 + * @param object + * @return + */ + public static byte[] serialize(Object object) { + + byte[] result = null; + + if (object == null) { + return new byte[0]; + } + try { + ByteArrayOutputStream byteStream = new ByteArrayOutputStream(128); + try { + if (!(object instanceof Serializable)) { + throw new IllegalArgumentException(SerializeUtils.class.getSimpleName() + " requires a Serializable payload " + + "but received an object of type [" + object.getClass().getName() + "]"); + } + ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteStream); + objectOutputStream.writeObject(object); + objectOutputStream.flush(); + result = byteStream.toByteArray(); + } + catch (Throwable ex) { + throw new Exception("Failed to serialize", ex); + } + } catch (Exception ex) { + logger.error("Failed to serialize",ex); + } + return result; + } +} \ No newline at end of file -- Gitee From 5723df84518133499fe1a4124c69ba5099dbe25d Mon Sep 17 00:00:00 2001 From: lcg0124 <1992lcg@163.com> Date: Mon, 8 Jan 2018 14:11:50 +0800 Subject: [PATCH 15/18] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=94=AF=E6=8C=81redis?= =?UTF-8?q?=E5=AD=98=E5=82=A8session=E5=92=8C=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/bootdo/common/redis/shiro/RedisCache.java | 3 +-- .../com/bootdo/common/redis/shiro/RedisCacheManager.java | 1 - .../java/com/bootdo/common/redis/shiro/RedisManager.java | 3 +++ .../java/com/bootdo/common/redis/shiro/RedisSessionDAO.java | 1 - .../src/main/java/com/bootdo/common/utils/ShiroUtils.java | 1 - .../java/com/bootdo/system/config/ShiroConfigRedis.java | 6 +++--- 6 files changed, 7 insertions(+), 8 deletions(-) diff --git a/bootdo/src/main/java/com/bootdo/common/redis/shiro/RedisCache.java b/bootdo/src/main/java/com/bootdo/common/redis/shiro/RedisCache.java index c7be6b1..f0bcea1 100644 --- a/bootdo/src/main/java/com/bootdo/common/redis/shiro/RedisCache.java +++ b/bootdo/src/main/java/com/bootdo/common/redis/shiro/RedisCache.java @@ -14,8 +14,7 @@ import java.util.Set; import org.apache.shiro.cache.Cache; import org.apache.shiro.cache.CacheException; import org.apache.shiro.util.CollectionUtils; -import org.crazycake.shiro.RedisManager; -import org.crazycake.shiro.SerializeUtils; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/bootdo/src/main/java/com/bootdo/common/redis/shiro/RedisCacheManager.java b/bootdo/src/main/java/com/bootdo/common/redis/shiro/RedisCacheManager.java index c7a2d7a..d454230 100644 --- a/bootdo/src/main/java/com/bootdo/common/redis/shiro/RedisCacheManager.java +++ b/bootdo/src/main/java/com/bootdo/common/redis/shiro/RedisCacheManager.java @@ -10,7 +10,6 @@ import java.util.concurrent.ConcurrentMap; import org.apache.shiro.cache.Cache; import org.apache.shiro.cache.CacheException; import org.apache.shiro.cache.CacheManager; -import org.crazycake.shiro.RedisManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/bootdo/src/main/java/com/bootdo/common/redis/shiro/RedisManager.java b/bootdo/src/main/java/com/bootdo/common/redis/shiro/RedisManager.java index 8f50ea8..39834d0 100644 --- a/bootdo/src/main/java/com/bootdo/common/redis/shiro/RedisManager.java +++ b/bootdo/src/main/java/com/bootdo/common/redis/shiro/RedisManager.java @@ -10,6 +10,9 @@ import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; +/** + * + */ public class RedisManager { private String host = "127.0.0.1"; diff --git a/bootdo/src/main/java/com/bootdo/common/redis/shiro/RedisSessionDAO.java b/bootdo/src/main/java/com/bootdo/common/redis/shiro/RedisSessionDAO.java index 39bc964..86e3e81 100644 --- a/bootdo/src/main/java/com/bootdo/common/redis/shiro/RedisSessionDAO.java +++ b/bootdo/src/main/java/com/bootdo/common/redis/shiro/RedisSessionDAO.java @@ -3,7 +3,6 @@ package com.bootdo.common.redis.shiro; import org.apache.shiro.session.Session; import org.apache.shiro.session.UnknownSessionException; import org.apache.shiro.session.mgt.eis.AbstractSessionDAO; -import org.crazycake.shiro.SerializeUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/bootdo/src/main/java/com/bootdo/common/utils/ShiroUtils.java b/bootdo/src/main/java/com/bootdo/common/utils/ShiroUtils.java index b629b00..277eeae 100644 --- a/bootdo/src/main/java/com/bootdo/common/utils/ShiroUtils.java +++ b/bootdo/src/main/java/com/bootdo/common/utils/ShiroUtils.java @@ -8,7 +8,6 @@ import org.apache.shiro.session.mgt.eis.SessionDAO; import org.apache.shiro.subject.Subject; import com.bootdo.system.domain.UserDO; -import org.crazycake.shiro.RedisSessionDAO; import org.springframework.beans.factory.annotation.Autowired; import java.lang.reflect.InvocationTargetException; diff --git a/bootdo/src/main/java/com/bootdo/system/config/ShiroConfigRedis.java b/bootdo/src/main/java/com/bootdo/system/config/ShiroConfigRedis.java index af9cc37..80c074d 100644 --- a/bootdo/src/main/java/com/bootdo/system/config/ShiroConfigRedis.java +++ b/bootdo/src/main/java/com/bootdo/system/config/ShiroConfigRedis.java @@ -1,6 +1,9 @@ //package com.bootdo.system.config; // //import at.pollux.thymeleaf.shiro.dialect.ShiroDialect; +//import com.bootdo.common.redis.shiro.RedisCacheManager; +//import com.bootdo.common.redis.shiro.RedisManager; +//import com.bootdo.common.redis.shiro.RedisSessionDAO; //import com.bootdo.system.shiro.UserRealm; //import org.apache.shiro.mgt.SecurityManager; //import org.apache.shiro.session.SessionListener; @@ -10,9 +13,6 @@ //import org.apache.shiro.spring.web.ShiroFilterFactoryBean; //import org.apache.shiro.web.mgt.DefaultWebSecurityManager; //import org.apache.shiro.web.session.mgt.DefaultWebSessionManager; -//import org.crazycake.shiro.RedisCacheManager; -//import org.crazycake.shiro.RedisManager; -//import org.crazycake.shiro.RedisSessionDAO; //import org.springframework.beans.factory.annotation.Value; //import org.springframework.context.annotation.Bean; //import org.springframework.context.annotation.Configuration; -- Gitee From 9a573f9fab5c51288a362c962799e1061058194e Mon Sep 17 00:00:00 2001 From: lcg0124 <1992lcg@163.com> Date: Mon, 8 Jan 2018 14:46:50 +0800 Subject: [PATCH 16/18] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=AD=98=E5=82=A8?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E7=AD=96=E7=95=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bootdo/pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/bootdo/pom.xml b/bootdo/pom.xml index fe1422e..744612a 100644 --- a/bootdo/pom.xml +++ b/bootdo/pom.xml @@ -201,6 +201,12 @@ 2.6.1 + + redis.clients + jedis + 2.4.2 + + org.jsoup -- Gitee From 0f948b7c36391d8237ec4f6dad4ec4d41e042b1b Mon Sep 17 00:00:00 2001 From: lcg0124 <1992lcg@163.com> Date: Mon, 8 Jan 2018 15:04:44 +0800 Subject: [PATCH 17/18] =?UTF-8?q?=E7=BC=93=E5=AD=98=E7=AD=96=E7=95=A5?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/bootdo/common/config/Constant.java | 3 + .../com/bootdo/system/config/ShiroConfig.java | 300 +++++++++++------- .../system/config/ShiroConfigRedis.java | 183 ----------- bootdo/src/main/resources/application.yml | 4 +- 4 files changed, 190 insertions(+), 300 deletions(-) delete mode 100644 bootdo/src/main/java/com/bootdo/system/config/ShiroConfigRedis.java diff --git a/bootdo/src/main/java/com/bootdo/common/config/Constant.java b/bootdo/src/main/java/com/bootdo/common/config/Constant.java index f1e8aba..be17bed 100644 --- a/bootdo/src/main/java/com/bootdo/common/config/Constant.java +++ b/bootdo/src/main/java/com/bootdo/common/config/Constant.java @@ -15,5 +15,8 @@ public class Constant { public static int OA_NOTIFY_READ_YES = 1; //部门根节点id public static Long DEPT_ROOT_ID = 0l; + //缓存方式 + public static String CACHE_TYPE_REDIS ="redis"; + } diff --git a/bootdo/src/main/java/com/bootdo/system/config/ShiroConfig.java b/bootdo/src/main/java/com/bootdo/system/config/ShiroConfig.java index 4e4e48f..aa956fd 100644 --- a/bootdo/src/main/java/com/bootdo/system/config/ShiroConfig.java +++ b/bootdo/src/main/java/com/bootdo/system/config/ShiroConfig.java @@ -1,116 +1,184 @@ -package com.bootdo.system.config; - -import at.pollux.thymeleaf.shiro.dialect.ShiroDialect; -import com.bootdo.system.shiro.UserRealm; -import org.apache.shiro.cache.ehcache.EhCacheManager; -import org.apache.shiro.mgt.SecurityManager; -import org.apache.shiro.session.SessionListener; -import org.apache.shiro.session.mgt.SessionManager; -import org.apache.shiro.session.mgt.eis.MemorySessionDAO; -import org.apache.shiro.session.mgt.eis.SessionDAO; -import org.apache.shiro.spring.LifecycleBeanPostProcessor; -import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; -import org.apache.shiro.spring.web.ShiroFilterFactoryBean; -import org.apache.shiro.web.mgt.DefaultWebSecurityManager; -import org.apache.shiro.web.session.mgt.DefaultWebSessionManager; -import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.LinkedHashMap; - -@Configuration -public class ShiroConfig { - @Bean - public EhCacheManager getEhCacheManager() { - EhCacheManager em = new EhCacheManager(); - em.setCacheManagerConfigFile("classpath:config/ehcache.xml"); - return em; - } - - @Bean - UserRealm userRealm(EhCacheManager cacheManager) { - UserRealm userRealm = new UserRealm(); - userRealm.setCacheManager(cacheManager); - return userRealm; - } - @Bean - SessionDAO sessionDAO() { - MemorySessionDAO sessionDAO = new MemorySessionDAO(); - return sessionDAO; - } - - @Bean - public SessionManager sessionManager() { - DefaultWebSessionManager sessionManager = new DefaultWebSessionManager(); - Collection listeners = new ArrayList(); - listeners.add(new BDSessionListener()); - sessionManager.setSessionListeners(listeners); - sessionManager.setSessionDAO(sessionDAO()); - return sessionManager; - } - - @Bean - SecurityManager securityManager(UserRealm userRealm) { - DefaultWebSecurityManager manager = new DefaultWebSecurityManager(); - manager.setRealm(userRealm); - manager.setCacheManager(getEhCacheManager()); - manager.setSessionManager(sessionManager()); - return manager; - } - - @Bean - ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) { - ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); - shiroFilterFactoryBean.setSecurityManager(securityManager); - shiroFilterFactoryBean.setLoginUrl("/login"); - shiroFilterFactoryBean.setSuccessUrl("/index"); - shiroFilterFactoryBean.setUnauthorizedUrl("/403"); - LinkedHashMap filterChainDefinitionMap = new LinkedHashMap<>(); - filterChainDefinitionMap.put("/css/**", "anon"); - filterChainDefinitionMap.put("/js/**", "anon"); - filterChainDefinitionMap.put("/fonts/**", "anon"); - filterChainDefinitionMap.put("/img/**", "anon"); - filterChainDefinitionMap.put("/docs/**", "anon"); - filterChainDefinitionMap.put("/druid/**", "anon"); - filterChainDefinitionMap.put("/upload/**", "anon"); - filterChainDefinitionMap.put("/files/**", "anon"); - filterChainDefinitionMap.put("/logout", "logout"); - filterChainDefinitionMap.put("/", "anon"); - filterChainDefinitionMap.put("/blog", "anon"); - filterChainDefinitionMap.put("/blog/open/**", "anon"); - filterChainDefinitionMap.put("/**", "authc"); - - shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); - return shiroFilterFactoryBean; - } - - @Bean("lifecycleBeanPostProcessor") - public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() { - return new LifecycleBeanPostProcessor(); - } - - @Bean - public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() { - DefaultAdvisorAutoProxyCreator proxyCreator = new DefaultAdvisorAutoProxyCreator(); - proxyCreator.setProxyTargetClass(true); - return proxyCreator; - } - - @Bean - public ShiroDialect shiroDialect() { - return new ShiroDialect(); - } - - @Bean - public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor( - @Qualifier("securityManager") SecurityManager securityManager) { - AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); - authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); - return authorizationAttributeSourceAdvisor; - } - -} +package com.bootdo.system.config; + +import at.pollux.thymeleaf.shiro.dialect.ShiroDialect; +import com.bootdo.common.config.Constant; +import com.bootdo.common.redis.shiro.RedisCacheManager; +import com.bootdo.common.redis.shiro.RedisManager; +import com.bootdo.common.redis.shiro.RedisSessionDAO; +import com.bootdo.system.shiro.UserRealm; +import org.apache.shiro.cache.ehcache.EhCacheManager; +import org.apache.shiro.mgt.SecurityManager; +import org.apache.shiro.session.SessionListener; +import org.apache.shiro.session.mgt.eis.MemorySessionDAO; +import org.apache.shiro.session.mgt.eis.SessionDAO; +import org.apache.shiro.spring.LifecycleBeanPostProcessor; +import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; +import org.apache.shiro.spring.web.ShiroFilterFactoryBean; +import org.apache.shiro.web.mgt.DefaultWebSecurityManager; +import org.apache.shiro.web.session.mgt.DefaultWebSessionManager; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedHashMap; + +/** + * @author bootdo 1992lcg@163.com + */ +@Configuration +public class ShiroConfig { + @Value("${spring.redis.host}") + private String host; + @Value("${spring.redis.password}") + private String password; + @Value("${spring.redis.port}") + private int port; + @Value("${spring.redis.timeout}") + private int timeout; + + @Value("${cacheType}") + private String cacheType; + + @Bean + public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() { + return new LifecycleBeanPostProcessor(); + } + + /** + * ShiroDialect,为了在thymeleaf里使用shiro的标签的bean + * @return + */ + @Bean + public ShiroDialect shiroDialect() { + return new ShiroDialect(); + } + + @Bean + ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) { + ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); + shiroFilterFactoryBean.setSecurityManager(securityManager); + shiroFilterFactoryBean.setLoginUrl("/login"); + shiroFilterFactoryBean.setSuccessUrl("/index"); + shiroFilterFactoryBean.setUnauthorizedUrl("/403"); + LinkedHashMap filterChainDefinitionMap = new LinkedHashMap<>(); + filterChainDefinitionMap.put("/css/**", "anon"); + filterChainDefinitionMap.put("/js/**", "anon"); + filterChainDefinitionMap.put("/fonts/**", "anon"); + filterChainDefinitionMap.put("/img/**", "anon"); + filterChainDefinitionMap.put("/docs/**", "anon"); + filterChainDefinitionMap.put("/druid/**", "anon"); + filterChainDefinitionMap.put("/upload/**", "anon"); + filterChainDefinitionMap.put("/files/**", "anon"); + filterChainDefinitionMap.put("/logout", "logout"); + filterChainDefinitionMap.put("/", "anon"); + filterChainDefinitionMap.put("/blog", "anon"); + filterChainDefinitionMap.put("/blog/open/**", "anon"); + filterChainDefinitionMap.put("/**", "authc"); + shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); + return shiroFilterFactoryBean; + } + + + @Bean + public SecurityManager securityManager(){ + DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); + //设置realm. + securityManager.setRealm(userRealm()); + // 自定义缓存实现 使用redis + if(Constant.CACHE_TYPE_REDIS.equals(cacheType)){ + securityManager.setCacheManager(cacheManager()); + }else { + securityManager.setCacheManager(ehCacheManager()); + } + securityManager.setSessionManager(sessionManager()); + return securityManager; + } + + @Bean + UserRealm userRealm() { + UserRealm userRealm = new UserRealm(); + return userRealm; + } + + /** + * 开启shiro aop注解支持. + * 使用代理方式;所以需要开启代码支持; + * @param securityManager + * @return + */ + @Bean + public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){ + AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); + authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); + return authorizationAttributeSourceAdvisor; + } + + /** + * 配置shiro redisManager + * @return + */ + @Bean + public RedisManager redisManager() { + RedisManager redisManager = new RedisManager(); + redisManager.setHost(host); + redisManager.setPort(port); + redisManager.setExpire(1800);// 配置缓存过期时间 + //redisManager.setTimeout(1800); + redisManager.setPassword(password); + return redisManager; + } + + /** + * cacheManager 缓存 redis实现 + * 使用的是shiro-redis开源插件 + * @return + */ + public RedisCacheManager cacheManager() { + RedisCacheManager redisCacheManager = new RedisCacheManager(); + redisCacheManager.setRedisManager(redisManager()); + return redisCacheManager; + } + + + /** + * RedisSessionDAO shiro sessionDao层的实现 通过redis + * 使用的是shiro-redis开源插件 + */ + @Bean + public RedisSessionDAO redisSessionDAO() { + RedisSessionDAO redisSessionDAO = new RedisSessionDAO(); + redisSessionDAO.setRedisManager(redisManager()); + return redisSessionDAO; + } + + @Bean + public SessionDAO sessionDAO(){ + if(Constant.CACHE_TYPE_REDIS.equals(cacheType)){ + return redisSessionDAO(); + }else { + return new MemorySessionDAO(); + } + } + + /** + * shiro session的管理 + */ + @Bean + public DefaultWebSessionManager sessionManager() { + DefaultWebSessionManager sessionManager = new DefaultWebSessionManager(); + sessionManager.setSessionDAO(sessionDAO()); + Collection listeners = new ArrayList(); + listeners.add(new BDSessionListener()); + sessionManager.setSessionListeners(listeners); + return sessionManager; + } + @Bean + public EhCacheManager ehCacheManager() { + EhCacheManager em = new EhCacheManager(); + em.setCacheManagerConfigFile("classpath:config/ehcache.xml"); + return em; + } + +} diff --git a/bootdo/src/main/java/com/bootdo/system/config/ShiroConfigRedis.java b/bootdo/src/main/java/com/bootdo/system/config/ShiroConfigRedis.java deleted file mode 100644 index 80c074d..0000000 --- a/bootdo/src/main/java/com/bootdo/system/config/ShiroConfigRedis.java +++ /dev/null @@ -1,183 +0,0 @@ -//package com.bootdo.system.config; -// -//import at.pollux.thymeleaf.shiro.dialect.ShiroDialect; -//import com.bootdo.common.redis.shiro.RedisCacheManager; -//import com.bootdo.common.redis.shiro.RedisManager; -//import com.bootdo.common.redis.shiro.RedisSessionDAO; -//import com.bootdo.system.shiro.UserRealm; -//import org.apache.shiro.mgt.SecurityManager; -//import org.apache.shiro.session.SessionListener; -//import org.apache.shiro.session.mgt.eis.SessionDAO; -//import org.apache.shiro.spring.LifecycleBeanPostProcessor; -//import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; -//import org.apache.shiro.spring.web.ShiroFilterFactoryBean; -//import org.apache.shiro.web.mgt.DefaultWebSecurityManager; -//import org.apache.shiro.web.session.mgt.DefaultWebSessionManager; -//import org.springframework.beans.factory.annotation.Value; -//import org.springframework.context.annotation.Bean; -//import org.springframework.context.annotation.Configuration; -// -//import java.util.ArrayList; -//import java.util.Collection; -//import java.util.LinkedHashMap; -// -///** -// * @author bootdo 1992lcg@163.com -// */ -//@Configuration -//public class ShiroConfigRedis{ -// @Value("${spring.redis.host}") -// private String host; -// @Value("${spring.redis.password}") -// private String password; -// @Value("${spring.redis.port}") -// private int port; -// @Value("${spring.redis.timeout}") -// private int timeout; -// -// @Bean -// public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() { -// return new LifecycleBeanPostProcessor(); -// } -// -// /** -// * ShiroDialect,为了在thymeleaf里使用shiro的标签的bean -// * @return -// */ -// @Bean -// public ShiroDialect shiroDialect() { -// return new ShiroDialect(); -// } -// -// @Bean -// ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) { -// ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); -// shiroFilterFactoryBean.setSecurityManager(securityManager); -// shiroFilterFactoryBean.setLoginUrl("/login"); -// shiroFilterFactoryBean.setSuccessUrl("/index"); -// shiroFilterFactoryBean.setUnauthorizedUrl("/403"); -// LinkedHashMap filterChainDefinitionMap = new LinkedHashMap<>(); -// filterChainDefinitionMap.put("/css/**", "anon"); -// filterChainDefinitionMap.put("/js/**", "anon"); -// filterChainDefinitionMap.put("/fonts/**", "anon"); -// filterChainDefinitionMap.put("/img/**", "anon"); -// filterChainDefinitionMap.put("/docs/**", "anon"); -// filterChainDefinitionMap.put("/druid/**", "anon"); -// filterChainDefinitionMap.put("/upload/**", "anon"); -// filterChainDefinitionMap.put("/files/**", "anon"); -// filterChainDefinitionMap.put("/logout", "logout"); -// filterChainDefinitionMap.put("/", "anon"); -// filterChainDefinitionMap.put("/blog", "anon"); -// filterChainDefinitionMap.put("/blog/open/**", "anon"); -// filterChainDefinitionMap.put("/**", "authc"); -// shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); -// return shiroFilterFactoryBean; -// } -// -// -// @Bean -// public SecurityManager securityManager(){ -// DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); -// //设置realm. -// securityManager.setRealm(userRealm()); -// // 自定义缓存实现 使用redis -// securityManager.setCacheManager(cacheManager()); -// // 自定义session管理 使用redis -// securityManager.setSessionManager(sessionManager()); -// return securityManager; -// } -// -// @Bean -// UserRealm userRealm() { -// UserRealm userRealm = new UserRealm(); -// return userRealm; -// } -// /** -// * 凭证匹配器 -// * (由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了 -// * 所以我们需要修改下doGetAuthenticationInfo中的代码; -// * ) -// * @return -// */ -//// @Bean -//// public HashedCredentialsMatcher hashedCredentialsMatcher(){ -//// HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher(); -//// -//// hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法:这里使用MD5算法; -//// hashedCredentialsMatcher.setHashIterations(2);//散列的次数,比如散列两次,相当于 md5(md5("")); -//// -//// return hashedCredentialsMatcher; -//// } -// -// -// /** -// * 开启shiro aop注解支持. -// * 使用代理方式;所以需要开启代码支持; -// * @param securityManager -// * @return -// */ -// @Bean -// public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){ -// AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); -// authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); -// return authorizationAttributeSourceAdvisor; -// } -// -// /** -// * 配置shiro redisManager -// * 使用的是shiro-redis开源插件 -// * @return -// */ -// @Bean -// public RedisManager redisManager() { -// RedisManager redisManager = new RedisManager(); -// redisManager.setHost(host); -// redisManager.setPort(port); -// redisManager.setExpire(1800);// 配置缓存过期时间 -// //redisManager.setTimeout(1800); -// redisManager.setPassword(password); -// return redisManager; -// } -// -// /** -// * cacheManager 缓存 redis实现 -// * 使用的是shiro-redis开源插件 -// * @return -// */ -// public RedisCacheManager cacheManager() { -// RedisCacheManager redisCacheManager = new RedisCacheManager(); -// redisCacheManager.setRedisManager(redisManager()); -// return redisCacheManager; -// } -// -// -// /** -// * RedisSessionDAO shiro sessionDao层的实现 通过redis -// * 使用的是shiro-redis开源插件 -// */ -// @Bean -// public RedisSessionDAO redisSessionDAO() { -// RedisSessionDAO redisSessionDAO = new RedisSessionDAO(); -// redisSessionDAO.setRedisManager(redisManager()); -// return redisSessionDAO; -// } -// -// @Bean -// public SessionDAO sessionDAO(){ -// return redisSessionDAO(); -// } -// -// /** -// * shiro session的管理 -// */ -// @Bean -// public DefaultWebSessionManager sessionManager() { -// DefaultWebSessionManager sessionManager = new DefaultWebSessionManager(); -// sessionManager.setSessionDAO(redisSessionDAO()); -// Collection listeners = new ArrayList(); -// listeners.add(new BDSessionListener()); -// sessionManager.setSessionListeners(listeners); -// return sessionManager; -// } -// -//} diff --git a/bootdo/src/main/resources/application.yml b/bootdo/src/main/resources/application.yml index 565b97e..e6a1660 100644 --- a/bootdo/src/main/resources/application.yml +++ b/bootdo/src/main/resources/application.yml @@ -29,4 +29,6 @@ mybatis: configuration: map-underscore-to-camel-case: true mapper-locations: mybatis/**/*Mapper.xml - typeAliasesPackage: com.bootdo.**.domain \ No newline at end of file + typeAliasesPackage: com.bootdo.**.domain +#配置缓存和session存储方式,默认ehcache,可选redis +cacheType: ehcache \ No newline at end of file -- Gitee From 2b43a8ffd13444038c98b6a9242b82d9e3e18a73 Mon Sep 17 00:00:00 2001 From: lcg0124 <1992lcg@163.com> Date: Mon, 8 Jan 2018 15:12:18 +0800 Subject: [PATCH 18/18] =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=BC=93=E5=AD=98?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E7=AD=96=E7=95=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bootdo/pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bootdo/pom.xml b/bootdo/pom.xml index 744612a..2a2a84c 100644 --- a/bootdo/pom.xml +++ b/bootdo/pom.xml @@ -201,10 +201,10 @@ 2.6.1 + - redis.clients - jedis - 2.4.2 + org.springframework.boot + spring-boot-starter-data-redis -- Gitee