来到新的公司一个月,以前实习公司的用的是srping+hibernate+struts2,而在这里不在用的这些了,而是用的springMVC和jdbc模板来操作数据了,所以又用了一段时间去慢慢融入这个新的体系中去;但终究这些技术是万变不离其宗的,学习也是很快的事,所以我也就很快的就融入了这个团队;

进入正题吧!我这里其实就是想把学习新东西自己记录下来,这有助于我的学习也有助于大家的学习;把springmvc+httl+shiro+maven给整合起来;我刚来到新公司这里已经是搭建好了这个项目;所以我也在空闲时间之余把这些知识给过了一遍,也有助于我开发效率的提高;

我使用的开发工具室MyEclipse(开发工具的使用都是大同小异);

至于httl和shiro的优势我就不多说了有兴趣的看:

http://www.open-open.com/open342321.htm;

http://blog.csdn.net/boonya/article/details/8233303

废话不多说,开始搭建吧。。。

1:首先建立一个javaweb项目

2:配置pom.xml导入必须的jar包

<dependencies><!-- junit核心jar包 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency><!-- springMVC核心jar包 --><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>4.0.5.RELEASE</version></dependency><!-- httl 核心jar包  --><dependency><groupId>com.github.httl</groupId><artifactId>httl-springmvc</artifactId><version>1.0.10</version></dependency><dependency><groupId>com.github.httl</groupId><artifactId>httl</artifactId><version>1.0.11</version></dependency><!--当你运行的环境是jre是时;httl模板必须加入这个jar包;还有就是必须在httl的 httl.properties注入属性值:compiler=httl.spi.compilers.JavassistCompiler。。这点很重要,不然当你启动tomcat时会一直抛classnotfound异常--><dependency><groupId>org.javassist</groupId><artifactId>javassist</artifactId><version>3.18.2-GA</version></dependency><dependency>  <groupId>commons-logging</groupId>  <artifactId>commons-logging</artifactId>  <version>1.1.3</version>  </dependency>  <!-- shiro --><dependency>  <groupId>org.apache.shiro</groupId>  <artifactId>shiro-core</artifactId>  <version>1.2.2</version>  </dependency>  <dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-web</artifactId><version>1.2.2</version></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-ehcache</artifactId><version>1.2.2</version></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>1.2.2</version></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-quartz</artifactId><version>1.2.2</version></dependency><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version></dependency><!-- spring aop --><dependency><groupId>org.aspectj</groupId><artifactId>aspectjrt</artifactId><version>1.8.5</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.8.5</version></dependency></dependencies>

3:修改web.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"version="3.0"><display-name></display-name><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext-shiro.xml</param-value></context-param><!-- 配置Shiro过滤器,先让Shiro过滤系统接收到的请求 --><!-- 这里filter-name必须对应applicationContext.xml中定义的<bean id="shiroFilter" /> --><!-- 使用[/*]匹配所有请求,保证所有的可控请求都经过Shiro的过滤 --><!-- 通常会将此filter-mapping放置到最前面(即其他filter-mapping前面),以保证它是过滤器链中第一个起作用的 --><filter><filter-name>shiroFilter</filter-name><filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class><init-param><!-- 该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理 --><param-name>targetFilterLifecycle</param-name><param-value>true</param-value></init-param></filter><filter-mapping><filter-name>shiroFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping><!-- 加载httl的属性文件 --><context-param><param-name>httl.properties</param-name><param-value>classpath:httl.properties</param-value></context-param><!-- Character Encoding filter --><filter><filter-name>encodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param><init-param><param-name>forceEncoding</param-name><param-value>true</param-value></init-param></filter><filter-mapping><filter-name>encodingFilter</filter-name><url-pattern>/*</url-pattern><dispatcher>REQUEST</dispatcher><dispatcher>FORWARD</dispatcher></filter-mapping><!-- Spring MVC Servlet 载入 --><servlet><servlet-name>springMVC</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring-mvc.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>springMVC</servlet-name><url-pattern>/</url-pattern></servlet-mapping><!-- 实例化Spring容器 --><!-- 应用启动时,该监听器被执行,它会读取Spring相关配置文件,其默认会到WEB-INF中查找applicationContext.xml --><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><welcome-file-list><welcome-file>index.jsp</welcome-file></welcome-file-list>
</web-app>

4:添加httl.properties文件

import.packages+=com.lishun.controller

template.directory=/WEB-INF/templates

template.suffix=.httl

input.encoding=utf-8

output.encoding=utf-8

reloadable=true

precompiled=true

compiler=httl.spi.compilers.JavassistCompiler

import.methods+=com.lishun.httl.staticMethods.ShiroKit

注:import.packages:领域模型包导入

import.methods:这里可以封装在httl模板页面上使用的静态方法

template.directory:模板文件目录;

template.suffix:模板文件后缀

input.encoding:资源加载编码

output.encoding: 模板输出编码

precompiled:是否预编译

reloadable: 是否热加载;开发模式下建议开启

compiler:(摘自httl官网)

用于将模板类编译成字节码,缺省使用根据JDK版本自适应编译器:(缺省值不用配)

1

compiler=httl.spi.compilers.AdaptiveCompiler

当前运行环境为JDK1.6以前版本时,AdaptiveCompiler将适配到JavassistCompiler,否则将适配到JdkCompiler。

你可以强制指定使用jdk自带的编译器:(必需要用JDK运行,JRE不行,JDK比JRE多编译工具包)

1

compiler=httl.spi.compilers.JdkCompiler

你也可以换成javassist编译:(如果为JRE运行,请使用javassist编译)

1

compiler=httl.spi.compilers.JavassistCompiler

当然,也就需要增加javassist的jar包依赖:

javassist-3.15.0-GA.jar

<dependency>

<groupId>org.javassist</groupId>

<artifactId>javassist</artifactId>

<version>3.15.0-GA</version>

</dependency>

5:编写applicationContext-shiro.xml 注:该文件是管理shiro的

<!-- 这里别忘了配置,否则会导致自定义的Realm的属性值无法注入 --><context:component-scan base-package="com.lishun"></context:component-scan><!-- 继承自AuthorizingRealm的自定义Realm,即指定Shiro验证用户登录的类为自定义的UserRealm.java --><bean id="shiroRealm" class="com.lishun.shiro.realm.UserRealm" ></bean> <!-- 基于Form表单的身份验证过滤器 --><bean id="formAuthenticationFilter"class="org.apache.shiro.web.filter.authc.FormAuthenticationFilter"><property name="usernameParam" value="username" /><property name="passwordParam" value="password" /><property name="loginUrl" value="/users/index.html" /><property name="successUrl" value="/index/index.html" /></bean><context:component-scan base-package="com.lishun"></context:component-scan><beanclass="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"depends-on="lifecycleBeanPostProcessor"><property name="proxyTargetClass" value="true" /></bean><!-- 这里主要是设置自定义的单Realm应用,若有多个Realm,可使用'realms'属性代替 --><bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"><property name="realm" ref="shiroRealm" /></bean><bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"><!-- 调用自定义的权限管理器 --><property name="securityManager" ref="securityManager" /><!-- 配置登陆成功后跳转地址 --><property name="successUrl" value="/index/index" /><!-- 配置登陆时请求的地址 --><property name="loginUrl" value="/users/index" /><!-- 如果请求的资源不再你的权限范围内,则跳转到error.htm --><property name="unauthorizedUrl" value="/users/noAuth" /><property name="filters"><map><entry key="authc" value-ref="formAuthenticationFilter"></entry></map></property><property name="filterChainDefinitions"><value><!-- anon表示此地址不需要任何权限即可访问 -->/users/*=anon<!--login页面和logout页面不需要验证 -->/login* = anon<!--访问所有文件,authc必须通过验证后才能访问 -->/** = authc</value></property></bean><!-- 相当于调用SecurityUtils.setSecurityManager(securityManager) --><beanclass="org.springframework.beans.factory.config.MethodInvokingFactoryBean"><property name="staticMethod"value="org.apache.shiro.SecurityUtils.setSecurityManager" /><property name="arguments" ref="securityManager" /></bean><!-- Shiro生命周期处理器 --><bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />

6.编写spring-mvc.xml文件 注:该文件是管理springmvc的

<!-- 自动扫描且只扫描@Controller --><context:component-scan base-package="com.lishun"use-default-filters="false"><context:include-filter type="annotation"expression="org.springframework.stereotype.Controller" /><context:include-filter type="annotation"expression="org.springframework.web.bind.annotation.ControllerAdvice" /></context:component-scan><!-- 启用SpringMVC的注解功能,它会自动注册HandlerMapping、HandlerAdapter、ExceptionResolver的相关实例 --><mvc:annotation-driven /><!-- 配置SpringMVC的视图解析器 httl视图 --><bean id="viewResolver" class="httl.web.springmvc.HttlViewResolver"><property name="contentType" value="text/html; charset=UTF-8" /></bean><!-- 在spring-mvc.xml配置文件添加Shiro Spring AOP权限注解的支持: --><aop:config proxy-target-class="true"></aop:config><beanclass="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"><property name="securityManager" ref="securityManager" /></bean><!-- 当前用户没有权限时跳转到的页面: --><bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">    <property name="exceptionMappings">    <props>    <prop key="org.apache.shiro.authz.UnauthorizedException">/users/unauthorizedView</prop>  </props>    </property>    </bean>

7:编写用户实体(User)和角色实体(Role)

public class User {private String name;private String password;private Role role;@Overridepublic String toString() {return "User [name=" + name + ", password=" + password + ", role="+ role + "]";}public String getName() {return name;}public User() {super();}public void setName(String name) {this.name = name;}public User(String name, String password) {super();this.name = name;this.password = password;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public Role getRole() {return role;}public void setRole(Role role) {this.role = role;}
}
---------------------------------------------------分割线public class Role {private String roleName;private Set<String> rolePermissions;public Set<String> getRolePermissions() {return rolePermissions;}public void setRolePermissions(Set<String> rolePermissions) {this.rolePermissions = rolePermissions;}public String getRoleName() {return roleName;}public void setRoleName(String roleName) {this.roleName = roleName;}
}

8:在httl模板上执行静态函数的类

/** 在httl模板上可以直接使用的函数*/
public class ShiroKit {/*** 禁止初始化*/private ShiroKit() {}/*** 获取 Subject* * @return Subject*/protected static Subject getSubject() {return SecurityUtils.getSubject();}/*** 验证当前用户是否拥有指定权限,使用时与lacksPermission 搭配使用* * @param permission*            权限名* @return 拥有权限:true,否则false*/public static boolean hasPermission(String permission) {boolean ret = getSubject() != null && permission != null && permission.length() > 0 && getSubject().isPermitted(permission);return ret;}/*** 与hasPermission标签逻辑相反,当前用户没有制定权限时,验证通过。* * @param permission*            权限名* @return 拥有权限:true,否则false*/public static boolean lacksPermission(String permission) {return !hasPermission(permission);}}

9:自定义用户验证规则(必须继承AuthorizingRealm)

public class UserRealm extends AuthorizingRealm {@Autowired@Qualifier("userDao")private UserDao userDao;/** 权限认证*/@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {// 根据用户配置用户与权限if (principals == null) {throw new AuthorizationException("PrincipalCollection method argument cannot be null.");}String name = (String) getAvailablePrincipal(principals);List<String> roles = new ArrayList<String>();User user = userDao.getUserByName(name);SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();// 把当前用户的角色保存到Subject中
        roles.add(user.getRole().getRoleName());info.addRoles(roles);// 把当前用户的权限保存到Subject中
        info.setStringPermissions(user.getRole().getRolePermissions());return info;}/** 登陆认证*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {UsernamePasswordToken token = (UsernamePasswordToken) authcToken;//获取页面输入用户名String username=(String) token.getPrincipal();//从dao层获取该用户
        System.out.println(userDao);User user = userDao.getUserByName(username);if (user == null) {throw new AuthorizationException();}SimpleAuthenticationInfo info = null;//存储令牌信息if (user.getName().equals(token.getUsername())) {info = new SimpleAuthenticationInfo(user.getName(),user.getPassword(), getName());}return info;}}

10:编写dao层

/** 这里我就不查询数据数据了,侧重点不在这里,所以写死用户数据*/
public class UserDao {private static List<User> list=new ArrayList<User>();private static Set<String> userPermissions=new HashSet<String>();private static Set<String> adminPermissions=new HashSet<String>();static {//lishun普通用户User lishun =new User();lishun.setName("lishun");lishun.setPassword("123");Role lishunRole=new Role();lishunRole.setRoleName("user");//lishun普通用户只拥有一个权限userPermissions.add("user:lishun:view");lishunRole.setRolePermissions(userPermissions);lishun.setRole(lishunRole);//admin超级用户User admin =new User();admin.setName("admin");admin.setPassword("123");Role adminRole=new Role();adminRole.setRoleName("admin");//admin用户拥有所有权限adminPermissions.add("user:lishun:view");adminPermissions.add("manager:lishun:view");adminRole.setRolePermissions(adminPermissions);admin.setRole(adminRole);list.add(admin);list.add(lishun);}public User getUserByName(String name){for (User u : list) {if(u.getName().equals(name)){return u;}}return null;}

11:编写控制器:用户登陆控制器

//不用任何权限都可以访问该控制器的方法
@Controller
public class UserController {/** 登陆页面*/@RequestMapping(value = "users/index", method = RequestMethod.GET)public String index() {return "users/login";}/** 验证用户*/@RequestMapping(value = "users/login", method = RequestMethod.POST)public String login(String username,String password,Model model){//获取到当前用户的的Subject及创建用户名/密码身份验证Token(即用户身份/凭证)Subject subject = SecurityUtils.getSubject();UsernamePasswordToken token = new UsernamePasswordToken(username, password);String error = null;try {//验证登陆
            subject.login(token);} catch (AuthenticationException e) {error = "warning message:Login failed,please check your username and password"; model.addAttribute("errorMessage", error);}if (error==null) {        return "redirect:../index/index";} else {return "redirect:index";}}/** 没有权限后跳转的页面*/@RequestMapping(value = "users/unauthorizedView", method = RequestMethod.GET)public String unauthorizedView() {return "users/unauthorizedView";}
}

12:login.httl文件

<!--#set(String msg="httl模板测试") -->
<!--#set(String manageHost = request.getScheme()+"://"+request.serverName+":"+"a".valueOf(request.serverPort)+request.getContextPath())--><html>
<body><form action="${manageHost}/users/login" method="post"><label style="color: red">${errorMessage}</label><table><tr><td>UserName:</td><td><input type="text" name="username" /></td></tr><tr><td>Password:</td><td><input type="password" name="password" /></td></tr><tr><td colspan="2"><input type="submit" value="Login" /></td></tr></table></form>
</body>
</html>
-----------------------分隔符

至于httl的语法大家可以去官网上浏览,我这里就不多说,http://httl.github.io/zh/syntax.html

打开url:http://localhost:8080/SpringMvc-Httl-shiro/users/login

就可以浏览了

13 编写控制器:用户主页控制器

@Controller
public class IndexController {/** 普通用户就可以访问该页面*/@RequiresPermissions("user:lishun:view")@RequestMapping(value = "index/index", method = RequestMethod.GET)public String index() {System.out.println(SecurityUtils.getSubject().isPermitted("user:lishun:view"));return "index/index";}
}
-------------------------------------------分割线

用户主页模板index.httl

<!--#set(String msg="httl模板测试") -->
<!--#set(String manageHost = request.getScheme()+"://"+request.serverName+":"+"a".valueOf(request.serverPort)+request.getContextPath())--><html>
<body>#if(hasPermission("manager:lishun:view"))超级用户登陆<a href="${manageHost}/manager/user">管理用户</a>#else(hasPermission("user:lishun:view"))普通用户登陆#end
</body>
</html>

14 编写控制器:管理员控制器

@Controller
@RequestMapping("manager")
public class ManagerController {/** 只有管理员才有权限查看本页面*/@RequiresPermissions("manager:lishun:view")@RequestMapping(value = "/user", method = RequestMethod.GET)public String index() {return "manager/userManager";}}
-------------------------------------------分割线

管理用户模板userManager.httl

<!--#set(String msg="httl模板测试") -->
<!--#set(String manageHost = request.getScheme()+"://"+request.serverName+":"+"a".valueOf(request.serverPort)+request.getContextPath())--><html>
<body><h1>只有admin角色才可以访问</h1>
</body>
</html>

当你是普通用户访问该页面时因没有权限而跳转到无权限页面

由于本人水平有限,若文章在表述和代码方面如有不妥之处,欢迎批评指正。留下你的脚印,欢迎评论!希望能互相学习。需要源码的留下邮箱

最后附上项目的目录结构

转载于:https://www.cnblogs.com/lishun1005/p/4581146.html

SpringMvc-Httl-shiro的整合相关推荐

  1. SpringMVC与Shiro快速整合

    SpringMVC与Shiro快速整合: 好久没有重新整合Shiro框架了,为了方便以后参考查阅,特此将步骤分享出来,共同学习. 一.配置XML文件: 1.到相应的pom.xml中添加shiro相关依 ...

  2. springMVC和Shiro框架整合使用简单示例 【转】

    为什么80%的码农都做不了架构师?>>>    一.目录结构 首先是目录结构如图: 二.pom.xml文件 <project xmlns="http://maven. ...

  3. cas4.2.7与shiro进行整合

    准备工作 cas单点登录开始前准备,请参考cas4.2.7实现单点登录. 与shiro进行整合 注:准备工作的基础上,对cas客户端进行如下改进. 引入相关jar包 shiro-cas-1.2.6.j ...

  4. SpringMVC Mybatis Shiro RestTemplate的实现客户端无状态验证及访问控制【转】

    2019独角兽企业重金招聘Python工程师标准>>> A.首先需要搭建SpringMVC+Shiro环境 a1.pom.xml配置  spring: <dependency& ...

  5. Spring+SpringMVC+MyBatis+Maven框架整合

    本文记录了Spring+SpringMVC+MyBatis+Maven框架整合的记录,主要记录以下几点  一.Maven需要引入的jar包  二.Spring与SpringMVC的配置分离  三.Sp ...

  6. 视频教程-基于springboot2.x+layui+shiro+redis整合前后端分离的权限管理系统-Java

    基于springboot2.x+layui+shiro+redis整合前后端分离的权限管理系统 拥有八年的Java项目开发经验,擅长Java.vue.SpringBoot.springCloud.sp ...

  7. 2015 java 第168期全套包含springmvc mybatis shiro视频教程

    Shiro教程升级了,新的shiro教程包括包括springmvc+mybaits+shiro总共6天的视频教程(含视频,源码,笔记等).包括92页的<Apache_Shiro参考手册中文版.p ...

  8. SpringMVC:学习笔记(10)——整合Ckeditor且实现图片上传

    SpringMVC:学习笔记(10)--整合Ckeditor且实现图片上传 配置CKEDITOR 精简文件 解压之后可以看到ckeditor/lang下面有很多语言的js,如果不需要那么多种语言的,可 ...

  9. 1.springMVC+spring+Mybatis的整合思路

    视频教程地址:http://edu.51cto.com/sd/2cfc2 SSM整合的过程:就是把一些东西交给spring管理,也就是添加配置文件的一个过程.那么有哪些东西我们要交给spring管理呢 ...

  10. SpringMvc 集成 shiro 实现权限角色管理-maven

    2019独角兽企业重金招聘Python工程师标准>>> SpringMvc 集成 shiro 实现权限角色管理 1.项目清单展示 2.项目源码解析  1)spring-context ...

最新文章

  1. photoshop 图片转 pdf
  2. 进大厂全靠自学,微软头条实习生现身说法:我是这样自学深度学习的丨课程传送门...
  3. java 实例化对象的几种姿势
  4. Win7重启后IP地址无效
  5. c语言 pow优化_c程序代码优化的一些方法
  6. react 示例_2020年的React Cheatsheet(+真实示例)
  7. vue可编辑div_vue2 如何实现div contenteditable=“true”(类似于v-model)的效果
  8. svn增量打包部署_超详细的jenkins持续集成工作原理、功能、部署方式等介绍
  9. freemarker数据格式化问题(即数值超过三位后自动添加逗号问题)
  10. 【原创】Kakfa log包源代码分析(一)
  11. LINUX备份,使用再生龙Clonezilla成功,remastersys、systemback都失败
  12. DSP28335学习记录(二)——外部中断和定时器中断
  13. win10 Python3安装pysqlcipher3的问题总结
  14. java中递归遍历文件夹下所有文件
  15. 电信光猫PT622 G开通ipv6
  16. shell脚本复制文件
  17. 李航统计学习方法总结与整理
  18. PostgreSQL multixact日志管理器说明
  19. grbl源码解析——速度前瞻(2)
  20. 苹果新品发布会?看美维公司的小伙伴如何评论!

热门文章

  1. python使用方法-在Python中使用next()方法操作文件的教程
  2. Fisher_Yates算法
  3. UVa11389 The Bus Driver Problem(贪心)
  4. 第四十四章 Django ORM
  5. php 获取用户的IP、地址、来源
  6. 信度和效度 智商计算
  7. Linux环境搭建Hadoop伪分布模式
  8. 移动端给img加上max-width:100%
  9. 如何查看Oracle的用户权限
  10. 禅道项目管理软件的命令行入口