从懵懂到了解,再到熟悉,是一个进步的过程!
先撸代码,跑起来看效果,再做详细的介绍,开始干活!
1,先列出工程目录结构,自己需要创建对应层级的程序和相关配置文件。
2,导入maven依赖的jar包。打开pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>mvc_shiro</groupId>
<artifactId>mvc_shiro</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>mvc_shiro Maven Webapp</name> <!-- 这个地址可以改为自己项目的地址-->
<url>http://maven.apache.org</url> <properties>
<!-- spring版本号 -->
<spring.version>4.0.2.RELEASE</spring.version>
<!-- mybatis版本号 -->
<mybatis.version>3.2.6</mybatis.version>
<!-- log4j日志文件管理包版本 -->
<slf4j.version>1.7.7</slf4j.version>
<log4j.version>1.2.17</log4j.version>
</properties> <dependencies>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-all -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-all</artifactId>
<version>1.2.4</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<!-- 表示开发的时候引入,发布的时候不会加载此包 -->
<scope>test</scope>
</dependency>
<!-- spring核心包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- mybatis核心包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<!-- mybatis/spring包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.2.2</version>
</dependency>
<!-- 导入java ee jar 包 -->
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
</dependency>
<!-- 导入Mysql数据库链接jar包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.30</version>
</dependency>
<!-- 导入dbcp的jar包,用来在applicationContext.xml中配置数据库 -->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.2.2</version>
</dependency>
<!-- JSTL标签类 -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- 日志文件管理包 -->
<!-- log start -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<!-- 格式化对象,方便输出日志 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.1.41</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency> <dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- log end -->
<!-- 映入JSON -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<!-- 上传组件包 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.9</version>
</dependency>
</dependencies>
<build>
<finalName>mvc_shiro</finalName>
</build>
</project>
3,配置web.xml文件。简单的spring-mvc配置。
<?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"
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>Archetype Created Web Application</display-name>
<!-- Spring和mybatis的配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mybatis.xml</param-value>
</context-param>
<!-- 编码过滤器 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<async-supported>true</async-supported>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Spring监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 防止Spring内存溢出监听器 -->
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>
<!-- 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>
<async-supported>true</async-supported>
</servlet> <!-- 配置由Spring提供的过滤器,用于整合shiro框架 -->
<!-- 在项目启动的过程中,当前过滤器会从Spring工厂中提取同名对象 -->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>
org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Spring MVC 普通页面拦截 -->
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<!-- 此处可以可以配置成*.do,对应struts的后缀习惯 -->
<url-pattern>/</url-pattern>
</servlet-mapping> <welcome-file-list>
<welcome-file>/index.jsp</welcome-file>
</welcome-file-list> </web-app>
4,配置数据库配置文件jdbc.properties,需要配置自己的本地的数据库信息。
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/自己的数据库名称
username=自己的数据库登录账户
password=自己的数据库登录密码
#定义初始连接数
initialSize=0
#定义最大连接数
maxActive=20
#定义最大空闲
maxIdle=20
#定义最小空闲
minIdle=1
#定义最长等待时间
maxWait=60000
5,配置日志log4j.properties。注意 自己指定日志输出的位置。
#定义LOG输出级别
log4j.rootLogger=DEBUG,File
#定义日志输出目的地为控制台
#log4j.appender.Console=org.apache.log4j.ConsoleAppender
#log4j.appender.Console.Target=System.out
#可以灵活地指定日志输出格式,下面一行是指定具体的格式
#log4j.appender.Console.layout = org.apache.log4j.PatternLayout
#log4j.appender.Console.layout.ConversionPattern=[%c] - %m%n #文件大小到达指定尺寸的时候产生一个新的文件
log4j.appender.File = org.apache.log4j.RollingFileAppender
#指定输出目录
log4j.appender.File.File = 需要自己配置输出的日志位置及日志名称。比如c:/desktop/shiro.log
#定义文件最大大小
log4j.appender.File.MaxFileSize = 10MB
log4j.appender.File.Encoding = UTF-8
# 输出所以日志,如果换成DEBUG表示输出DEBUG以上级别日志
log4j.appender.File.Threshold = ALL
log4j.appender.File.layout = org.apache.log4j.PatternLayout
log4j.appender.File.layout.ConversionPattern =[%p] [%d{yyyy-MM-dd HH\:mm\:ss}][%c]%m%n
6,配置shiro-context.xml配置文件。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" /> <!--加载管理器-->
<property name="loginUrl" value="/user/login" /> <!--没有登录的时候,跳转到这个页面-->
<property name="unauthorizedUrl" value="/user/nopermission" /> <!--当没有权限的时候,跳转到这个url--> <property name="filterChainDefinitions">
<value>
/user/login = anon <!--可以不需要登录-->
/user/readName = authc, perms[/readName] <!-- perms 表示需要该权限才能访问的页面 -->
/user/readData = authc, perms[/readData]
/user/* = authc <!-- authc 表示需要认证才能访问的页面 -->
</value>
</property>
</bean> <!-- 自定义Realm -->
<bean id="myShiroRealm" class="com.Shiro.MyShiroReaml">
<!-- businessManager 用来实现用户名密码的查询 -->
<property name="shiroService" ref="accountService" />
</bean> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!-- 注入realm -->
<property name="realm" ref="myShiroRealm"/>
</bean> <!--声明一个Service 注入到自定义Realm-->
<bean id="accountService" class="com.Service.Impl.ShiroServiceImpl"/>
<!-- <bean id="shiroCacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<property name="cacheManager" ref="cacheManager" /> </bean> -->
</beans>
7,配置spring-mvc.xml文件。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"> <import resource="shiro-context.xml"/>
<!-- 自动扫描该包,使SpringMVC认为包下用了@controller注解的类是控制器 -->
<context:component-scan base-package="com.*" />
<!--避免IE执行AJAX时,返回JSON出现下载文件 -->
<bean id="mappingJacksonHttpMessageConverter"
class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
</list>
</property>
</bean> <!-- 启动SpringMVC的注解功能,完成请求和注解POJO的映射 -->
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="mappingJacksonHttpMessageConverter" /> <!-- JSON转换器 -->
</list>
</property>
</bean>
<!-- 定义跳转的文件的前后缀 ,视图模式配置-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 这里的配置我的理解是自动给后面action的方法return的字符串加上前缀和后缀,变成一个 可用的url地址 -->
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean> <!-- 配置文件上传,如果没有使用文件上传可以不用配置,当然如果不配,那么配置文件中也不必引入上传组件包 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 默认编码 -->
<property name="defaultEncoding" value="utf-8" />
<!-- 文件大小最大值 -->
<property name="maxUploadSize" value="10485760000" />
<!-- 内存中的最大值 -->
<property name="maxInMemorySize" value="40960" />
</bean> </beans>
8,配置spring-mybatis.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<!-- 自动扫描 -->
<context:component-scan base-package="com" />
<import resource="shiro-context.xml"/>
<!-- 引入配置文件 -->
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:jdbc.properties" />
</bean> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
<!-- 初始化连接大小 -->
<property name="initialSize" value="${initialSize}"/>
<!-- 连接池最大数量 -->
<property name="maxActive" value="${maxActive}"/>
<!-- 连接池最大空闲 -->
<property name="maxIdle" value="${maxIdle}"/>
<!-- 连接池最小空闲 -->
<property name="minIdle" value="${minIdle}"/>
<!-- 获取连接最大等待时间 -->
<property name="maxWait" value="${maxWait}"/>
</bean> <!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 自动扫描mapping.xml文件 -->
<property name="mapperLocations" value="classpath:mapping/*.xml"/>
</bean> <!-- DAO接口所在包名,Spring会自动查找其下的类 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.Dao" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean> <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean> </beans>
9,在本地数据库维护初始化数据。
CREATE DATABASE `shirotest;USE `shirotest`; /*Table structure for table `permission` */ DROP TABLE IF EXISTS `permission`; CREATE TABLE `permission` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`url` varchar(30) NOT NULL,
`roleid` int(11) DEFAULT NULL,
`description` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; /*Data for the table `permission` */ insert into `permission`(`id`,`url`,`roleid`,`description`) values (1,'/readName',1,'查看名单'),(2,'/readData',2,'查看数据'); /*Table structure for table `role` */ DROP TABLE IF EXISTS `role`; CREATE TABLE `role` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`role` varchar(20) NOT NULL,
`description` varchar(120) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; /*Data for the table `role` */ insert into `role`(`id`,`role`,`description`) values (1,'管理员','管理员'),(2,'普通用户','普通用户'); /*Table structure for table `user` */ DROP TABLE IF EXISTS `user`; CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`account` varchar(20) NOT NULL,
`password` varchar(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; /*Data for the table `user` */ insert into `user`(`id`,`account`,`password`) values (1,'',''),(2,'',''); /*Table structure for table `user_role` */ DROP TABLE IF EXISTS `user_role`; CREATE TABLE `user_role` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`userid` int(11) NOT NULL,
`roleid` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC; /*Data for the table `user_role` */ insert into `user_role`(`id`,`userid`,`roleid`) values (1,1,1),(2,2,2);
10,实现自己的reaml类。
package com.Shiro; import com.Controller.loginController;
import com.Pojo.Permission;
import com.Pojo.User;
import com.Service.ShiroService;
import org.apache.log4j.Logger;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection; import java.util.List; public class MyShiroReaml extends AuthorizingRealm {
private Logger logger = Logger.getLogger(MyShiroReaml.class); 0
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection pc) {
logger.debug("doGetAuthorizationInfo----权限验证");
/**
*
* 流程
* 1.根据用户user->2.获取角色id->3.根据角色id获取权限permission
*/
//方法一:获得user对象
User user=(User)pc.getPrimaryPrincipal();
logger.debug("user========="+user);
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//获取permission
if(user!=null) {
List<Permission> permissionsByUser = shiroService.getPermissionsByUser(user);
if (permissionsByUser.size()!=0) {
for (Permission p: permissionsByUser) { info.addStringPermission(p.getUrl());
}
return info;
}
}
return null;
} // 认证方法
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
logger.debug("doGetAuthenticationInfo----登录验证");
//验证账号密码
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
logger.debug("1:"+token.getUsername());
User user = shiroService.getUserByUserName(token.getUsername());
logger.debug("2");
if(user==null){
return null;
}
//最后的比对需要交给安全管理器
//三个参数进行初步的简单认证信息对象的包装
AuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), this.getClass().getSimpleName());
logger.debug("info===="+info);
return info;
} private ShiroService shiroService; public ShiroService getShiroService() {
return shiroService;
} public void setShiroService(ShiroService shiroService) {
this.shiroService = shiroService;
}
}
11,完善pojo对象类。
Permission.java
package com.Pojo; import org.springframework.stereotype.Component; @Component
public class Permission {
private int id;
private String token;
/**资源url**/
private String url;
/**权限说明**/
private String description;
/**所属角色编号**/
private int roleId; public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getToken() {
return token;
} public void setToken(String token) {
this.token = token;
} public String getUrl() {
return url;
} public void setUrl(String url) {
this.url = url;
} public String getDescription() {
return description;
} public void setDescription(String description) {
this.description = description;
} public int getRoleId() {
return roleId;
} public void setRoleId(int roleId) {
this.roleId = roleId;
} @Override
public String toString() {
return "PermissionPojo{" +
"id=" + id +
", token='" + token + '\'' +
", url='" + url + '\'' +
", description='" + description + '\'' +
", roleId=" + roleId +
'}';
}
}
Role.java
package com.Pojo; public class Role {
private int id;
/**角色**/
private String role;
/**说明**/
private String description; public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getRole() {
return role;
} public void setRole(String role) {
this.role = role;
} public String getDescription() {
return description;
} public void setDescription(String description) {
this.description = description;
} @Override
public String toString() {
return "Role{" +
"id=" + id +
", role='" + role + '\'' +
", description='" + description + '\'' +
'}';
}
}
User.java
package com.Pojo; import org.springframework.stereotype.Component; @Component
public class User {
private int id;
private String account;
private String password; public User(int id, String account, String password) {
this.id = id;
this.account = account;
this.password = password;
} public User() {
super();
} public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getAccount() {
return account;
} public void setAccount(String account) {
this.account = account;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
} @Override
public String toString() {
return "UserPojo{" +
"id=" + id +
", account='" + account + '\'' +
", password='" + password + '\'' +
'}';
}
}
12,开始写验证代码,按照Controller-Service-Dao-Mapping
LoginController.java
package com.Controller; import com.Pojo.User;
import com.Service.ShiroService;
import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpSession; @Controller
@RequestMapping("/user")
public class loginController {
@Autowired
private ShiroService shiroService;
private Logger logger = Logger.getLogger(loginController.class);
/**
* 验证登录
* @param username
* @param password
* @param session
* @return url
*/
@RequestMapping(value = "/login")
public String Login(String username, String password, HttpSession session, Model model){
if(username==null){
model.addAttribute("message", "账号不为空");
return "login";
}
//主体,当前状态为没有认证的状态“未认证”
Subject subject = SecurityUtils.getSubject();
// 登录后存放进shiro token
UsernamePasswordToken token=new UsernamePasswordToken(username,password);
User user;
//登录方法(认证是否通过)
//使用subject调用securityManager,安全管理器调用Realm
try {
//利用异常操作
//需要开始调用到Realm中
logger.debug("========================================");
logger.debug("1、进入认证方法");
subject.login(token);
user = (User)subject.getPrincipal();
session.setAttribute("user",subject);
model.addAttribute("message", "登录完成");
logger.debug("登录完成");
} catch (UnknownAccountException e) {
model.addAttribute("message", "账号密码不正确");
return "index";
}
return "test";
} @RequestMapping("/check")
public String check(HttpSession session){
Subject subject=(Subject)session.getAttribute("user");
User user=(User)subject.getPrincipal();
logger.debug(user.toString());
return "permission";
} @RequestMapping("/readName")
public String readName(HttpSession session){ return "name";
} @RequestMapping("/readData")
public String readData(){ return "data";
} @RequestMapping("/nopermission")
public String noPermission(){
return "error";
}
}
ShiroService.java
package com.Service; import com.Pojo.Permission;
import com.Pojo.User; import java.util.List; public interface ShiroService { /**
* 根据账号获取账号密码
* @param username
* @return UserPojo
*/
User getUserByUserName(String username); /**
* 根据账号获取该账号的权限
*
* @param user
* @return List
*/
List<Permission> getPermissionsByUser(User user);
}
ShiroServiceImpl.java
package com.Service.Impl; import com.Dao.ShiroDao;
import com.Pojo.Permission;
import com.Pojo.User;
import com.Service.ShiroService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import java.util.ArrayList;
import java.util.List; @Service("shiroService")
public class ShiroServiceImpl implements ShiroService { @Autowired
private ShiroDao shiroDao; public User getUserByUserName(String username) {
//根据账号获取账号密码
User userByUserName = shiroDao.getUserByUserName(username);
return userByUserName;
} public List<Permission> getPermissionsByUser(User user) {
//获取到用户角色userRole
List<Integer> roleId = shiroDao.getUserRoleByUserId(user.getId());
List<Permission> perArrary = new ArrayList<Permission>(); if (roleId!=null&&roleId.size()!=0) {
//根据roleid获取peimission
for (Integer i : roleId) {
perArrary.addAll(shiroDao.getPermissionsByRoleId(i));
}
} System.out.println(perArrary);
return perArrary;
}
}
ShiroDao.java
package com.Dao; import com.Pojo.Permission;
import com.Pojo.User;
import org.springframework.stereotype.Component; import java.util.List; @Component
public interface ShiroDao { /**
* 根据账号获取账号密码
* @param username
* @return UserPojo
*/
User getUserByUserName(String username); /**
* 根据角色id获取该账号的权限
* @param roleId
* @return List
*/
List<Permission> getPermissionsByRoleId(int roleId); /**
* 根据userId获取角色id
* @param id
* @return LIST
*/
List<Integer> getUserRoleByUserId(int id);
}
Shiro.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.Dao.ShiroDao">
<select id="getUserByUserName" resultType="com.Pojo.User">
select * FROM user
WHERE account= #{0}
</select> <select id="getUserRoleByUserId" resultType="int">
SELECT roleid FROM user_role
where userid = #{_parameter}
</select> <select id="getPermissionsByRoleId" resultType="com.Pojo.Permission">
SELECT a.id,a.url,a.roleid as roleId,a.description FROM permission a
WHERE roleid = #{_parameter}
</select> </mapper>
13,简单的页面jsp,可参考,也可自己撸前端的代码,本文只起示例作用。
WEB-INF/index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<body>
<h2>Hello World!</h2> <script type="text/javascript">
window.location.href="user/login";
</script>
</body>
</html>
WEB-INF/jsp/data.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body> <ul>
<li>数据1</li>
<li>数据2</li>
</ul>
</body>
</html>
WEB-INF/jsp/error.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body> <h2>你没有查看的权利</h2>
</body>
</html>
WEB-INF/jsp/index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<body>
<h2>Hello World!</h2> <form action="login" method="post" >
账号:<input type="text" name="username"/>
密码<input type="password" name="password"/>
<button type="submit">提交</button>
</form>
</body>
</html>
WEB-INF/jsp/login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="login" method="post" style="margin: 0 auto">
账号:<input type="text" name="username" value="${message}"/>
密码<input type="password" name="password"/>
<button type="submit">提交</button>
</form>
</body>
</html>
WEB-INF/jsp/name.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body> <ul>
<li>小米</li>
<li>小红</li>
</ul> </body>
</html>
WEB-INF/jsp/permission.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<a href="readName">查看名单</a>
<a href="readData">查看数据</a>
</body>
</html>
WEB-INF/jsp/test.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${message} <a href="check">查看</a>
</body>
</html>
至此,框架搭建起了,测试代码也撸好了。假设上面一切顺利,没有飘红报错,那么就可以用maven帮我们打个war包,直接扔tomcat上,跑起来玩了。如图打包。浏览器访问127.0.0.1:8080/mvc_shiro
实际操作中,可能不会很顺利,有遇到一些问题,但是都解决了,现在没法复现,所以暂不列出,如果有遇到问题的,欢迎留言讨论。后续会把自己的一些理解添加到博文中,今天累了,先溜了。。