第三阶段实战(九)——项目功能拓展与总结

1 首页菜单动态化实现

1.1 背景

用户希望在登陆以后基于权限的不同,在首页左侧呈现不同的菜单,如何实现呢?

1.2 初步分析

基于登陆用户id,查询用户对应的菜单信息然后进行呈现

1.3 原理应用分析

方案实现上可以基于同步或异步查询然后进行菜单数据呈现。

1.4 最终解决方案

用户登陆以后,基于用户登陆id查询用户对应的一级菜单,二级菜单然后存储到指定 作用域,当进入系统首页后基于thymeleaf呈现用户菜单。

1.4.1 Pojo类的定义

基于用户需求将查询到的一级菜单以及一级菜单对应的二级菜单查询出来,并进行 封装。

package​ com.cy.pj.sys.pojo;     
@Setter 
@Getter 
@ToString 
public​ ​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( @Param("menuIds")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 left join sys_menus c
        on p.id=c.parentId
        where p.parentId is null and c.id in
        <foreach collection="menuIds" open="(" close=")" item="menuId" separator=",">
            #{menuId}
        </foreach>
    </select>
<resultMap id="sysUserMenu" type="com.cy.pj.sys.pojo.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">  
	functiondoLoadRS(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​ ​booleanpreHandle(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​ ​newServiceException("不在访问时间之内"); 
		return​ ​true; 
	} 
}

第二步:拦截器配置,注册拦截器,关键代码如下

package​ com.cy.pj.common.config; 
@Configuration 
public​ ​class​ SpringWebConfig ​implements​ WebMvcConfigurer{//web.xml 
	//配置spring ​mvc​ 拦截器  @Overridepublic​ ​voidaddInterceptors(InterceptorRegistry ​registry​) {  ​
		registry​.addInterceptor(newTimeAccessInterceptor()).addPathPatterns("/user/doLogin");
	} 
} 

3 项目打包策略及实现

3.1 jar包方式实现(推荐)

假如使用的是sts,可直接对项目进行maven install操作,然后在项目target目录中找到对应的jar包,在当前目录下执行java -jar project-a.jar即可(假如 project-a.jar为打包好的jar文件)
说 明:可以在打包时跳过测试类,打开pom.xml,在properties元素中添加跳过测试 元素​( < skip Tests>true</skip Tests>​),代码如下:

<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> 

修改启动类

@​SpringBootApplication 
public​ ​class​ Application ​extends​ SpringBootServletInitializer{ 
	@Override 
	protected​ SpringApplicationBuilder configure(SpringApplicationBuilder ​application​) {
		return​ ​application​.sources(Application.class); 
	} 
	public​ ​static​ ​voidmain(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 知识点总结

  1. Spring Boot (入门,基础,进阶)
  2. Thymeleaf&ajax
  3. dbms(动吧系统中的权限子系统)
  4. Spring AOP (AspectJ,事务,异步,缓存,日志)
  5. Shiro (安全框架-认证,授权,会话,记住我,加密)

4.2 项目业务总结

1.项目中各个模块之间的业务关系。
在这里插入图片描述
2.项目中各个业务模块的实现过程?(pojo,dao,service,controller)
3.项目中事务的控制,缓存应用,认证和授权核心的业务实现。
4.建议:通读阿里巴巴的开发手册,熟悉其标准。

4.3 项目代码实现总结

项目核心业务流程,如图所示:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值