1 首页菜单动态化实现
1.1 背景
用户心愿在登陆当前基于权限的不同,在首页左侧出现不同的菜单,如何实现呢?
1.2 初步剖析
基于登陆用户id,查问用户对应的菜单信息而后进行出现
1.3 原理利用剖析
计划实现上能够基于同步或异步查问而后进行菜单数据出现。
1.4 最终解决方案
用户登陆当前,基于用户登陆id查问用户对应的一级菜单,二级菜单而后存储到指定作用域,当进入零碎首页后基于thymeleaf出现用户菜单。
1.4.1 Pojo类的定义
基于用户需要将查问到的一级菜单以及一级菜单对应的二级菜单查问进去,并进行封装。
package com.cy.pj.sys.pojo;@Setter@Getter@ToStringpublic class SysUserMenu implements Serializable{ private static final long serialVersionUID = -8126757329276920059L; private Integer id; private String name; private String url; private List<SysUserMenu> childs;}
1.4.2 Dao接口实现
在SysMenuDao中增加办法,基于菜单id获取所有菜单相干信息,代码如下
/** * 基于菜单获取菜单信息 * **@param** menuIds * **@return** */List<SysUserMenu> findMenusByIds(List<Integer> menuIds);
1.4.3 Mapper元素定义
在SysMenuMapper.xml文件中增加如下映射元素:
<select id="findMenusByIds" resultMap="sysUserMenu"> select p.id,p.name,p.url,c.id cid,c.name cname,c.url curl from sys_menus p join sys_menus c on c.parentId=p.id <where> <foreach collection="menuIds"open="("close=")"separator="or"item="menuId"> c.id=#{menuId} </foreach> and p.parentId is null </where> </select>
<resultMap type="com.cy.pj.sys.pojo.SysUserMenu" id="sysUserMenu"> <!-- 一级菜单映射 --> <id property="id" column="id"/> <result property="name" column="name"/> <result property="url" column="url"/> <!-- 二级菜单映射 --> <collection property="childs" ofType="com.cy.pj.sys.pojo.SysUserMenu"> <id property="id" column="cid"/> <result property="name" column="cname"/> <result property="url" column="curl"/> </collection> </resultMap>
1.4.4 Service接口及实现
在SysMenuService接口及实现类中定义如下办法,基于用户id查问用户对应的菜单信息,代码如下
@Override public List<SysUserMenu> findUserMenusByUserId(Integer id) { //1.对用户id进行判断 //2.基于用户id查找用户对应的角色id List<Integer> roleIds=sysUserRoleDao.findRoleIdsByUserId(id); //3.基于角色id获取角色对应的菜单信息,并进行封装. List<Integer> menuIds=sysRoleMenuDao.findMenuIdsByRoleIds(roleIds); //4.基于菜单id获取用户对应的菜单信息并返回 return sysMenuDao.findMenusByIds(menuIds); }
1.4.5 Controller类实现
批改PageController中的doIndexUI办法
@RequestMapping("doIndexUI") public String doIndexUI(Model model) { SysUser user=ShiroUtils.getUser(); model.addAttribute("username", user.getUsername()); List<SysUserMenu>userMenus=sysUserService.findUserMenusByUserId(user.getId()); model.addAttribute("userMenus",userMenus); return "starter"; }
1.4.6 Starter页面实现
将如下代码替换starter.html中Sidebar Menu对应的地位。
<ul class="sidebar-menu" data-widget="tree"> <li class="header">HEADER</li> <li class="treeview" th:each="m:${userMenus}"> <a href="#"><i class="fa fa-link"></i> <span>[[${m.name}]]</span> <span class="pull-right-container"> <i class="fa fa-angle-left pull-right"></i> </span> </a> <ul class="treeview-menu"> <li th:each="c:${m.childs}"> <a th:onclick="javascript:doLoadRS([[${c.url}]])">[[${c.name}]]</a> </li> </ul> </li> </ul>
当点击对应的菜单元素时,其事件处理函数如下:
<script type="text/javascript"> function doLoadRS(url){ $("#mainContentId").load(url); } </script>
2 管制层拜访拦挡实现
2.1 背景
最近我的项目业务上有新的需要,要求零碎登陆操作要有工夫限度。
2.2 初步剖析
对于相似需要的实现,可采纳过滤器(Filter),SpringMVC拦截器,AOP等进行实现。对于过滤器而言个别次要利用在我的项目中共性的过滤,AOP须要依靠于动静代理以及切面对象,这样性能方面绝对较差,所以最终抉择应用Spring MVC拦截器进行实现。
2.3 原理利用剖析
Spring MVC中的拦截器基于回调机制,能够在指标办法执行之前,先进行业务检测,满足条件则放行,不满足条件则进行拦挡,拦截器原理剖析如下图所示:
2.4 最终解决方案实现
第一步:拦截器定义,要害代码如下:
package com.cy.pj.common.web;/** * Spring MVC中拦截器 * @author Administrator */public class TimeAccessInterceptor implements HandlerInterceptor { /** * preHandle在管制层指标办法执行之前执行 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception { System.out.println("preHandler()"); //获取java中的日历对象 Calendar c=Calendar.getInstance(); c.set(Calendar.HOUR_OF_DAY, 6); c.set(Calendar.MINUTE, 0); c.set(Calendar.SECOND, 0); long start=c.getTimeInMillis(); c.set(Calendar.HOUR_OF_DAY,23); long end=c.getTimeInMillis(); long cTime=System.currentTimeMillis(); if(cTime<start||cTime>end) throw new ServiceException("不在拜访工夫之内"); return true; }}
第二步:拦截器配置,要害代码如下
package com.cy.pj.common.config;@Configurationpublic class SpringWebConfig implements WebMvcConfigurer{//web.xml //配置spring mvc 拦截器 @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new TimeAccessInterceptor()) .addPathPatterns("/user/doLogin"); }}
3 我的项目打包策略及实现
3.1 jar包形式实现(举荐)
如果应用的是sts,可间接对我的项目进行maven install操作,而后在我的项目target目录中找到对应的jar包,在当前目录下执行java -jar project-a.jar即可(如果project-a.jar为打包好的jar文件)
阐明:能够在打包时跳过测试类,关上pom.xml,在properties元素中增加跳过测试元素(<skipTests>true</skipTests>),代码如下:
<properties> <java.version>1.8</java.version> <skipTests>true</skipTests> </properties>
3.2 war包形式实现(理解)
第一步:批改pom.xml,将打包形式批改为war:
<packaging>war</packaging>
第二步:增加依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope></dependency>
批改启动类
@SpringBootApplicationpublic class Application extends SpringBootServletInitializer{ @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(Application.class); } public static void main(String[] args) { SpringApplication.run(Application.class, args); }}
第三步:对我的项目进行maven install操作
第四步:将我的项目target目录下生成的war包拷贝到指定tomcat的webapps目录,启动tomcat测试运行,例如
http://localhost:8080/CGB-DB-SYS-V1.04-0.0.1-SNAPSHOT/doIndexUI
4 我的项目总结
4.1 知识点总结
- Spring Boot (入门,根底,进阶)
- Thymeleaf&ajax
- dbms(动吧零碎中的权限子系统)
- Spring AOP (AspectJ,事务,异步,缓存,日志)
- Shiro (平安框架-认证,受权,会话,记住我,加密)
4.2 我的项目业务总结
1.我的项目中各个模块之间的业务关系。
2.我的项目中各个业务模块的实现过程?(pojo,dao,service,controller)
3.我的项目中事务的管制,缓存利用,认证和受权外围的业务实现。
4.倡议:通读阿里巴巴的开发手册,相熟其规范。
4.3 我的项目代码实现总结
我的项目外围业务流程,如图所示: