【shiro】2.spring整合shiro,注解控制shiro用户/角色/权限And/OR,没有权限跳转到固定页面
这几天粗浅的把shiro整合到spring中,并且注解控制shiro用户/角色/权限And/OR
步骤:
1.首先maven搭建web项目
2.创建数据库 user/role/authority 其中,role->user是一对多,role->authority是多对多
shiros.sql内容:
/*
SQLyog Ultimate v11.24 (32 bit)
MySQL - 5.5.41 : Database - shiros
*********************************************************************
*/ /*!40101 SET NAMES utf8 */; /*!40101 SET SQL_MODE=''*/; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`shiros` /*!40100 DEFAULT CHARACTER SET utf8 */; USE `shiros`; /*Table structure for table `authority` */ DROP TABLE IF EXISTS `authority`; CREATE TABLE `authority` (
`authorityId` varchar(36) NOT NULL,
`authorityName` varchar(20) DEFAULT NULL,
`authorityContent` varchar(500) DEFAULT NULL,
PRIMARY KEY (`authorityId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8; /*Data for the table `authority` */ insert into `authority`(`authorityId`,`authorityName`,`authorityContent`) values ('97e2a86d-802c-415f-8d2e-6d94a3390001','疾病:增加',NULL),('97e2a86d-802c-415f-8d2e-6d94a3390002','疾病:删除',NULL),('97e2a86d-802c-415f-8d2e-6d94a3390003','疾病:修改',NULL),('97e2a86d-802c-415f-8d2e-6d94a3390004','疾病:查看',NULL),('97e2a86d-802c-415f-8d2e-6d94a3390005','产品:增加',NULL),('97e2a86d-802c-415f-8d2e-6d94a3390006','产品:删除',NULL),('97e2a86d-802c-415f-8d2e-6d94a3390007','产品:修改',NULL),('97e2a86d-802c-415f-8d2e-6d94a3390008','产品:查看',NULL); /*Table structure for table `role` */ DROP TABLE IF EXISTS `role`; CREATE TABLE `role` (
`roleId` varchar(36) NOT NULL,
`roleName` varchar(36) DEFAULT NULL,
`roleGrade` int(11) DEFAULT NULL,
PRIMARY KEY (`roleId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8; /*Data for the table `role` */ insert into `role`(`roleId`,`roleName`,`roleGrade`) values ('97e2a86d-802c-415f-8d2e-6d94a3390121','管理员3',1),('97e2a86d-802c-415f-8d2e-6d94a3390122','管理员2',1),('97e2a86d-802c-415f-8d2e-6d94a3390123','管理员1',1); /*Table structure for table `roleauthority` */ DROP TABLE IF EXISTS `roleauthority`; CREATE TABLE `roleauthority` (
`roleId` varchar(36) NOT NULL,
`authorityId` varchar(36) NOT NULL,
PRIMARY KEY (`roleId`,`authorityId`),
KEY `FK_Relationship_3` (`authorityId`),
CONSTRAINT `FK_Relationship_2` FOREIGN KEY (`roleId`) REFERENCES `role` (`roleId`),
CONSTRAINT `FK_Relationship_3` FOREIGN KEY (`authorityId`) REFERENCES `authority` (`authorityId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8; /*Data for the table `roleauthority` */ insert into `roleauthority`(`roleId`,`authorityId`) values ('97e2a86d-802c-415f-8d2e-6d94a3390123','97e2a86d-802c-415f-8d2e-6d94a3390001'),('97e2a86d-802c-415f-8d2e-6d94a3390123','97e2a86d-802c-415f-8d2e-6d94a3390002'),('97e2a86d-802c-415f-8d2e-6d94a3390123','97e2a86d-802c-415f-8d2e-6d94a3390003'),('97e2a86d-802c-415f-8d2e-6d94a3390123','97e2a86d-802c-415f-8d2e-6d94a3390004'),('97e2a86d-802c-415f-8d2e-6d94a3390122','97e2a86d-802c-415f-8d2e-6d94a3390005'),('97e2a86d-802c-415f-8d2e-6d94a3390122','97e2a86d-802c-415f-8d2e-6d94a3390006'); /*Table structure for table `user` */ DROP TABLE IF EXISTS `user`; CREATE TABLE `user` (
`userId` varchar(36) NOT NULL,
`roleId` varchar(36) NOT NULL,
`userName` varchar(20) DEFAULT NULL,
`password` varchar(20) DEFAULT NULL,
PRIMARY KEY (`userId`),
KEY `FK_Relationship_1` (`roleId`),
CONSTRAINT `FK_Relationship_1` FOREIGN KEY (`roleId`) REFERENCES `role` (`roleId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8; /*Data for the table `user` */ insert into `user`(`userId`,`roleId`,`userName`,`password`) values ('97e2a86d-802c-415f-8d2e-6d94a3390110','97e2a86d-802c-415f-8d2e-6d94a3390122','李四','123456'),('97e2a86d-802c-415f-8d2e-6d94a3390111','97e2a86d-802c-415f-8d2e-6d94a3390123','张三','123456'),('97e2a86d-802c-415f-8d2e-6d94a3390112','97e2a86d-802c-415f-8d2e-6d94a3390121','王五','123456'); /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
3.创建完成之后,使用hibernate反转工具,生成实体
user.java
package com.sxd.entity; import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator; /**
* User entity. @author MyEclipse Persistence Tools
*/
@Entity
@Table(name = "user", catalog = "shiros")
public class User implements java.io.Serializable { // Fields private String userId;
private Role role;
private String userName;
private String password; // Constructors /** default constructor */
public User() {
} /** minimal constructor */
public User(Role role) {
this.role = role;
} /** full constructor */
public User(Role role, String userName, String password) {
this.role = role;
this.userName = userName;
this.password = password;
} // Property accessors
@GenericGenerator(name = "generator", strategy = "uuid.hex")
@Id
@GeneratedValue(generator = "generator")
@Column(name = "userId", unique = true, nullable = false, length = 36)
public String getUserId() {
return this.userId;
} public void setUserId(String userId) {
this.userId = userId;
} @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "roleId", nullable = false)
public Role getRole() {
return this.role;
} public void setRole(Role role) {
this.role = role;
} @Column(name = "userName", length = 20)
public String getUserName() {
return this.userName;
} public void setUserName(String userName) {
this.userName = userName;
} @Column(name = "password", length = 20)
public String getPassword() {
return this.password;
} public void setPassword(String password) {
this.password = password;
} }
role.java
package com.sxd.entity; import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator; /**
* Role entity. @author MyEclipse Persistence Tools
*/
@Entity
@Table(name = "role", catalog = "shiros")
public class Role implements java.io.Serializable { // Fields private String roleId;
private String roleName;
private Integer roleGrade;
private Set<Authority> authorities = new HashSet<Authority>(0);
private Set<User> users = new HashSet<User>(0); // Constructors /** default constructor */
public Role() {
} /** full constructor */
public Role(String roleName, Integer roleGrade, Set<Authority> authorities,
Set<User> users) {
this.roleName = roleName;
this.roleGrade = roleGrade;
this.authorities = authorities;
this.users = users;
} // Property accessors
@GenericGenerator(name = "generator", strategy = "uuid.hex")
@Id
@GeneratedValue(generator = "generator")
@Column(name = "roleId", unique = true, nullable = false, length = 36)
public String getRoleId() {
return this.roleId;
} public void setRoleId(String roleId) {
this.roleId = roleId;
} @Column(name = "roleName", length = 36)
public String getRoleName() {
return this.roleName;
} public void setRoleName(String roleName) {
this.roleName = roleName;
} @Column(name = "roleGrade")
public Integer getRoleGrade() {
return this.roleGrade;
} public void setRoleGrade(Integer roleGrade) {
this.roleGrade = roleGrade;
} @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinTable(name = "roleauthority", catalog = "shiros", joinColumns = { @JoinColumn(name = "roleId", nullable = false, updatable = false) }, inverseJoinColumns = { @JoinColumn(name = "authorityId", nullable = false, updatable = false) })
public Set<Authority> getAuthorities() {
return this.authorities;
} public void setAuthorities(Set<Authority> authorities) {
this.authorities = authorities;
} @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "role")
public Set<User> getUsers() {
return this.users;
} public void setUsers(Set<User> users) {
this.users = users;
} }
Authority.java
package com.sxd.entity; import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator; /**
* Authority entity. @author MyEclipse Persistence Tools
*/
@Entity
@Table(name = "authority", catalog = "shiros")
public class Authority implements java.io.Serializable { // Fields private String authorityId;
private String authorityName;
private String authorityContent;
private Set<Role> roles = new HashSet<Role>(0); // Constructors /** default constructor */
public Authority() {
} /** full constructor */
public Authority(String authorityName, String authorityContent,
Set<Role> roles) {
this.authorityName = authorityName;
this.authorityContent = authorityContent;
this.roles = roles;
} // Property accessors
@GenericGenerator(name = "generator", strategy = "uuid.hex")
@Id
@GeneratedValue(generator = "generator")
@Column(name = "authorityId", unique = true, nullable = false, length = 36)
public String getAuthorityId() {
return this.authorityId;
} public void setAuthorityId(String authorityId) {
this.authorityId = authorityId;
} @Column(name = "authorityName", length = 20)
public String getAuthorityName() {
return this.authorityName;
} public void setAuthorityName(String authorityName) {
this.authorityName = authorityName;
} @Column(name = "authorityContent", length = 500)
public String getAuthorityContent() {
return this.authorityContent;
} public void setAuthorityContent(String authorityContent) {
this.authorityContent = authorityContent;
} @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "authorities")
public Set<Role> getRoles() {
return this.roles;
} public void setRoles(Set<Role> roles) {
this.roles = roles;
} }
4.接下来,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.sxd.shiro</groupId>
<artifactId>shiro-first</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<version>3.0</version>
</configuration>
</plugin>
</plugins>
</build> <properties>
<shiro.version>1.3.2</shiro.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>4.1.4.RELEASE</spring.version>
<hibernate.version>4.3.8.Final</hibernate.version>
</properties> <dependencies>
<!-- Logging API + implementation: -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.21</version>
<scope>runtime</scope>
</dependency> <!-- Shiro dependencies: -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>${shiro.version}</version>
</dependency> <!-- https://mvnrepository.com/artifact/javax.persistence/persistence-api -->
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0</version>
</dependency>
<!-- 进行加密操作 -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency> <!-- https://mvnrepository.com/artifact/dom4j/dom4j -->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency> <!-- 微信开发工具包 --> <!-- https://mvnrepository.com/artifact/com.github.binarywang/weixin-java-common -->
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-common</artifactId>
<version>2.2.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.github.binarywang/weixin-java-mp -->
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-mp</artifactId>
<version>2.2.0</version>
</dependency> <!-- junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency> <!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.1.4</version>
</dependency> <!-- spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</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-web</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency> <!-- 使用SpringMVC需配置 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- spring cglib 代理 -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
<!-- 关系型数据库整合时需配置 如hibernate jpa等 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency> <!-- hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version> </dependency> <dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>${hibernate.version}</version>
</dependency> <!-- 二级缓存ehcache -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.9.0</version>
</dependency> <!-- log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency> <!-- mysql连接 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.34</version>
</dependency> <!-- c3p0数据源 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5-pre10</version>
</dependency> <!-- json --> <!-- 1号 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.8.1</version>
</dependency>
<!-- 2号 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.8.1</version>
</dependency> <!-- 3号 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.1</version>
<exclusions>
<exclusion>
<artifactId>jackson-core</artifactId>
<groupId>com.fasterxml.jackson.core</groupId>
</exclusion>
<exclusion>
<artifactId>jackson-annotations</artifactId>
<groupId>com.fasterxml.jackson.core</groupId>
</exclusion>
</exclusions>
</dependency> <!-- 4号 -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.7</version>
</dependency>
<!-- 5号 -->
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
<!-- 5号json-lib还需要以下依赖包 -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency> <!-- aop -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.4</version>
</dependency> <!-- servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>3.0-alpha-1</version>
<scope>provided</scope>
</dependency> <dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- guava 集合的交并操作 -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>19.0</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava-collections</artifactId>
<version>r03</version>
</dependency> <!-- 文件上传 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency> </dependencies> </project>
尤其注意,这里着重看一下shiro的架包就是下面三个:版本号自行选择
<!-- Shiro dependencies: -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>${shiro.version}</version>
</dependency>
5.为实体生成对应的Dao/service以及其impl
GenericDao.java
package com.sxd.dao; import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map; import org.hibernate.Criteria;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria; import com.github.pagehelper.PageInfo; public interface GenericDao<T, PK extends Serializable> {
/**
* 查询全部,可以排序
* @param orderBy
* @param isAsc
* @return List<T>
*/
public List<T> list(Criteria criteria); /**
* 查询全部,可以排序
* @param orderBy
* @param isAsc
* @return List<T>
*/
public List<T> list(String orderBy, boolean isAsc); /**
* 离线查询
* @param criteria
* @return List<T>
*/
public List<T> list(DetachedCriteria criteria); /**
* 根据Criteria查询条件,获取总数
* @param criteria
* @return int
* @throws SecurityException
* @throws NoSuchFieldException
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
public int countAll(Criteria criteria); /**
* 获取总数(默认为entityClass) 即查询总条数
* @return int
*/
public int countAll(); /**
* 根据I判断是否存在
* @param id
* @return boolean
*/
public boolean exists(PK id); /**
* 保存实体
* @param t 实体参数
*/
public void save(T t); /**
* 保存或者更新实体
* @param t 实体
*/
public void saveOrUpdate(T t); /**
* 加载实体的通过load方法
* @param id 实体的id
* @return 查询出来的实体
*/
public T load(PK id); /**
* 合并实体
* @param entity
*/
public void merge(T entity); /**
* 查找全部
*/
public List<T> findAll(); /**
* 通过get方法加载实体的
* @param id 实体的id
* @return 查询出来的实体
*/
public T get(PK id); /**
* contains
* @param t 实体
* @return 是否包含
*/
public boolean contains(T t); /**
* delete
* @param t
* 删除实体
*/
public void delete(T t); /**
* 根据ID删除数据
* @param Id 实体id
* @return 是否删除成功
*/
public boolean deleteById(PK Id); /**
* 删除所有
* @param entities 实体的Collection集合
*/
public void deleteAll(Collection<T> entities); /**
* 执行Hql语句 要求 hql中参数顺序与可变参数 中参数顺序相一致
* @param hqlString hql
* @param values 不定参数数组
*/
public void queryHql(String hqlString, Object... values); /**
* 执行Sql语句(不建议用,影响扩展)
* @param sqlString sql
* @param values 不定参数数组
*/
public void querySql(String sqlString, Object... values); /**
* 根据HQL语句查找唯一实体
*
* @param hqlString HQL语句
* @param values 不定参数的Object数组
* @return 查询实体
*/
public T getByHQL(String hqlString, Object... values); /**
* 根据SQL语句查找唯一实体(不建议用,影响扩展)
* @param sqlString SQL语句
* @param values 不定参数的Object数组
* @return 查询实体
*/ /**
* 根据HQL语句,得到对应的list
* @param hqlString HQL语句
* @param values 不定参数的Object数组
* @return 查询多个实体的List集合
*/
public List<T> getListByHQL(String hqlString, Object... values); /**
* 根据SQL语句,得到对应的list(不建议用,影响扩展)
* @param sqlString HQL语句
* @param values 不定参数的Object数组
* @return 查询多个实体的List集合
*/
public List<T> getListBySQL(String sqlString,Class c, Object... values); /**
* refresh 刷新实体,强制与数据库两步 refresh方法应该是数据库的数据更新到本地的person实体中,而不是本地person更新数据到数据库中 也就是执行refresh方法是更新了java代码中变量的数据值
* @param t 实体
*/
public void refresh(T t); /**
* update
* @param t
* 更新的是数据库中的数据
*/
public void update(T t); /**
* 根据HQL得到记录数
* @param hql HQL语句
* @param values 不定参数的Object数组
* @return 记录总数
*/
public Long countByHql(String hql, Object... values); /**
* HQL分页查询
*
* @param hql HQL语句
* @param countHql 查询记录条数的HQL语句
* @param pageNo 下一页
* @param pageSize 一页总条数
* @param values 不定Object数组参数
* @return PageResults的封装类,里面包含了页码的信息以及查询的数据List集合
*/
public PageInfo<T> findPageByHql(String hql, String countHql, int pageNo, int pageSize, Object... values); /**
* 按属性查找对象列表,匹配方式为相等
* @param propertyName
* @param value
* @return List<T>
*/
public List<T> list(String propertyName, Object value); /**
* 根据criterion查询条件获取数据列表
* @param criterion
* @return List<T>
*/
public List<T> list(Criterion criterion); /**
* 按Criteria查询对象列表
* @param criterions
* @return List<T>
*/
public List<T> list(Criterion... criterions); /**
* 按属性查找唯一对象,匹配方式为相等
* @param propertyName
* @param value
* @return T
*/
public T uniqueResult(String propertyName, Object value); /**
* 按Criteria查询唯一对象
* @param criterions
* @return T
*/
public T uniqueResult(Criterion... criterions); /**
* 按Criteria查询唯一对象
* @param criteria
* @return T
*/
public T uniqueResult(Criteria criteria); /**
* 按criteria查询某个Integer类型的字段
* @param criteria
* @return
*/
public Integer uniqueResultInt(Criteria criteria); /**
* 为Criteria添加distinct transformer
* @param criteria
* @return Criteria
*/
public Criteria distinct(Criteria criteria); /**
* 刷新session
*/
public void flush(); /**
* 清空session
*/
public void clear(); /**
* 创建Criteria实例
*/
public Criteria createCriteria(); /**
* 根据Criterion条件创建Criteria
* @param criterions
* @return Criteria
*/
public Criteria createCriteria(Criterion... criterions); /**
* 分页查询Criteria
* @param criteria
* @param pageNo 下页页码
* @param pageSize 页面数据量
* @return List<T>
*/
public List<T> findPage(Criteria criteria, int pageNo, int pageSize); /**
* 分页查询Criteria
* @param criteria
* @param pageNo
* @param pageSize
* @return PageInfo<T>
* @throws SecurityException
* @throws NoSuchFieldException
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
public PageInfo<T> findQuery(Criteria criteria, int pageNo, int pageSize); /**
*
* @param hql
* @param pageNo
* @param pageSize
* @param map
* @return List<T>
*/
public List<T> findQuery(String hql, int pageNo, int pageSize, Map<?, ?> map); }
GenericDaoImpl.java
package com.sxd.dao.impl; import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry; import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.QueryException;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.internal.CriteriaImpl;
import org.hibernate.internal.CriteriaImpl.Subcriteria;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert; import java.lang.reflect.ParameterizedType; import com.github.pagehelper.PageInfo;
import com.sxd.dao.GenericDao; public class GenericDaoImpl<T, PK extends Serializable> implements GenericDao<T, PK> {
/**
* 不建议直接使用
*/
@Autowired
private SessionFactory sessionFactory; public Session getSession() {
// 需要开启事物,才能得到CurrentSession
return sessionFactory.getCurrentSession();
} protected Class<T> entityClass; protected Class getEntityClass() {
if (entityClass == null) {
if(((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments().length > 0) {
entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
}
return entityClass;
} public SessionFactory getSessionFactory() {
return sessionFactory;
} public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
} @Override
public Criteria createCriteria() {
return getSession().createCriteria(getEntityClass());
} @Override
public void save(T t) {
this.getSession().save(t);
} @Override
public void saveOrUpdate(T t) {
Assert.notNull(t);
this.getSession().saveOrUpdate(t);
} @Override
public T load(PK id) {
Assert.notNull(id);
T load = (T) this.getSession().load(getEntityClass(), id);
return load;
} @Override
public T get(PK id) {
T load = (T) this.getSession().get(getEntityClass(), id);
return load;
} @Override
public boolean contains(T t) {
Assert.notNull(t);
return this.getSession().contains(t);
} @Override
public void delete(T t) {
Assert.notNull(t);
this.getSession().delete(t);
} @Override
public boolean deleteById(PK Id) {
Assert.notNull(Id);
T t = get(Id);
if (t == null) return false;
delete(t);
return true;
} @Override
public void deleteAll(Collection<T> entities) {
Assert.notNull(entities);
for (Object entity : entities) {
this.getSession().delete(entity);
}
} @Override
public void queryHql(String hqlString, Object... values) {
Query query = this.getSession().createQuery(hqlString);
if (values != null) {
for (int i = 0; i < values.length; i++) {
query.setParameter(i, values[i]);
}
}
query.executeUpdate();
} /**
* 根据hql 和 map集合中的数据 进行相对应的 insert update delete操作
* @param hqlString
* @param paras
*/
public void queryHql(String hqlString, Map<String, Object> paras) {
Query query = this.getSession().createQuery(hqlString);
if (paras != null) {
for (Entry<String, Object> en : paras.entrySet()) {
query.setParameter(en.getKey(), en.getValue());
}
}
query.executeUpdate();
} @Override
public void querySql(String sqlString, Object... values) {
Query query = this.getSession().createSQLQuery(sqlString);
if (values != null) {
for (int i = 0; i < values.length; i++) {
query.setParameter(i, values[i]);
}
}
query.executeUpdate();
} @Override
public T getByHQL(String hqlString, Object... values) {
Query query = this.getSession().createQuery(hqlString);
if (values != null) {
for (int i = 0; i < values.length; i++) {
query.setParameter(i, values[i]);
}
}
return (T) query.uniqueResult();
} @Override
public List<T> getListByHQL(String hqlString, Object... values) {
Query query = this.getSession().createQuery(hqlString);
if (values != null) {
for (int i = 0; i < values.length; i++) {
query.setParameter(i, values[i]);
}
}
return query.list();
} @Override
public List<T> getListBySQL(String sqlString,Class c, Object... values) {
Query query = this.getSession().createSQLQuery(sqlString);
if (values != null) {
for (int i = 0; i < values.length; i++) {
query.setParameter(i, values[i]);
}
}
query.setResultTransformer(Transformers.aliasToBean(c));
return query.list();
} @Override
public void refresh(T t) {
this.getSession().refresh(t);
} @Override
public void update(T t) {
this.getSession().update(t);
} @Override
public Long countByHql(String hql, Object... values) {
Query query = this.getSession().createQuery(hql);
if (values != null) {
for (int i = 0; i < values.length; i++) {
query.setParameter(i, values[i]);
}
}
return (Long) query.uniqueResult();
} @Override
public PageInfo<T> findPageByHql(String hql, String countHql, int pageNo, int pageSize, Object... values) {
PageInfo<T> retValue = new PageInfo<T>();
Query query = this.getSession().createQuery(hql);
if (values != null) {
for (int i = 0; i < values.length; i++) {
query.setParameter(i, values[i]);
}
}
int currentPage = pageNo > 1 ? pageNo : 1;
retValue.setPages(currentPage);
retValue.setPageSize(pageSize);
if (countHql == null) {
ScrollableResults results = query.scroll();
results.last();
retValue.setTotal(results.getRowNumber() + 1);
} else {
Long count = countByHql(countHql, values);
retValue.setTotal(count.intValue());
}
List<T> itemList = query.setFirstResult((currentPage - 1) * pageSize).setMaxResults(pageSize).list();
if (itemList == null) {
itemList = new ArrayList<T>();
}
retValue.setList(itemList);
return retValue;
} @Override
public void merge(T entity) {
// TODO Auto-generated method stub
getSession().merge(entity);
} @Override
public boolean exists(PK id) {
return null != get(id);
} @Override
public int countAll() {
Criteria criteria = createCriteria();
return Integer.valueOf(criteria.setProjection(Projections.rowCount()).uniqueResult().toString());
} @Override
public int countAll(Criteria criteria) {
criteria.setProjection(null);
return Integer.valueOf(criteria.setProjection(Projections.rowCount()).uniqueResult().toString());
} @Override
public List<T> list(Criteria criteria) {
return criteria.list();
} @Override
public List<T> list(DetachedCriteria criteria) {
return (List<T>) list(criteria.getExecutableCriteria(getSession()));
} @Override
public List<T> list(String orderBy, boolean isAsc) {
Criteria criteria = createCriteria();
if (isAsc) {
criteria.addOrder(Order.asc(orderBy));
} else {
criteria.addOrder(Order.desc(orderBy));
}
return criteria.list();
} @Override
public List<T> list(String propertyName, Object value) {
Criterion criterion = Restrictions.like(propertyName, "%"+ value +"%");
return list(criterion);
} @Override
public List<T> list(Criterion criterion) {
Criteria criteria = createCriteria();
criteria.add(criterion);
return criteria.list();
} @Override
public List<T> list(Criterion... criterions) {
return createCriteria(criterions).list();
} @Override
public T uniqueResult(String propertyName, Object value) {
Criterion criterion = Restrictions.eq(propertyName, value);
return (T) createCriteria(criterion).uniqueResult();
} @Override
public T uniqueResult(Criterion... criterions) {
Criteria criteria = createCriteria(criterions);
return uniqueResult(criteria);
} @Override
public T uniqueResult(Criteria criteria) {
return (T) criteria.uniqueResult();
} @Override
public Integer uniqueResultInt(Criteria criteria) {
return (Integer) criteria.uniqueResult();
} @Override
public Criteria distinct(Criteria criteria) {
criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
return criteria;
} @Override
public void flush() {
getSession().flush();
} @Override
public void clear() {
getSession().clear();
} @Override
public Criteria createCriteria(Criterion... criterions) {
Criteria criteria = createCriteria();
for (Criterion c : criterions) {
criteria.add(c);
}
return criteria;
} @Override
public List<T> findPage(Criteria criteria, int pageNo, int pageSize) {
criteria.setFirstResult((pageNo - 1) * pageSize);
criteria.setMaxResults(pageSize);
return list(criteria);
} @Override
public PageInfo<T> findQuery(Criteria criteria, int pageNo, int pageSize) {
try {
Assert.isTrue(pageNo >= 1, "pageNO should start from 1");
while(criteria instanceof Subcriteria){
criteria = ((Subcriteria)criteria).getParent();
}
//拆分order by子句
while(criteria instanceof Subcriteria){
criteria = ((Subcriteria)criteria).getParent();
}
Field field = CriteriaImpl.class.getDeclaredField("orderEntries");
field.setAccessible(true);
List<?> orderEntrys = (List<?>) field.get(criteria);
field.set(criteria, new ArrayList());
//统计总数
long totalCount = countAll(criteria);
criteria.setProjection(null);
//统计完了再把order by子句加上 这样保证了sql语句不会出错
field.set(criteria, orderEntrys);
List<T> list = findPage(criteria, pageNo, pageSize);
if (totalCount < 1) {
return new PageInfo<T>();
}
PageInfo<T> page = new PageInfo<T>();
page.setPageNum(pageNo);
page.setTotal(totalCount);
page.setPages((int) (totalCount % pageSize == 0 ? totalCount / pageSize : totalCount / pageSize + 1));
page.setPageSize(pageSize);
page.setList(list);
return page;
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
throw new QueryException("查询出错!");
} } @Override
public List<T> findQuery(String hql, int pageNo, int pageSize, Map<?, ?> map) {
// TODO Auto-generated method stub
if(null == hql) return null;
Query query = getSession().createQuery(hql);
for (Entry<?, ?> en : map.entrySet()) {
query.setParameter(en.getKey().toString(), en.getValue());
}
if(pageNo > 0) query.setFirstResult(pageNo);
if(pageSize > 0) query.setFirstResult(pageSize);
return query.list();
} @Override
public List<T> findAll() {
// TODO Auto-generated method stub
return createCriteria().list();
}
}
GenericService.java
package com.sxd.service; import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map; import org.hibernate.Criteria;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria; import com.github.pagehelper.PageInfo; public interface GenericService<T, PK extends Serializable> {
/**
* 查询全部,可以排序
* @param orderBy
* @param isAsc
* @return List<T>
*/
public List<T> list(Criteria criteria); /**
* 查询全部,可以排序
* @param orderBy
* @param isAsc
* @return List<T>
*/
public List<T> list(String orderBy, boolean isAsc); /**
* 离线查询
* @param criteria
* @return List<T>
*/
public List<T> list(DetachedCriteria criteria); /**
* 根据Criteria查询条件,获取总数
* @param criteria
* @return int
* @throws SecurityException
* @throws NoSuchFieldException
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
public int countAll(Criteria criteria); /**
* 获取总数(默认为entityClass) 即查询总条数
* @return int
*/
public int countAll(); /**
* 根据I判断是否存在
* @param id
* @return boolean
*/
public boolean exists(PK id); /**
* 保存实体
* @param t 实体参数
*/
public void save(T t); /**
* 保存或者更新实体
* @param t 实体
*/
public void saveOrUpdate(T t); /**
* 加载实体的通过load方法
* @param id 实体的id
* @return 查询出来的实体
*/
public T load(PK id); /**
* 合并实体
* @param entity
*/
public void merge(T entity); /**
* 查找全部
*/
public List<T> findAll(); /**
* 通过get方法加载实体的
* @param id 实体的id
* @return 查询出来的实体
*/
public T get(PK id); /**
* contains
* @param t 实体
* @return 是否包含
*/
public boolean contains(T t); /**
* delete
* @param t
* 删除实体
*/
public void delete(T t); /**
* 根据ID删除数据
* @param Id 实体id
* @return 是否删除成功
*/
public boolean deleteById(PK Id); /**
* 删除所有
* @param entities 实体的Collection集合
*/
public void deleteAll(Collection<T> entities); /**
* 执行Hql语句 要求 hql中参数顺序与可变参数 中参数顺序相一致
* @param hqlString hql
* @param values 不定参数数组
*/
public void queryHql(String hqlString, Object... values); /**
* 执行Sql语句(不建议用,影响扩展)
* @param sqlString sql
* @param values 不定参数数组
*/
public void querySql(String sqlString, Object... values); /**
* 根据HQL语句查找唯一实体
*
* @param hqlString HQL语句
* @param values 不定参数的Object数组
* @return 查询实体
*/
public T getByHQL(String hqlString, Object... values); /**
* 根据SQL语句查找唯一实体(不建议用,影响扩展)
* @param sqlString SQL语句
* @param values 不定参数的Object数组
* @return 查询实体
*/ /**
* 根据HQL语句,得到对应的list
* @param hqlString HQL语句
* @param values 不定参数的Object数组
* @return 查询多个实体的List集合
*/
public List<T> getListByHQL(String hqlString, Object... values); /**
* 根据SQL语句,得到对应的list(不建议用,影响扩展)
* @param sqlString HQL语句
* @param values 不定参数的Object数组
* @return 查询多个实体的List集合
*/
public List<T> getListBySQL(String sqlString,Class c, Object... values); /**
* refresh 刷新实体,强制与数据库两步 refresh方法应该是数据库的数据更新到本地的person实体中,而不是本地person更新数据到数据库中 也就是执行refresh方法是更新了java代码中变量的数据值
* @param t 实体
*/
public void refresh(T t); /**
* update
* @param t
* 更新的是数据库中的数据
*/
public void update(T t); /**
* 根据HQL得到记录数
* @param hql HQL语句
* @param values 不定参数的Object数组
* @return 记录总数
*/
public Long countByHql(String hql, Object... values); /**
* HQL分页查询
*
* @param hql HQL语句
* @param countHql 查询记录条数的HQL语句
* @param pageNo 下一页
* @param pageSize 一页总条数
* @param values 不定Object数组参数
* @return PageResults的封装类,里面包含了页码的信息以及查询的数据List集合
*/
public PageInfo<T> findPageByHql(String hql, String countHql, int pageNo, int pageSize, Object... values); /**
* 按属性查找对象列表,匹配方式为相等
* @param propertyName
* @param value
* @return List<T>
*/
public List<T> list(String propertyName, Object value); /**
* 根据criterion查询条件获取数据列表
* @param criterion
* @return List<T>
*/
public List<T> list(Criterion criterion); /**
* 按Criteria查询对象列表
* @param criterions
* @return List<T>
*/
public List<T> list(Criterion... criterions); /**
* 按属性查找唯一对象,匹配方式为相等
* @param propertyName
* @param value
* @return T
*/
public T uniqueResult(String propertyName, Object value); /**
* 按Criteria查询唯一对象
* @param criterions
* @return T
*/
public T uniqueResult(Criterion... criterions); /**
* 按Criteria查询唯一对象
* @param criteria
* @return T
*/
public T uniqueResult(Criteria criteria);
/**
* 按照criteria返回类型为Integer类型的某个字段的值
* @param criteria
* @return
*/
public Integer uniqueResultInt(Criteria criteria); /**
* 为Criteria添加distinct transformer
* @param criteria
* @return Criteria
*/
public Criteria distinct(Criteria criteria); /**
* 刷新session
*/
public void flush(); /**
* 清空session
*/
public void clear(); /**
* 创建Criteria实例
*/
public Criteria createCriteria(); /**
* 根据Criterion条件创建Criteria
* @param criterions
* @return Criteria
*/
public Criteria createCriteria(Criterion... criterions); /**
* 分页查询Criteria
* @param criteria
* @param pageNo 下页页码
* @param pageSize 页面数据量
* @return List<T>
*/
public List<T> findPage(Criteria criteria, int pageNo, int pageSize); /**
* 分页查询Criteria
* @param criteria
* @param pageNo
* @param pageSize
* @return PageInfo<T>
* @throws SecurityException
* @throws NoSuchFieldException
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
public PageInfo<T> findQuery(Criteria criteria, int pageNo, int pageSize); /**
*
* @param hql
* @param pageNo
* @param pageSize
* @param map
* @return List<T>
*/
public List<T> findQuery(String hql, int pageNo, int pageSize, Map<?, ?> map); }
GenericServiceImpl.java
package com.sxd.service.impl; import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map; import org.hibernate.Criteria;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import com.github.pagehelper.PageInfo;
import com.sxd.dao.impl.GenericDaoImpl;
import com.sxd.service.GenericService; @Transactional
public class GenericServiceImpl<T, PK extends Serializable> implements GenericService<T, PK> { private GenericDaoImpl<T, PK> dao;
/**
* 设值注入Dao
* @param dao
*/
@Autowired
public void setDao(GenericDaoImpl<T, PK> dao) {
this.dao = dao;
} @Override
@Transactional(propagation = Propagation.REQUIRED)
public List<T> list(Criteria criteria) {
// TODO Auto-generated method stub
return dao.list(criteria);
} @Override
public List<T> list(String orderBy, boolean isAsc) {
// TODO Auto-generated method stub
return dao.list(orderBy, isAsc);
} @Override
public List<T> list(DetachedCriteria criteria) {
// TODO Auto-generated method stub
return dao.list(criteria);
} @Override
public int countAll(Criteria criteria) {
// TODO Auto-generated method stub
return dao.countAll(criteria);
} @Override
public int countAll() {
// TODO Auto-generated method stub
return dao.countAll();
} @Override
public boolean exists(PK id) {
// TODO Auto-generated method stub
return dao.exists(id);
} @Override
@Transactional(propagation = Propagation.REQUIRED)
public void save(T t) {
// TODO Auto-generated method stub
dao.save(t);
} @Override
@Transactional(propagation = Propagation.REQUIRED)
public void saveOrUpdate(T t) {
// TODO Auto-generated method stub
dao.saveOrUpdate(t);
} @Override
@Transactional(propagation = Propagation.REQUIRED)
public T load(PK id) {
// TODO Auto-generated method stub
return dao.load(id);
} @Override
@Transactional(propagation = Propagation.REQUIRED)
public void merge(T entity) {
// TODO Auto-generated method stub
dao.merge(entity);
} @Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
public List<T> findAll() {
// TODO Auto-generated method stub
return dao.findAll();
} @Override
@Transactional(propagation = Propagation.REQUIRED)
public T get(PK id) {
// TODO Auto-generated method stub
return dao.get(id);
} @Override
public boolean contains(T t) {
// TODO Auto-generated method stub
return dao.contains(t);
} @Override
public void delete(T t) {
// TODO Auto-generated method stub
dao.delete(t);
} @Override
@Transactional(propagation = Propagation.REQUIRED)
public boolean deleteById(PK Id) {
// TODO Auto-generated method stub
return dao.deleteById(Id);
} @Override
@Transactional(propagation = Propagation.REQUIRED)
public void deleteAll(Collection<T> entities) {
// TODO Auto-generated method stub
dao.deleteAll(entities);
} @Override
public void queryHql(String hqlString, Object... values) {
// TODO Auto-generated method stub
dao.queryHql(hqlString, values);
} @Override
public void querySql(String sqlString, Object... values) {
// TODO Auto-generated method stub
dao.querySql(sqlString, values);
} @Override
public T getByHQL(String hqlString, Object... values) {
// TODO Auto-generated method stub
return dao.getByHQL(hqlString, values);
} @Override
public List<T> getListByHQL(String hqlString, Object... values) {
// TODO Auto-generated method stub
return dao.getListByHQL(hqlString, values);
} @Override
public List<T> getListBySQL(String sqlString,Class c, Object... values) {
// TODO Auto-generated method stub
return dao.getListBySQL(sqlString, c, values);
} @Override
public void refresh(T t) {
// TODO Auto-generated method stub
dao.refresh(t);
} @Override
@Transactional(propagation = Propagation.REQUIRED)
public void update(T t) {
// TODO Auto-generated method stub
dao.update(t);
} @Override
public Long countByHql(String hql, Object... values) {
// TODO Auto-generated method stub
return dao.countByHql(hql, values);
} @Override
public PageInfo<T> findPageByHql(String hql, String countHql, int pageNo,
int pageSize, Object... values) {
// TODO Auto-generated method stub
return dao.findPageByHql(hql, countHql, pageNo, pageSize, values);
} @Override
public List<T> list(String propertyName, Object value) {
// TODO Auto-generated method stub
return dao.list(propertyName, value);
} @Override
public List<T> list(Criterion criterion) {
// TODO Auto-generated method stub
return dao.list(criterion);
} @Override
public List<T> list(Criterion... criterions) {
// TODO Auto-generated method stub
return dao.list(criterions);
} @Override
public T uniqueResult(String propertyName, Object value) {
// TODO Auto-generated method stub
return dao.uniqueResult(propertyName, value);
} @Override
public T uniqueResult(Criterion... criterions) {
// TODO Auto-generated method stub
return dao.uniqueResult(criterions);
} @Override
@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
public T uniqueResult(Criteria criteria) {
// TODO Auto-generated method stub
return dao.uniqueResult(criteria);
} @Override
@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
public Integer uniqueResultInt(Criteria criteria){
return dao.uniqueResultInt(criteria);
} @Override
public Criteria distinct(Criteria criteria) {
// TODO Auto-generated method stub
return dao.distinct(criteria);
} @Override
public void flush() {
// TODO Auto-generated method stub
dao.flush();
} @Override
public void clear() {
// TODO Auto-generated method stub
dao.clear();
} @Override
public Criteria createCriteria() {
// TODO Auto-generated method stub
return dao.createCriteria();
} @Override
public Criteria createCriteria(Criterion... criterions) {
// TODO Auto-generated method stub
return dao.createCriteria(criterions);
} @Override
public List<T> findPage(Criteria criteria, int pageNo, int pageSize) {
// TODO Auto-generated method stub
return dao.findPage(criteria, pageNo, pageSize);
} @Override
public PageInfo<T> findQuery(Criteria criteria, int pageNo, int pageSize) {
// TODO Auto-generated method stub
return dao.findQuery(criteria, pageNo, pageSize);
} @Override
public List<T> findQuery(String hql, int pageNo, int pageSize, Map<?, ?> map) {
// TODO Auto-generated method stub
return dao.findQuery(hql, pageNo, pageSize, map);
} }
使用工具类生成实体的Dao/Service
CreateJava.java
package com.sxd.utils; import java.io.File;
import java.io.FileWriter;
import java.io.IOException; import org.junit.Test; public class CreateJava { @Test
public void justCreateJava() throws IOException{
File file = new File("F:/workspace2/shiro-first/src/main/java/com/sxd/entity");
File []list = file.listFiles();
for (File file2 : list) {
String fileName = file2.getName().substring(0,file2.getName().lastIndexOf("."));
createDao(fileName);
createDaoImpl(fileName);
createService(fileName);
createServiceImpl(fileName);
}
}
/**
* 创建Dao层
* @param fileName
* @throws IOException
*/
public void createDao(String fileName) throws IOException{
//拼接 DaoImpl内容
String content = "package com.sxd.dao;\r\n"
+ "\r\n"
+ "import com.sxd.entity."+fileName+";\r\n"
+ "public interface "+fileName+"Dao extends GenericDao<"+fileName+", String> {\r\n"
+ "\r\n"
+ "}"; //指定将Dao文件生成到对应的指定位置
FileWriter writer = new FileWriter(new File("F:/workspace2/shiro-first/src/main/java/com/sxd/dao/"+fileName+"Dao.java"));
writer.write(content);
writer.close();
} /**
* 创建DaoImpl层
*/
public void createDaoImpl(String fileName) throws IOException{
//拼接 DaoImpl内容
String content = "package com.sxd.dao.impl;\r\n"
+ "\r\n"
+ "import org.springframework.stereotype.Repository;\r\n"
+ "import com.sxd.dao."+fileName+"Dao;\r\n"
+ "import com.sxd.entity."+fileName+";\r\n"
+ "@Repository \r\n"
+ "public class "+fileName+"DaoImpl extends GenericDaoImpl<"+fileName+", String> implements "+fileName+"Dao {\r\n"
+ "\r\n"
+ "}"; //指定将DaoImpl文件生成到对应的指定位置
FileWriter writer = new FileWriter(new File("F:/workspace2/shiro-first/src/main/java/com/sxd/dao/impl/"+fileName+"DaoImpl.java"));
writer.write(content);
writer.close();
} /**
* 创建 Service层
* @param fileName
* @throws IOException
*/
public void createService(String fileName) throws IOException{
//拼接Service内容
String content = "package com.sxd.service;\r\n"
+ "import com.sxd.entity."+fileName+";\r\n"
+ "public interface "+fileName+"Service extends GenericService<"+fileName+", String> {\r\n"
+ "\r\n"
+ "}"; FileWriter writer = new FileWriter(new File("F:/workspace2/shiro-first/src/main/java/com/sxd/service/"+fileName+"Service.java"));
writer.write(content);
writer.close();
} /**
* 创建ServiceImpl
* @throws IOException
*/
public void createServiceImpl(String fileName) throws IOException{
//拼接Service内容
String content = "package com.sxd.service.impl;\r\n"
+ "import org.springframework.beans.factory.annotation.Autowired;\r\n"
+ "import org.springframework.stereotype.Service;\r\n"
+ "import com.sxd.dao."+fileName+"Dao;\r\n"
+ "import com.sxd.entity."+fileName+";\r\n"
+ "import com.sxd.service."+fileName+"Service;\r\n"
+ "@Service \r\n"
+ "public class "+fileName+"ServiceImpl extends GenericServiceImpl<"+fileName+", String> implements "+fileName+"Service {\r\n"
+ "\r\n"
+ "@Autowired\r\n"
+ "private "+fileName+"Dao dao;\r\n"
+ "}";
FileWriter writer = new FileWriter(new File("F:/workspace2/shiro-first/src/main/java/com/sxd/service/impl/"+fileName+"ServiceImpl.java"));
writer.write(content);
writer.close();
} }
6.配置spring+hibernate+shiro+springMVC的配置文件
config.properties
#application configs #jdbc c3p0 config
jdbc.driver = com.mysql.jdbc.Driver
jdbc.url = jdbc\:mysql\://localhost\:3306/shiros?useUnicode\=true&characterEncoding\=utf-8
jdbc.username = root
jdbc.password = root #hibernate config
hibernate.dialect = org.hibernate.dialect.MySQLDialect
hibernate.show_sql = true
hibernate.format_sql = false
hibernate.hbm2ddl.auto = update
hibernate.cache.use_second_level_cache = true
hibernate.cache.use_query_cache = true
hibernate.cache.region.factory_class = org.hibernate.cache.ehcache.EhCacheRegionFactory
hibernate.cache.provider_configuration_file_resource_path =ehcache.xml
ehcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
<diskStore path="D:/ehcache" />
<!-- DefaultCache setting. -->
<defaultCache
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
maxElementsOnDisk="1000000"
overflowToDisk="true"
memoryStoreEvictionPolicy="LRU"> </defaultCache> <!-- Special objects setting. --> <cache
name="org.andy.work.entity.AcctUser"
maxElementsInMemory="2"
memoryStoreEvictionPolicy="LRU"
eternal="true"
diskPersistent="false"
overflowToDisk="false"
maxElementsOnDisk="1000000" /> </ehcache>
log4j.properties
### set log levels ###
log4j.rootLogger = INFO , C , D , E ### console ###
log4j.appender.C = org.apache.log4j.ConsoleAppender
log4j.appender.C.Target = System.out
log4j.appender.C.layout = org.apache.log4j.PatternLayout
log4j.appender.C.layout.ConversionPattern = [shiro-first][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n ### log file ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = ../logs/springmvc_hibernate_demo.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = INFO
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = [shiro-first][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n ### exception ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File = ../logs/biologyInfo_error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern =[shiro-first][%p] [%-d{yyyy-MM-dd HH\:mm\:ss}] %C.%M(%L) | %m%n
spring-hibernate.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:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd"> <!-- 以下为SpringMVC配置 -->
<mvc:annotation-driven>
<!-- 返回json数据,@response使用 -->
<mvc:message-converters register-defaults="true">
<bean
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property> </bean>
</mvc:message-converters>
</mvc:annotation-driven> <!-- 自动扫描@Controller注入为bean -->
<context:property-placeholder location="classpath:config.properties"/>
<!-- 自动扫描@Controller注入为bean -->
<context:component-scan base-package="com.agen" /> <!-- 标明注解事务 -->
<tx:annotation-driven transaction-manager="transactionManager" /> <!-- 配置数据源 c3p0 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="${jdbc.driver}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" /> <!-- 请求超时时间 -->
<property name="checkoutTimeout" value="30000" />
<!-- 每60秒检查所有连接池中的空闲连接。默认值: 0,不检查 -->
<property name="idleConnectionTestPeriod" value="30" />
<!-- 连接数据库连接池最大空闲时间 -->
<property name="maxIdleTime" value="30" />
<!-- 连接池初始化连接数 -->
<property name="initialPoolSize" value="5" />
<property name="minPoolSize" value="5" />
<property name="maxPoolSize" value="20" />
<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。默认值: 3 -->
<property name="acquireIncrement" value="5" />
</bean> <!-- 配置hibernate的SessionFactory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<!-- 注入数据源 相关信息看源码 -->
<property name="dataSource" ref="dataSource" />
<!-- hibernate配置信息 -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop> <!-- 开启二级缓存 ehcache -->
<prop key="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</prop>
<prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
<prop key="hibernate.cache.region.factory_class">${hibernate.cache.region.factory_class}</prop>
<prop key="hibernate.cache.provider_configuration_file_resource_path">${hibernate.cache.provider_configuration_file_resource_path}
</prop>
</props>
</property>
<!-- 扫描hibernate注解配置的entity -->
<property name="packagesToScan" value="com.agen.entity" />
</bean> <!-- 配置事务管理器 -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean> <!-- 自定义Realm
<bean id="myRealm" class="com.sxd.utils.MyRealm">
<property name="sessionFactory" ref="sessionFactory" />
</bean>--> <!-- 安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="myRealm"/>
</bean> <!-- Shiro过滤器 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- Shiro的核心安全接口,这个属性是必须的 -->
<property name="securityManager" ref="securityManager"/>
<!-- 身份认证失败,则跳转到登录页面的配置 -->
<property name="loginUrl" value="/index.jsp"/>
<!-- 权限认证失败,则跳转到指定页面 -->
<property name="unauthorizedUrl" value="/error.jsp"/>
<!-- Shiro连接约束配置,即过滤链的定义 -->
<property name="filterChainDefinitions" ref="filterChainDefinitions" />
</bean>
<bean name="filterChainDefinitions" class="java.lang.String">
<constructor-arg>
<value>
/=anon
/index.jsp=anon
/login/login1.htmls=anon
/login/register.htmls=anon
/js/** = anon
/bootstrap/** = anon
/css/** = anon
/images/** = anon
/layer/** = anon
/lib/** = anon
/skin/** = anon
/temp/** = anon
/upload/** = anon
/**=authc
</value>
</constructor-arg>
</bean> <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/> <!-- 开启Shiro注解 -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor">
<property name="proxyTargetClass" value="true"/>
</bean>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean> <!-- 自定义异常处理-->
<bean id="exceptionResolver" class="com.agen.util.MyExceptionResolver"></bean> </beans>
着重注意shiro的相关配置:
<!-- 自定义Realm
<bean id="myRealm" class="com.sxd.utils.MyRealm">
<property name="sessionFactory" ref="sessionFactory" />
</bean>--> <!-- 安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="myRealm"/>
</bean> <!-- Shiro过滤器 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- Shiro的核心安全接口,这个属性是必须的 -->
<property name="securityManager" ref="securityManager"/>
<!-- 身份认证失败,则跳转到登录页面的配置 -->
<property name="loginUrl" value="/index.jsp"/>
<!-- 权限认证失败,则跳转到指定页面 -->
<property name="unauthorizedUrl" value="/error.jsp"/>
<!-- Shiro连接约束配置,即过滤链的定义 -->
<property name="filterChainDefinitions" ref="filterChainDefinitions" />
</bean>
<bean name="filterChainDefinitions" class="java.lang.String">
<constructor-arg>
<value>
/=anon
/index.jsp=anon
/login/login1.htmls=anon
/login/register.htmls=anon
/js/** = anon
/bootstrap/** = anon
/css/** = anon
/images/** = anon
/layer/** = anon
/lib/** = anon
/skin/** = anon
/temp/** = anon
/upload/** = anon
/**=authc
</value>
</constructor-arg>
</bean> <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/> <!-- 开启Shiro注解 -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor">
<property name="proxyTargetClass" value="true"/>
</bean>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean> <!-- 自定义异常处理-->
<bean id="exceptionResolver" class="com.agen.util.MyExceptionResolver"></bean>
其中:1>shiro需要开启注解
2>shiro自定义异常处理【这个自定义的异常处理类需要自己写】
3>/=anon表示跟路径【http://localhost:8080/shiro-first/】是不拦截的
4>/index.jsp=anon表示【http://localhost:8080/shiro-first/index.jsp】是不拦截的
5>/js/** = anon表示【http://localhost:8080/shiro-first/js/jquery.js】这种类型的资源请求都是不拦截的
6>/**=authc 表示除了上面定义的不拦截之外的其他请求地址均需要被拦截到,被拦截到是需要验证 当前访问这个地址的 用户是否已经通过验证,也就是是否登录过,如果没有,会根据上面配置的<property name="loginUrl" value="/index.jsp"/>跳转指定页面,这里就是指定到登录页面。
7><property name="unauthorizedUrl" value="/error.jsp"/>如果没有整合使用springMVC跳转页面,那么这个就是有用的,现在页面的跳转交给springMVC来控制,这个权限认证不通过的配置就不起作用了,而是springMVC根据抛出异常,然后根据自定义的异常处理类,跳转到指定的页面了。
8>
<!-- 自定义Realm
<bean id="myRealm" class="com.sxd.utils.MyRealm">
<property name="sessionFactory" ref="sessionFactory" />
</bean>-->
自定义的这个Realm相当于咱们自己写的Filter,其中是实现了shiro提供的接口,进行了相对应的处理,拿到了本用户以及本用户所对应的权限,交给shiro自行比较,完成验证。
9>/login/login.htmls=anon需要加后缀是因为web.xml中的相关配置未拦截到相关的请求页面,仅注意就好
spring-mvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd"> <!-- 对模型视图名称的解析,即在模型视图名称添加前后缀 -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/views" />
<property name="suffix" value=".jsp" />
</bean> <!-- 实现文件上传,这样一旦某个Request是一个MultipartRequest,它就会首先被MultipartResolver处理,然后再转发相应的Controller -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设置上传文件的最大尺寸为1GB -->
<!-- <property name="maxUploadSize">
<value>1073741824</value>
</property> -->
</bean> </beans>
7.配置web项目的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_2_5.xsd"
id="WebApp_ID" version="2.5">
<!-- web容器是web项目的大脑 -->
<!-- 在web.xml中,执行顺序是:1.先执行listener 2。再执行filter 3.最后执行servlet 这就是执行顺序
就像spring-hibernate.xml文件是在执行Listener的时候加载的,那注意这几个配置文件在web.xml中的加载顺序,因为资源文件是在配置文件【xml文件】中加载的,肯定是先加载的资源文件【properties文件】,才能在配置文件中调用资源文件中的变量的值使用 -->
<display-name>shiro-first</display-name>
<!-- web容器,首先需要引入spring,让spring管理各个框架,并将其注入为bean -->
<!-- 这个相当于定一个 变量在web.xml中,在下面的listener org.springframework.web.context.ContextLoaderListener中,加载这个spring-hibernate.xml文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-hibernate.xml</param-value>
</context-param> <!-- 编码过滤器 配置控制层的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>
</filter-mapping> <!-- 监听servletContext,启动contextConfigLocation中的spring配置信息 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> <!-- 防止spring内存溢出监听器 可用可不用-->
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener> <!-- shiro
<listener>
<listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
</listener>
-->
<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> <!-- 添加springmvc支持 -->
<!-- 类似与servlet 需要在web.xml中都需要配置一样,spring的思想是让这些servlet【controller也是servlet】继承了一个基础的servlet,那就只需在web.xml中配置一个servlet即可。 -->
<!-- 这个servlet和下面的servlet-mapping相配合使用,注明了所有的以.htmls结尾的请求都被截取到,去到servlet中去找相对应的方法 进行处理 -->
<servlet>
<description>spring mvc servlet</description>
<servlet-name>rest</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<!-- 此处配置的是SpringMVC的配置文件 -->
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 配置了springmvc拦截的url为以.htmls结尾的请求 -->
<servlet-mapping>
<servlet-name>rest</servlet-name>
<url-pattern>*.htmls</url-pattern>
</servlet-mapping> <!-- 配置session超时时间,单位分钟 -->
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<!-- 欢迎界面 默认的项目访问界面 -->
<welcome-file-list>
<welcome-file>/index.jsp</welcome-file>
</welcome-file-list>
</web-app>
8.相关配置完成,然后,先把登录页面做出来
index.jsp【登录页面/主页面】
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<title>LOGIN VIEW</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<body class="hold-transition skin-blue sidebar-mini">
<h2 style="color:red " class="msg"></h2>
<form method="post">
userName:<input type="text" name="username"/><br/>
password:<input type="password" name="password"/><br/>
<button type="button">login</button>
</form>
</body> <script type="text/javascript" src="js/jquery.js"></script>
<!-- 使用ajax提交而不是用submit,避免了 重定向 302的状态码 -->
<script type="text/javascript">
$(document).ready(function(){
$("button").click(function(){ var username = $("input[name='username']").val();
var password = $("input[name='password']").val();
//提交给后台
$.ajax({url:"login/login.htmls",
dataType:'json',
type:"post",
data:{username:username,password:password},
traditional:true,
success:function(data){
if(data == "success"){
location.href = "login/success.htmls";
}else{
$(".msg").text(data);
}
}
});
}); });
</script>
</html>
success.jsp【成功页面】
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Admin 主页</title>
<!-- Tell the browser to be responsive to screen width -->
<meta
content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"
name="viewport"> <body>
成功
<button type="button" class="123" onclick="logout()">退出</button>
</body> <script type="text/javascript">
function logout(){
location.href = "../login/logout.htmls";
}
</script>
</html>
noAuth.jsp【没有权限页面】
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>没有权限页面</title>
<!-- Tell the browser to be responsive to screen width -->
<meta
content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"
name="viewport"> <body class="hold-transition skin-blue sidebar-mini">
没有权限
</body> </html>
9.springMVC的Controller,控制页面跳转
LoginController.java
package com.sxd.controller; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession; import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresGuest;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.authz.annotation.RequiresUser;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; @Controller
@RequestMapping("login")
public class LoginController { @RequestMapping("login")
@ResponseBody
public String login(String username,String password,HttpSession session){ Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
String errorMsg = null;
try {
subject.login(token);
} catch (UnknownAccountException e) {
errorMsg = "用户名错误";
}catch (IncorrectCredentialsException e) {
errorMsg = "用户密码错误";
}catch (AuthenticationException e) {
errorMsg = "其它异常:"+e.getMessage();
} if(errorMsg != null){
System.out.println(errorMsg);
return errorMsg;
}
return "success";
} @RequestMapping("success")
public String success(){
return "/welcome/success";
} @RequestMapping("/logout")
public String logout(HttpServletRequest request) {
request.getSession().invalidate();
return "../../../index";
} /**
* 当前登录用户 才能进入
* @param request
* @return
*/
@RequestMapping("/user")
@RequiresUser()
public String admin(HttpServletRequest request) {
return "/welcome/success";
} @RequestMapping("/admin1")
@RequiresRoles(value="管理员1")
public String student1(HttpServletRequest request) {
return "/welcome/success";
} /**
* 没有用户/角色/权限 规定
* @param request
* @return
*/
@RequestMapping("/admin")
public String teacher1(HttpServletRequest request) {
return "/welcome/success";
}
/**
* 角色为 这种角色的 才能进入
* @param request
* @return
*/
@RequestMapping("/admin2")
@RequiresRoles(value="管理员2")
public String student2(HttpServletRequest request) {
return "/welcome/success";
}
/**
* 仅满足这种权限的 可以进入
* @param request
* @return
*/
@RequestMapping("/admin3")
@RequiresPermissions("疾病:增加")
public String teacher2(HttpServletRequest request) {
return "/welcome/success";
}
/**
* 两种权限其中的一种满足 即满足
* @param request
* @return
*/
@RequestMapping("/admin4")
@RequiresPermissions(value={"产品:增加","产品:修改"},logical=Logical.OR)
public String student3(HttpServletRequest request) {
return "/welcome/success";
} /**
* 两种权限都满足 才满足
* @param request
* @return
*/
@RequestMapping("/admin5")
@RequiresPermissions(value={"产品:增加","产品:修改"},logical=Logical.AND)
public String teacher3(HttpServletRequest request) {
return "/welcome/success";
}
@RequestMapping("/admin6")
@RequiresPermissions(value="疾病:增加")
public String student4(HttpServletRequest request) {
return "/welcome/success";
} }
其中 使用注解将权限/角色/用户 具体到某一个具体的方法上
10.自定义的Realm和自定义的异常控制处理类
MyRealm.java
package com.sxd.utils; import java.util.HashSet;
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 org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import com.sxd.entity.Authority;
import com.sxd.entity.Role;
import com.sxd.entity.User;
import com.sxd.service.UserService; @Component(value="myRealm")
public class MyRealm extends AuthorizingRealm { @Resource
private UserService userService;
@Autowired
private SessionFactory sessionFactory; public Session getSession() {
// 需要开启事物,才能得到CurrentSession
return sessionFactory.openSession();
} /**
* 用来为当前登陆成功的用户授予权限和角色(已经登陆成功了)
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String username = (String) principals.getPrimaryPrincipal(); //获取用户名
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
//拼接criteria查询条件
Criteria criteria = getSession().createCriteria(User.class);
//根据用户名查询
criteria.add(Restrictions.eq("userName", username));
User user = userService.uniqueResult(criteria);
if(user != null){
//获取到用户的角色,根据角色,封装数据为Set<String>,将可以唯一确定本条数据的信息封装起来,供shiro对比使用
Role role= user.getRole();
Set<String> roleSet = new HashSet<String>();
roleSet.add(role.getRoleName());
authorizationInfo.setRoles(roleSet); //同理,根据用户角色所拥有的权限,封装数据,将唯一确定本条权限信息的String封装为set,供shiro使用
Set<Authority> authoritySet = role.getAuthorities();
Set<String> auSet = new HashSet<String>();
for (Authority authority : authoritySet) {
auSet.add(authority.getAuthorityName());
}
authorizationInfo.setStringPermissions(auSet);
return authorizationInfo;
}else{
return null;
} } /**
* 用来验证当前登录的用户,获取认证信息 (对比是否可以成功登录)
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String username = (String) token.getPrincipal();//获取用户名
Criteria criteria = getSession().createCriteria(User.class);
criteria.add(Restrictions.eq("userName", username));
User user = userService.uniqueResult(criteria);
if(user != null){
AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(user.getUserName(), user.getPassword(), this.getName());
return authcInfo;
}else{
return null;
}
} }
MyExceptionResolver.java
package com.sxd.utils; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView; /**
* 自定义 --异常处理类
* @author Administrator
*
*/
public class MyExceptionResolver implements HandlerExceptionResolver { @Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) {
System.out.println("==============异常开始=============");
//如果是shiro无权操作,因为shiro 在操作auno等一部分不进行转发至无权限url
if(ex instanceof UnauthorizedException){
ModelAndView mv = new ModelAndView("/error/noAuth");//指定跳转到没有权限的页面
return mv;
}
ex.printStackTrace();
System.out.println("==============异常结束=============");
ModelAndView mv = new ModelAndView("error");
mv.addObject("exception", ex.toString().replaceAll("\n", "<br/>"));
return mv;
} }
11.项目搭建完成,启动tomcat
访问地址:http://localhost:8080/shiro-first/
用数据库中的某个用户登录:张三 123456
使用张三登录成功之后,张三的role是管理员1,管理员1对应的权限有疾病的增删改查,数据库中有
然后,此时张三登陆成功,
直接在地址栏修改地址为:http://localhost:8080/shiro-first/login/admin1.htmls
而更改地址为:http://localhost:8080/shiro-first/login/admin2.htmls
同理 测试其他的地址 即可!!!!!
【shiro】2.spring整合shiro,注解控制shiro用户/角色/权限And/OR,没有权限跳转到固定页面的更多相关文章
- shiro和Spring整合使用注解时没有执行realm的doGetAuthorizationInfo回调方法的解决(XML配置)
在使用Shiro框架进行项目整合时,使用注解在使用Shiro框架进行项目整合时,使用注解在使用Shiro框架进行项目整合时,使用注解@RequiresPermissions为方法提供是需要的权限,但是 ...
- Shiro与Spring整合
Shiro引入Spring 添加jar包/maven配置 <!-- shiro支持 --> <dependency> <groupId>org.apache.shi ...
- 安全框架 - Shiro与springMVC整合的注解以及JSP标签
Shiro想必大家都知道了,之前的文章我也有提过,是目前使用率要比spring security都要多的一个权限框架,本身spring自己都在用shiro,之前的文章有兴趣可以去扒一下 最近正好用到s ...
- Shiro 与spring 整合的及简单使用(转)
文章完全转载自: http://www.cnblogs.com/learnhow/p/5694876.html ,大家可以点击访问原文链接,个人仅作学习收藏 ! 本篇内容大多总结自张开涛的<跟 ...
- spring 整合hibernate注解时候,出现“Unknown entity: com.ssh.entry.Admin; nested exception is org.hibernate.MappingException: Unknown entity: com.ssh.entry.Admin”异常的问题
今天学习使用ssh框架的时候,出现一个异常,弄了好久才找到,在这记录一下,我的sb错误1.spring整合hibernate,取代*.hbm.xml配置文件 在applicationContext ...
- Hibernate Validation与Spring整合各注解的用法Demo
转自:https://www.aliyun.com/jiaocheng/1315650.html <dependency> <groupId>org.hibernate< ...
- Shiro第四篇【Shiro与Spring整合、快速入门、Shiro过滤器、登陆认证】
Spring与Shiro整合 导入jar包 shiro-web的jar. shiro-spring的jar shiro-code的jar 快速入门 shiro也通过filter进行拦截.filter拦 ...
- spring整合ehcache注解实现查询缓存,并实现实时缓存更新或删除
转载: http://www.importnew.com/23358.html 写在前面:上一篇博客写了spring cache和ehcache的基本介绍,个人建议先把这些最基本的知识了解了才能对今天 ...
- spring整合ehcache 注解实现查询缓存,并实现实时缓存更新或删除
写在前面:上一篇博客写了spring cache和ehcache的基本介绍,个人建议先把这些最基本的知识了解了才能对今天主题有所感触.不多说了,开干! 注:引入jar <!-- 引入ehcach ...
随机推荐
- mysql分组取前N记录
http://blog.csdn.net/acmain_chm/article/details/4126306 http://bbs.csdn.net/topics/390958705 1 我只用到了 ...
- java 多线程剖析
问题的缘由源自于一道简单的面试题:题目要求如下: 建立三个线程,A线程打印10次A,B线程打印10次B,C线程打印10次C,要求线程同时运行,交替打印10次ABC. 解决问题前我们前补充一些基本知识: ...
- 属性名、变量名与 内部关键字 重名 加&
procedure TForm4.btn3Click(Sender: TObject); var MyQj: TQJson; MyPrinter: TPrinter; begin MyQj := TQ ...
- Linux安装mysql.8.0.12
1. linux安装mysql8.0.12,亲测可用. 以下是安装过程中出现的问题: 1 [root@localtest1 file]# systemctl start mysqld 2 Job fo ...
- MapReduce案例二:好友推荐
1.需求 推荐好友的好友 图1: 2.解决思路 3.代码 3.1MyFoF类代码 说明: 该类定义了所加载的配置,以及执行的map,reduce程序所需要加载运行的类 package com.hado ...
- redis之(十三)redis的三种启动方式
Part I. 直接启动 下载 官网下载 安装 tar zxvf redis-2.8.9.tar.gz cd redis-2.8.9 #直接make 编译 make #可使用root用户执行`make ...
- [水煮 ASP.NET Web API2 方法论](1-2)在 WebForm 应用程序中添加 ASP.NET Web API
问题 怎么样将 Asp.Net Web Api 加入到 Asp.Net Web From 应用程序中 解决方案 在 Visual Studio 2013 中,创建新的 Web From,可以直接在&q ...
- springboot的mvn与gradle启动方式
1 很简单,直接鼠标右击项目,run启动项目 2 项目目录下的命令行 mvn spring-boot:run 或者 gradlew bootRun 3 进入libs下或者target下 java ...
- 如何通过 Redis 实现分布式锁
分布式锁需要解决的问题: 互斥性:任意时刻只能有一个客户端获取锁 安全性:锁只能被持有该锁的客户端删除 死锁:获取锁的客户端因为意外宕机未能释放锁,其他客户端再也无法获取到该锁导致死锁 容错:宕机后客 ...
- HTTP(HyperText Transport Protocol)超文本传输协议的状态码
关于HTTP状态码:是用于表示网页服务器HTTP响应状态的3位数字代码. 所有状态码的第一个数字代表了响应的五种状态之一. 1xx:消息:这一类型的状态码代表请求已被接受,需要继续处理 2xx:成功: ...