第九章:Shiro整合Spring【重点】
工程结构:
一、创建maven工程【创建过程请参考:http://www.cnblogs.com/josephcnblog/articles/6816564.html】
修改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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.java1234.shiro</groupId> <artifactId>ShiroWeb</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <dependencies> <!-- shiro的核心包和shiro的web支持 --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.2.5</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-web</artifactId> <version>1.2.5</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.2.5</version> </dependency> <!-- 添加Junit支持 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> </dependency> <!-- 添加Servlet支持 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> </dependency> <!-- 添加JSP支持 --> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>2.3.1</version> </dependency> <!-- 添加JSTL支持 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- 添加日志支持 --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.21</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>commons-beanutils</groupId> <artifactId>commons-beanutils</artifactId> <version>1.8.3</version> </dependency> <!-- mysql数据库驱动包 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.37</version> </dependency> <!-- IO包 --> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.5</version> </dependency> <!-- 添加Spring支持 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.1.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>4.1.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>4.1.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.1.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>4.1.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.1.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.1.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>4.1.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>4.1.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>4.1.7.RELEASE</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.3.0</version> </dependency> </dependencies> </project>
二、新建包com.java1234.shiro.controller、com.java1234.shiro.service、com.java1234.shiro.service.impl、com.java1234.shiro.dao、com.java1234.shiro.entities、com.java1234.shiro.utils、com.java1234.shiro.realm
数据库同第十章
Users.java
public class Users { private Integer id; private String userName; private String password;
UserDao.java
package com.java1234.shiro.dao; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.HashSet; import java.util.Set; import com.java1234.shiro.utils.DBHelper; import com.java1234.shiro.entities.Users; public class UserDao { // 数据库参数 private static Connection conn = null; private static PreparedStatement ps = null; private static ResultSet rs = null; // 连接参数 private static String filename = null; private static String jdbc_driverClassName = null; private static String jdbc_url = null; private static String jdbc_userName = null; private static String jdbc_password = null; static { // filename = "src\\main\\resources\\db.properties"; filename = "G:\\Test2\\ShiroWeb\\src\\main\\resources\\db.properties"; jdbc_driverClassName = DBHelper.getValueByKey(filename, "driverClassName"); jdbc_url = DBHelper.getValueByKey(filename, "url"); jdbc_userName = DBHelper.getValueByKey(filename, "userName"); jdbc_password = DBHelper.getValueByKey(filename, "password"); try { conn = DBHelper.getConnection(jdbc_driverClassName, jdbc_url, jdbc_userName, jdbc_password); } catch (Exception e) { e.printStackTrace(); } } /** * 根据用户名获取用户信息 * @param userName 用户输入的用户名 * @return * @throws Exception */ public Users getByUserName(String userName) throws Exception { Users user = null; String sql = "SELECT * FROM users WHERE userName = ? LIMIT 1"; try { ps = DBHelper.getPreparedStatement(conn, sql); ps.setString(1, userName); ResultSet rs = ps.executeQuery(); if (rs.next()) { user = new Users(); user.setId(rs.getInt(1)); user.setUserName(rs.getString(2)); user.setPassword(rs.getString(3)); } } catch (Exception e) { e.printStackTrace(); } return user; } /** * 根据用户名获取用户的角色 * @param userName * @return 角色列表 * @throws Exception */ public Set<String> getRoles(String userName) throws Exception { Set<String> roles = new HashSet<String>(); String sql = "SELECT r.roleName FROM users u LEFT JOIN roles r ON u.roleId = r.id WHERE u.userName = ?"; try { ps = DBHelper.getPreparedStatement(conn, sql); ps.setString(1, userName); rs = ps.executeQuery(); while (rs.next()) { roles.add(rs.getString("roleName")); } } catch (Exception e) { e.printStackTrace(); } return roles; } /** * 根据用户名获取用户权限 * @param userName 用户名 * @return 权限列表 * @throws Exception */ public Set<String> getPermissions(String userName) throws Exception { Set<String> permissions = new HashSet<String>(); String sql = "SELECT p.permissionName FROM users u LEFT " + "JOIN roles r ON u.roleId = r.id LEFT " + "JOIN permissions p ON r.id = p.roleId WHERE u.userName = ?"; try { ps = DBHelper.getPreparedStatement(conn, sql); ps.setString(1, userName); rs = ps.executeQuery(); while (rs.next()) { permissions.add(rs.getString("permissionName")); } } catch (Exception e) { e.printStackTrace(); } return permissions; } }
UserService.java
package com.java1234.shiro.service; import java.util.Set; import com.java1234.shiro.entities.Users; public interface UserService { /** * 根据用户名获取用户信息 * @param userName 用户输入的用户名 * @return * @throws Exception */ public Users getByUserName(String userName) throws Exception; /** * 根据用户名获取用户的角色 * @param userName * @return 角色列表 * @throws Exception */ public Set<String> getRoles(String userName) throws Exception; /** * 根据用户名获取用户权限 * @param userName 用户名 * @return 权限列表 * @throws Exception */ public Set<String> getPermissions(String userName) throws Exception; }
UserServiceImpl.java
package com.java1234.shiro.service.impl; import java.util.Set; import javax.annotation.Resource; import org.springframework.stereotype.Service; import com.java1234.shiro.dao.UserDao; import com.java1234.shiro.entities.Users; import com.java1234.shiro.service.UserService; @Service("userService") public class UserServiceImpl implements UserService { @Resource private UserDao userDao; /** * 根据用户名获取用户信息 * @param userName 用户输入的用户名 * @return 用户信息 * @throws Exception */ public Users getByUserName(String userName) throws Exception { return userDao.getByUserName(userName); } /** * 根据用户名获取用户的角色 * @param userName * @return 角色列表 * @throws Exception */ public Set<String> getRoles(String userName) throws Exception { return userDao.getRoles(userName); } /** * 根据用户名获取用户权限 * @param userName 用户名 * @return 权限列表 * @throws Exception */ public Set<String> getPermissions(String userName) throws Exception { return userDao.getPermissions(userName); } }
DBHelper.java
package com.java1234.shiro.utils; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.Properties; /** * 连接数据库 */ public class DBHelper { // 驱动参数 private static Connection conn = null; private static PreparedStatement ps = null; // 连接 public static Connection getConnection(String driverClassName, String url, String userName, String password) throws Exception { try { Class.forName(driverClassName); conn = DriverManager.getConnection(url, userName, password); } catch (Exception e) { e.printStackTrace(); } return conn; } public static PreparedStatement getPreparedStatement(Connection conn, String sql) throws Exception { try { ps = conn.prepareStatement(sql); } catch (Exception e) { e.printStackTrace(); } return ps; } // 释放资源 public static void closePreparedStatement(PreparedStatement ps) throws Exception { try { if (ps != null) { ps.close(); ps = null; } } catch (Exception e) { e.printStackTrace(); } } public static void closeConnection(Connection conn) throws Exception { try { if (conn != null) { conn.close(); conn = null; } } catch (Exception e) { e.printStackTrace(); } } public static void closeResultSet(ResultSet rs) throws Exception { try { if (rs != null) { rs.close(); rs = null; } } catch (Exception e) { e.printStackTrace(); } } public static String getValueByKey(String filename, String key) { Properties ps = new Properties(); InputStream is = null; try { is = new BufferedInputStream(new FileInputStream(filename)); ps.load(is); String value = ps.getProperty(key); return value; } catch (Exception e) { e.printStackTrace(); return null; } finally { if (is != null) { try { is.close(); is = null; } catch (IOException e) { e.printStackTrace(); } } } } }
MyRealm.java
package com.java1234.shiro.realm; import java.util.Iterator; import java.util.Set; import javax.annotation.Resource; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; 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 com.java1234.shiro.entities.Users; import com.java1234.shiro.service.UserService; public class MyRealm extends AuthorizingRealm { @Resource private UserService userService; /** * 验证当前登录的用户 */ @Override protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken token) throws AuthenticationException { String userName = (String) token.getPrincipal(); try { Users user = userService.getByUserName(userName); // 根据用户名获取用户 if (user != null) { AuthenticationInfo info = new SimpleAuthenticationInfo( user.getUserName(), user.getPassword(), "XXX"); return info; } } catch (Exception e) { e.printStackTrace(); } return null; } /** * 为当前用户授予角色和权限, 在用户成功登录后才会执行这个方法 */ @Override protected AuthorizationInfo doGetAuthorizationInfo( PrincipalCollection principals) { /** * 获取用户名,这里的用户名是数据库中的用户名,即从上面的方法doGetAuthenticationInfo() * 中获取的user中的user.getUserName()中获取到的合法的用户名, 通过这个用户名可以获取到用户拥有的角色和权限 */ String userName = (String) principals.getPrimaryPrincipal(); // 绑定用户所拥有的角色和权限 SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); try { // 根据用户名获取用户角色,并将其绑定到info中 Set<String> roles = userService.getRoles(userName); Iterator<String> iterator = roles.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } info.setRoles(roles); // 根据用户名获取用户权限,并剑气绑定到info中 Set<String> permissions = userService.getPermissions(userName); Iterator<String> iterator2 = permissions.iterator(); while (iterator2.hasNext()) { System.out.println(iterator2.next()); } info.setStringPermissions(permissions); } catch (Exception e) { e.printStackTrace(); } return info; } }
UserController.java
package com.java1234.shiro.controller; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.session.Session; import org.apache.shiro.subject.Subject; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import com.java1234.shiro.entities.Users; @Controller @RequestMapping("/user") public class UserController { @RequestMapping("/login") public String login(Users user, HttpServletRequest request, HttpServletResponse response) { // 获取登录对象 Subject subject = SecurityUtils.getSubject(); // 将登录的用户名和密码绑定到令牌Token UsernamePasswordToken token = new UsernamePasswordToken(user.getUserName(), user.getPassword()); // 尝试登录 try { subject.login(token); // Shiro的会话机制 Session session = subject.getSession(); session.setAttribute("sessionInfo", "session会话中的数据!"); subject.login(token); // 登录校验 return "redirect:/success.jsp"; } catch (Exception e) { // 登录失败 e.printStackTrace(); request.setAttribute("user", user); request.setAttribute("errorInfo", "用户名或密码错误!"); return "index"; } } }
在src/main/resources下新建包com.java1234.mappers,创建UserMapper.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.java1234.shiro.dao.UserDao"> <resultMap type="com.java1234.shiro.entities.Users" id="UserResult"> <result property="id" column="id"/> <result property="userName" column="userName"/> <result property="password" column="password"/> </resultMap> <select id="getByUserName" parameterType="string" resultMap="UserResult"> SELECT * FROM users WHERE userName = #{userName} LIMIT 1 </select> <select id="getRoles" parameterType="string" resultType="string"> SELECT r.roleName FROM users u LEFT JOIN roles r ON u.roleId = r.id WHERE u.userName = #{userName} </select> <select id="getPermissions" parameterType="string" resultType="string"> SELECT p.permissionName FROM users u LEFT JOIN roles r ON u.roleId = r.id LEFT JOIN permissions p ON r.id = p.roleId WHERE u.userName = #{userName} </select> </mapper>
在src/main/resources下创建db.properties、applicationContext.xml、log4j.properties、mybatis-config.xml、spring-mvc.xml
未完待续、、、、、、、、、