how2j.cn

下载区
文件名 文件大小
lib.rar 12m
shiro.rar 12m
步骤 1 : 权限维护一套   
步骤 2 : 表结构调整   
步骤 3 : 新的表数据   
步骤 4 : 先运行,看到效果,再学习   
步骤 5 : 模仿和排错   
步骤 6 : 用户管理效果   
步骤 7 : 角色管理效果   
步骤 8 : 权限管理效果   
步骤 9 : 基于前面的知识点   
步骤 10 : jar   
步骤 11 : OverIsMergeablePlugin   
步骤 12 : generatorConfig.xml   
步骤 13 : MybatisGenerator   
步骤 14 : Pojo,Example,Mapper   
步骤 15 : Service层   
步骤 16 : Service实现层   
步骤 17 : Controller 层   
步骤 18 : menu.jsp   
步骤 19 : View层   
步骤 20 : style.css   
步骤 21 : web.xml   
步骤 22 : DatabaseRealm   
步骤 23 : applicationContext-shiro.xml   
步骤 24 : 重启tomcat 访问测试   
步骤 25 : 原业务功能   

步骤 1 :

权限维护一套

edit
上一个知识点ssm,哪里需要权限,哪里写注解@RequirePermission就行。 但是,真正项目开发的时候,这种方式就很有局限性了,当权限配置关系发生变化,每次都要修改代码,编译打包重启系统,这肯定是不能够被接受的。
所以,最好的方式,还是通过动态配置,哪个给不同的用户配置不同的角色,权限,修改之后立马生效这种方式。 为了实现这个效果,就需要基于URL配置的方式来做了。

接下来要做基于URL配置权限的讲解。 但是基于URL配置权限需要自己能够进行权限信息的灵活配置,那么就需要对权限信息一套进行维护。
而权限一套本身的维护,就已经有相当的复杂性了。 为了学习更加平滑,本知识仅仅对权限一套信息的维护,进行开发,以此为后续的基于URL配置权限做准备。
对表结构有所调整,主要是增加了一些字段。
DROP DATABASE IF EXISTS shiro; CREATE DATABASE shiro DEFAULT CHARACTER SET utf8; USE shiro; drop table if exists user; drop table if exists role; drop table if exists permission; drop table if exists user_role; drop table if exists role_permission; create table user ( id bigint auto_increment, name varchar(100), password varchar(100), salt varchar(100), constraint pk_users primary key(id) ) charset=utf8 ENGINE=InnoDB; create table role ( id bigint auto_increment, name varchar(100), desc_ varchar(100), constraint pk_roles primary key(id) ) charset=utf8 ENGINE=InnoDB; create table permission ( id bigint auto_increment, name varchar(100), desc_ varchar(100), url varchar(100), constraint pk_permissions primary key(id) ) charset=utf8 ENGINE=InnoDB; create table user_role ( id bigint auto_increment, uid bigint, rid bigint, constraint pk_users_roles primary key(id) ) charset=utf8 ENGINE=InnoDB; create table role_permission ( id bigint auto_increment, rid bigint, pid bigint, constraint pk_roles_permissions primary key(id) ) charset=utf8 ENGINE=InnoDB;
增加基本数据。
INSERT INTO `permission` VALUES (1,'addProduct','增加产品','/addProduct'); INSERT INTO `permission` VALUES (2,'deleteProduct','删除产品','/deleteProduct'); INSERT INTO `permission` VALUES (3,'editeProduct','编辑产品','/editeProduct'); INSERT INTO `permission` VALUES (4,'updateProduct','修改产品','/updateProduct'); INSERT INTO `permission` VALUES (5,'listProduct','查看产品','/listProduct'); INSERT INTO `permission` VALUES (6,'addOrder','增加订单','/addOrder'); INSERT INTO `permission` VALUES (7,'deleteOrder','删除订单','/deleteOrder'); INSERT INTO `permission` VALUES (8,'editeOrder','编辑订单','/editeOrder'); INSERT INTO `permission` VALUES (9,'updateOrder','修改订单','/updateOrder'); INSERT INTO `permission` VALUES (10,'listOrder','查看订单','/listOrder'); INSERT INTO `role` VALUES (1,'admin','超级管理员'); INSERT INTO `role` VALUES (2,'productManager','产品管理员'); INSERT INTO `role` VALUES (3,'orderManager','订单管理员'); INSERT INTO `role_permission` VALUES (1,1,1); INSERT INTO `role_permission` VALUES (2,1,2); INSERT INTO `role_permission` VALUES (3,1,3); INSERT INTO `role_permission` VALUES (4,1,4); INSERT INTO `role_permission` VALUES (5,1,5); INSERT INTO `role_permission` VALUES (6,1,6); INSERT INTO `role_permission` VALUES (7,1,7); INSERT INTO `role_permission` VALUES (8,1,8); INSERT INTO `role_permission` VALUES (9,1,9); INSERT INTO `role_permission` VALUES (10,1,10); INSERT INTO `role_permission` VALUES (11,2,1); INSERT INTO `role_permission` VALUES (12,2,2); INSERT INTO `role_permission` VALUES (13,2,3); INSERT INTO `role_permission` VALUES (14,2,4); INSERT INTO `role_permission` VALUES (15,2,5); INSERT INTO `role_permission` VALUES (50,3,10); INSERT INTO `role_permission` VALUES (51,3,9); INSERT INTO `role_permission` VALUES (52,3,8); INSERT INTO `role_permission` VALUES (53,3,7); INSERT INTO `role_permission` VALUES (54,3,6); INSERT INTO `role_permission` VALUES (55,3,1); INSERT INTO `role_permission` VALUES (56,5,11); INSERT INTO `user` VALUES (1,'zhang3','a7d59dfc5332749cb801f86a24f5f590','e5ykFiNwShfCXvBRPr3wXg=='); INSERT INTO `user` VALUES (2,'li4','43e28304197b9216e45ab1ce8dac831b','jPz19y7arvYIGhuUjsb6sQ=='); INSERT INTO `user_role` VALUES (43,2,2); INSERT INTO `user_role` VALUES (45,1,1);
步骤 4 :

先运行,看到效果,再学习

edit
老规矩,先下载右上角的可运行项目,配置运行起来,确认可用之后,再学习做了哪些步骤以达到这样的效果。
在确保可运行项目能够正确无误地运行之后,再严格照着教程的步骤,对代码模仿一遍。
模仿过程难免代码有出入,导致无法得到期望的运行结果,此时此刻通过比较正确答案 ( 可运行项目 ) 和自己的代码,来定位问题所在。
采用这种方式,学习有效果,排错有效率,可以较为明显地提升学习速度,跨过学习路上的各个槛。

推荐使用diffmerge软件,进行文件夹比较。把你自己做的项目文件夹,和我的可运行项目文件夹进行比较。
这个软件很牛逼的,可以知道文件夹里哪两个文件不对,并且很明显地标记出来
这里提供了绿色安装和使用教程:diffmerge 下载和使用教程
步骤 6 :

用户管理效果

edit
访问地址:

http://127.0.0.1:8080/shiro/config/listUser

两张截图放在一起,上面是查询和增加,下面是修改和配置角色关系。
用户管理效果
步骤 7 :

角色管理效果

edit
访问地址:

http://127.0.0.1:8080/shiro/config/listRole

两张截图放在一起,上面是查询和增加,下面是修改和配置权限关系。
角色管理效果
步骤 8 :

权限管理效果

edit
访问地址:

http://127.0.0.1:8080/shiro/config/listPermission

两张截图放在一起,上面是查询和增加,下面是修改和配置权限关系。
权限管理效果
步骤 9 :

基于前面的知识点

edit
本项目是基于上一个知识点ssm 进行扩展,所以下面就列出改动了的地方,不再从每一文件创建说起。
增加了一些jar,主要用于对 Mybatis 逆向工程的支持
参考:逆向工程教程:逆向工程
右上角的lib.rar,解压后复制粘贴到 WebContent/WEB-INF/lib 下
jar
步骤 11 :

OverIsMergeablePlugin

edit
MybatisGenerator插件是Mybatis官方提供的,这个插件存在一个固有的Bug,即当第一次生成了Mapper.xml之后,再次运行会导致Mapper.xml生成重复内容,而影响正常的运行。
为了解决这个问题,需要自己写一个小插件类OverIsMergeablePlugin。 它为什么起作用说起来比较复杂,不在这里展开了,反正。。。我也是复制粘贴来的~
至于怎么使用,将在下一个步骤 generatorConfig.xml 讲解,这里先准备这个类。
package com.how2java.util; import org.mybatis.generator.api.GeneratedXmlFile; import org.mybatis.generator.api.IntrospectedTable; import org.mybatis.generator.api.PluginAdapter; import java.lang.reflect.Field; import java.util.List; public class OverIsMergeablePlugin extends PluginAdapter { @Override public boolean validate(List<String> warnings) { return true; } @Override public boolean sqlMapGenerated(GeneratedXmlFile sqlMap, IntrospectedTable introspectedTable) { try { Field field = sqlMap.getClass().getDeclaredField("isMergeable"); field.setAccessible(true); field.setBoolean(sqlMap, false); } catch (Exception e) { e.printStackTrace(); } return true; } }
步骤 12 :

generatorConfig.xml

edit
这个配置文件就是用于指定要逆向工程哪些表的
generatorConfig.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration> <context id="DB2Tables" targetRuntime="MyBatis3"> <!--避免生成重复代码的插件--> <plugin type="com.how2java.util.OverIsMergeablePlugin" /> <!--是否在代码中显示注释--> <commentGenerator> <property name="suppressDate" value="true" /> <property name="suppressAllComments" value="true" /> </commentGenerator> <!--数据库链接地址账号密码--> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost/shiro" userId="root" password="admin"> </jdbcConnection> <!--不知道做什么用的。。。反正贴上来了~--> <javaTypeResolver> <property name="forceBigDecimals" value="false"/> </javaTypeResolver> <!--生成pojo类存放位置--> <javaModelGenerator targetPackage="com.how2java.pojo" targetProject="src"> <property name="enableSubPackages" value="true"/> <property name="trimStrings" value="true"/> </javaModelGenerator> <!--生成xml映射文件存放位置--> <sqlMapGenerator targetPackage="com.how2java.mapper" targetProject="src"> <property name="enableSubPackages" value="true"/> </sqlMapGenerator> <!--生成mapper类存放位置--> <javaClientGenerator type="XMLMAPPER" targetPackage="com.how2java.mapper" targetProject="src"> <property name="enableSubPackages" value="true"/> </javaClientGenerator> <!--生成对应表及类名--> <table tableName="user" domainObjectName="User" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false"> <property name="my.isgen.usekeys" value="true"/> <property name="useActualColumnNames" value="true"/> <generatedKey column="id" sqlStatement="JDBC"/> </table> <table tableName="role" domainObjectName="Role" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false"> <property name="my.isgen.usekeys" value="true"/> <property name="useActualColumnNames" value="true"/> <generatedKey column="id" sqlStatement="JDBC"/> </table> <table tableName="permission" domainObjectName="Permission" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false"> <property name="my.isgen.usekeys" value="true"/> <property name="useActualColumnNames" value="true"/> <generatedKey column="id" sqlStatement="JDBC"/> </table> <table tableName="user_role" domainObjectName="UserRole" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false"> <property name="my.isgen.usekeys" value="true"/> <property name="useActualColumnNames" value="true"/> <generatedKey column="id" sqlStatement="JDBC"/> </table> <table tableName="role_permission" domainObjectName="RolePermission" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false"> <property name="my.isgen.usekeys" value="true"/> <property name="useActualColumnNames" value="true"/> <generatedKey column="id" sqlStatement="JDBC"/> </table> </context> </generatorConfiguration>
步骤 13 :

MybatisGenerator

edit
运行 MybatisGenerator 以获取自动生成 Pojo、Example 和 Mapper
package com.how2java.util; import org.mybatis.generator.api.MyBatisGenerator; import org.mybatis.generator.config.Configuration; import org.mybatis.generator.config.xml.ConfigurationParser; import org.mybatis.generator.internal.DefaultShellCallback; import java.io.InputStream; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; public class MybatisGenerator { public static void main(String[] args) throws Exception { String today = "2018-5-16"; SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd"); Date now =sdf.parse(today); Date d = new Date(); if(d.getTime()>now.getTime()+1000*60*60*24){ System.err.println("——————未成成功运行——————"); System.err.println("——————未成成功运行——————"); System.err.println("本程序具有破坏作用,应该只运行一次,如果必须要再运行,需要修改today变量为今天,如:" + sdf.format(new Date())); return; } if(false) return; List<String> warnings = new ArrayList<String>(); boolean overwrite = true; InputStream is= MybatisGenerator.class.getClassLoader().getResource("generatorConfig.xml").openStream(); ConfigurationParser cp = new ConfigurationParser(warnings); Configuration config = cp.parseConfiguration(is); is.close(); DefaultShellCallback callback = new DefaultShellCallback(overwrite); MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings); myBatisGenerator.generate(null); System.out.println("生成代码成功,只能执行一次,以后执行会覆盖掉mapper,pojo,xml 等文件上做的修改"); } }
步骤 14 :

Pojo,Example,Mapper

edit
如果是IDEA,那么生成后就会自动观察到这些文件的存在,如果是Eclipse需要刷新一下项目,才能看到如图所示pojo Mapper和xml都生成好了。

为什么要这么做? Mybatis 本质上就是自己写 sql 语句的一个帮助工具。 但是自己写 sql 太他妈繁琐了。。。 还是用逆向工程好,什么sql 都准备好了,能够支撑完成90% 的业务功能。 所以能偷懒就偷懒吧~
Pojo,Example,Mapper
package com.how2java.service; import java.util.List; import com.how2java.pojo.User; public interface UserService { public String getPassword(String name); public User getByName(String name); public List<User> list(); public void add(User user); public void delete(Long id); public User get(Long id); public void update(User user); }
package com.how2java.service; import java.util.List; import java.util.Set; import com.how2java.pojo.Role; import com.how2java.pojo.User; public interface RoleService { public Set<String> listRoleNames(String userName); public List<Role> listRoles(String userName); public List<Role> listRoles(User user); public List<Role> list(); public void add(Role role); public void delete(Long id); public Role get(Long id); public void update(Role role); }
package com.how2java.service; import java.util.List; import java.util.Set; import com.how2java.pojo.Permission; import com.how2java.pojo.Role; public interface PermissionService { public Set<String> listPermissions(String userName); public List<Permission> list(); public void add(Permission permission); public void delete(Long id); public Permission get(Long id); public void update(Permission permission); public List<Permission> list(Role role); }
package com.how2java.service; import com.how2java.pojo.User; public interface UserRoleService { public void setRoles(User user, long[] roleIds); public void deleteByUser(long userId); public void deleteByRole(long roleId); }
package com.how2java.service; import com.how2java.pojo.Role; public interface RolePermissionService { public void setPermissions(Role role, long[] permissionIds); public void deleteByRole(long roleId); public void deleteByPermission(long permissionId); }
步骤 16 :

Service实现层

edit
package com.how2java.service.impl; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.how2java.mapper.UserMapper; import com.how2java.pojo.User; import com.how2java.pojo.UserExample; import com.how2java.service.UserRoleService; import com.how2java.service.UserService; @Service public class UserServiceImpl implements UserService{ @Autowired UserMapper userMapper; @Autowired UserRoleService userRoleService; @Override public String getPassword(String name) { User user = getByName(name); if(null==user) return null; return user.getPassword(); } @Override public User getByName(String name) { UserExample example = new UserExample(); example.createCriteria().andNameEqualTo(name); List<User> users = userMapper.selectByExample(example); if(users.isEmpty()) return null; return users.get(0); } @Override public void add(User u) { userMapper.insert(u); } @Override public void delete(Long id) { userMapper.deleteByPrimaryKey(id); userRoleService.deleteByUser(id); } @Override public void update(User u) { userMapper.updateByPrimaryKeySelective(u); } @Override public User get(Long id) { return userMapper.selectByPrimaryKey(id); } @Override public List<User> list(){ UserExample example =new UserExample(); example.setOrderByClause("id desc"); return userMapper.selectByExample(example); } }
package com.how2java.service.impl; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.how2java.mapper.RoleMapper; import com.how2java.mapper.UserRoleMapper; import com.how2java.pojo.Role; import com.how2java.pojo.RoleExample; import com.how2java.pojo.User; import com.how2java.pojo.UserRole; import com.how2java.pojo.UserRoleExample; import com.how2java.service.RoleService; import com.how2java.service.UserService; @Service public class RoleServiceImpl implements RoleService{ @Autowired RoleMapper roleMapper; @Autowired UserRoleMapper userRoleMapper; @Autowired UserService userService; @Override public Set<String> listRoleNames(String userName) { Set<String> result = new HashSet<>(); List<Role> roles = listRoles(userName); for (Role role : roles) { result.add(role.getName()); } return result; } @Override public List<Role> listRoles(String userName) { List<Role> roles = new ArrayList<>(); User user = userService.getByName(userName); if(null==user) return roles; roles = listRoles(user); return roles; } @Override public void add(Role u) { roleMapper.insert(u); } @Override public void delete(Long id) { roleMapper.deleteByPrimaryKey(id); } @Override public void update(Role u) { roleMapper.updateByPrimaryKeySelective(u); } @Override public Role get(Long id) { return roleMapper.selectByPrimaryKey(id); } @Override public List<Role> list(){ RoleExample example =new RoleExample(); example.setOrderByClause("id desc"); return roleMapper.selectByExample(example); } @Override public List<Role> listRoles(User user) { List<Role> roles = new ArrayList<>(); UserRoleExample example = new UserRoleExample(); example.createCriteria().andUidEqualTo(user.getId()); List<UserRole> userRoles= userRoleMapper.selectByExample(example); for (UserRole userRole : userRoles) { Role role=roleMapper.selectByPrimaryKey(userRole.getRid()); roles.add(role); } return roles; } }
package com.how2java.service.impl; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.how2java.mapper.PermissionMapper; import com.how2java.mapper.RolePermissionMapper; import com.how2java.pojo.Permission; import com.how2java.pojo.PermissionExample; import com.how2java.pojo.Role; import com.how2java.pojo.RolePermission; import com.how2java.pojo.RolePermissionExample; import com.how2java.service.PermissionService; import com.how2java.service.RoleService; import com.how2java.service.UserService; @Service public class PermissionServiceImpl implements PermissionService{ @Autowired PermissionMapper permissionMapper; @Autowired UserService userService; @Autowired RoleService roleService; @Autowired RolePermissionMapper rolePermissionMapper; @Override public Set<String> listPermissions(String userName) { Set<String> result = new HashSet<>(); List<Role> roles = roleService.listRoles(userName); List<RolePermission> rolePermissions = new ArrayList<>(); for (Role role : roles) { RolePermissionExample example = new RolePermissionExample(); example.createCriteria().andRidEqualTo(role.getId()); List<RolePermission> rps= rolePermissionMapper.selectByExample(example); rolePermissions.addAll(rps); } for (RolePermission rolePermission : rolePermissions) { Permission p = permissionMapper.selectByPrimaryKey(rolePermission.getPid()); result.add(p.getName()); } return result; } @Override public void add(Permission u) { permissionMapper.insert(u); } @Override public void delete(Long id) { permissionMapper.deleteByPrimaryKey(id); } @Override public void update(Permission u) { permissionMapper.updateByPrimaryKeySelective(u); } @Override public Permission get(Long id) { return permissionMapper.selectByPrimaryKey(id); } @Override public List<Permission> list(){ PermissionExample example =new PermissionExample(); example.setOrderByClause("id desc"); return permissionMapper.selectByExample(example); } @Override public List<Permission> list(Role role) { List<Permission> result = new ArrayList<>(); RolePermissionExample example = new RolePermissionExample(); example.createCriteria().andRidEqualTo(role.getId()); List<RolePermission> rps = rolePermissionMapper.selectByExample(example); for (RolePermission rolePermission : rps) { result.add(permissionMapper.selectByPrimaryKey(rolePermission.getPid())); } return result; } }
package com.how2java.service.impl; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.how2java.mapper.UserRoleMapper; import com.how2java.pojo.Role; import com.how2java.pojo.User; import com.how2java.pojo.UserRole; import com.how2java.pojo.UserRoleExample; import com.how2java.service.UserRoleService; @Service public class UserRoleServiceImpl implements UserRoleService{ @Autowired UserRoleMapper userRoleMapper; @Override public void setRoles(User user, long[] roleIds) { //删除当前用户所有的角色 UserRoleExample example= new UserRoleExample(); example.createCriteria().andUidEqualTo(user.getId()); List<UserRole> urs= userRoleMapper.selectByExample(example); for (UserRole userRole : urs) userRoleMapper.deleteByPrimaryKey(userRole.getId()); //设置新的角色关系 if(null!=roleIds) for (long rid : roleIds) { UserRole userRole = new UserRole(); userRole.setRid(rid); userRole.setUid(user.getId()); userRoleMapper.insert(userRole); } } @Override public void deleteByUser(long userId) { UserRoleExample example= new UserRoleExample(); example.createCriteria().andUidEqualTo(userId); List<UserRole> urs= userRoleMapper.selectByExample(example); for (UserRole userRole : urs) { userRoleMapper.deleteByPrimaryKey(userRole.getId()); } } @Override public void deleteByRole(long roleId) { UserRoleExample example= new UserRoleExample(); example.createCriteria().andRidEqualTo(roleId); List<UserRole> urs= userRoleMapper.selectByExample(example); for (UserRole userRole : urs) { userRoleMapper.deleteByPrimaryKey(userRole.getId()); } } }
package com.how2java.service.impl; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.how2java.mapper.RolePermissionMapper; import com.how2java.pojo.Permission; import com.how2java.pojo.Role; import com.how2java.pojo.RolePermission; import com.how2java.pojo.RolePermissionExample; import com.how2java.service.RolePermissionService; @Service public class RolePermissionServiceImpl implements RolePermissionService{ @Autowired RolePermissionMapper rolePermissionMapper; @Override public void setPermissions(Role role, long[] permissionIds) { //删除当前角色所有的权限 RolePermissionExample example= new RolePermissionExample(); example.createCriteria().andRidEqualTo(role.getId()); List<RolePermission> rps= rolePermissionMapper.selectByExample(example); for (RolePermission rolePermission : rps) rolePermissionMapper.deleteByPrimaryKey(rolePermission.getId()); //设置新的权限关系 if(null!=permissionIds) for (long pid : permissionIds) { RolePermission rolePermission = new RolePermission(); rolePermission.setPid(pid); rolePermission.setRid(role.getId()); rolePermissionMapper.insert(rolePermission); } } @Override public void deleteByRole(long roleId) { RolePermissionExample example= new RolePermissionExample(); example.createCriteria().andRidEqualTo(roleId); List<RolePermission> rps= rolePermissionMapper.selectByExample(example); for (RolePermission rolePermission : rps) rolePermissionMapper.deleteByPrimaryKey(rolePermission.getId()); } @Override public void deleteByPermission(long permissionId) { RolePermissionExample example= new RolePermissionExample(); example.createCriteria().andPidEqualTo(permissionId); List<RolePermission> rps= rolePermissionMapper.selectByExample(example); for (RolePermission rolePermission : rps) rolePermissionMapper.deleteByPrimaryKey(rolePermission.getId()); } }
package com.how2java.controller; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.shiro.crypto.SecureRandomNumberGenerator; import org.apache.shiro.crypto.hash.SimpleHash; 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 com.how2java.pojo.Role; import com.how2java.pojo.User; import com.how2java.service.RoleService; import com.how2java.service.UserRoleService; import com.how2java.service.UserService; @Controller @RequestMapping("config") public class UserController { @Autowired UserRoleService userRoleService; @Autowired UserService userService; @Autowired RoleService roleService; @RequestMapping("listUser") public String list(Model model){ List<User> us= userService.list(); model.addAttribute("us", us); Map<User,List<Role>> user_roles = new HashMap<>(); for (User user : us) { List<Role> roles=roleService.listRoles(user); user_roles.put(user, roles); } model.addAttribute("user_roles", user_roles); return "listUser"; } @RequestMapping("editUser") public String edit(Model model,long id){ List<Role> rs = roleService.list(); model.addAttribute("rs", rs); User user =userService.get(id); model.addAttribute("user", user); List<Role> roles =roleService.listRoles(user); model.addAttribute("currentRoles", roles); return "editUser"; } @RequestMapping("deleteUser") public String delete(Model model,long id){ userService.delete(id); return "redirect:listUser"; } @RequestMapping("updateUser") public String update(User user,long[] roleIds){ userRoleService.setRoles(user,roleIds); String password=user.getPassword(); //如果在修改的时候没有设置密码,就表示不改动密码 if(user.getPassword().length()!=0) { String salt = new SecureRandomNumberGenerator().nextBytes().toString(); int times = 2; String algorithmName = "md5"; String encodedPassword = new SimpleHash(algorithmName,password,salt,times).toString(); user.setSalt(salt); user.setPassword(encodedPassword); } else user.setPassword(null); userService.update(user); return "redirect:listUser"; } @RequestMapping("addUser") public String add(Model model,String name, String password){ String salt = new SecureRandomNumberGenerator().nextBytes().toString(); int times = 2; String algorithmName = "md5"; String encodedPassword = new SimpleHash(algorithmName,password,salt,times).toString(); User u = new User(); u.setName(name); u.setPassword(encodedPassword); u.setSalt(salt); userService.add(u); return "redirect:listUser"; } }
package com.how2java.controller; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; 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 com.how2java.pojo.Permission; import com.how2java.pojo.Role; import com.how2java.service.PermissionService; import com.how2java.service.RolePermissionService; import com.how2java.service.RoleService; @Controller @RequestMapping("config") public class RoleController { @Autowired RoleService roleService; @Autowired RolePermissionService rolePermissionService; @Autowired PermissionService permissionService; @RequestMapping("listRole") public String list(Model model){ List<Role> rs= roleService.list(); model.addAttribute("rs", rs); Map<Role,List<Permission>> role_permissions = new HashMap<>(); for (Role role : rs) { List<Permission> ps = permissionService.list(role); role_permissions.put(role, ps); } model.addAttribute("role_permissions", role_permissions); return "listRole"; } @RequestMapping("editRole") public String list(Model model,long id){ Role role =roleService.get(id); model.addAttribute("role", role); List<Permission> ps = permissionService.list(); model.addAttribute("ps", ps); List<Permission> currentPermissions = permissionService.list(role); model.addAttribute("currentPermissions", currentPermissions); return "editRole"; } @RequestMapping("updateRole") public String update(Role role,long[] permissionIds){ rolePermissionService.setPermissions(role, permissionIds); roleService.update(role); return "redirect:listRole"; } @RequestMapping("addRole") public String list(Model model,Role role){ System.out.println(role.getName()); System.out.println(role.getDesc_()); roleService.add(role); return "redirect:listRole"; } @RequestMapping("deleteRole") public String delete(Model model,long id){ roleService.delete(id); return "redirect:listRole"; } }
package com.how2java.controller; import java.util.List; 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 com.how2java.pojo.Permission; import com.how2java.service.PermissionService; @Controller @RequestMapping("config") public class PermissionController { @Autowired PermissionService permissionService; @RequestMapping("listPermission") public String list(Model model){ List<Permission> ps= permissionService.list(); model.addAttribute("ps", ps); return "listPermission"; } @RequestMapping("editPermission") public String list(Model model,long id){ Permission permission =permissionService.get(id); model.addAttribute("permission", permission); return "editPermission"; } @RequestMapping("updatePermission") public String update(Permission permission){ permissionService.update(permission); return "redirect:listPermission"; } @RequestMapping("addPermission") public String list(Model model,Permission permission){ System.out.println(permission.getName()); System.out.println(permission.getDesc_()); permissionService.add(permission); return "redirect:listPermission"; } @RequestMapping("deletePermission") public String delete(Model model,long id){ permissionService.delete(id); return "redirect:listPermission"; } }
因为下面的View层 步骤中的jsp要用到这个文件,所以先准备它
在jsp目录下新增一个 include目录,然后新建menu.jsp文件
menu.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <div class="menu"> <a href="listUser">用户管理</a> <a href="listRole">角色管理</a> <a href="listPermission">权限管理</a> </div>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
	<div class="menu">
		<a href="listUser">用户管理</a>
		<a href="listRole">角色管理</a>
		<a href="listPermission">权限管理</a>
	</div>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> <link rel="stylesheet" type="text/css" href="../static/css/style.css" /> </head> <body> <div class="workingroom"> <%@include file="include/menu.jsp" %> <table> <tr> <td>id</td> <td>用户名称</td> <td>用户密码</td> <td>加密盐</td> <td>角色</td> <td>编辑</td> <td>删除</td> </tr> <c:forEach items="${us}" var="u"> <tr> <td>${u.id}</td> <td>${u.name}</td> <td>${fn:substring(u.password, 0, 5)}...</td> <td>${fn:substring(u.salt, 0, 5)}...</td> <td> <c:forEach items="${user_roles[u]}" var="r"> ${r.name} <br> </c:forEach> </td> <td><a href="editUser?id=${u.id}">编辑</a></td> <td><a href="deleteUser?id=${u.id}">删除</a></td> </tr> </c:forEach> </table> <div class="addOrEdit" > <form action="addUser" method="post"> 用户名: <input type="text" name="name"> <br> 密码: <input type="password" name="password"> <br><br> <input type="submit" value="增加"> </form> </div> </div> </body> </html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <link rel="stylesheet" type="text/css" href="../static/css/style.css" /> </head> <body> <div class="workingroom"> <%@include file="include/menu.jsp" %> <div class="addOrEdit" > <form action="updateUser" method="post"> 用户名: <input type="text" name="name" value="${user.name}"> <br><br> 密码: <input type="password" name="password" value="" placeholder="留空就表示不修改密码"> <br><br> 配置角色:<br> <div style="text-align:left;width:300px;margin:0px auto;padding-left:50px"> <c:forEach items="${rs}" var="r"> <c:set var="hasRole" value="false" /> <c:forEach items="${currentRoles}" var="currentRole"> <c:if test="${r.id==currentRole.id}"> <c:set var="hasRole" value="true" /> </c:if> </c:forEach> <input type="checkbox" ${hasRole?"checked='checked'":"" } name="roleIds" value="${r.id}"> ${r.name}<br> </c:forEach> </div> <br> <input type="hidden" name="id" value="${user.id}"> <input type="submit" value="修改"> </form> </div> </div> <script> </script> </body> </html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <link rel="stylesheet" type="text/css" href="../static/css/style.css" /> </head> <body> <div class="workingroom"> <%@include file="include/menu.jsp" %> <table> <tr> <td>id</td> <td>角色名称</td> <td>角色描述</td> <td>权限</td> <td>编辑</td> <td>删除</td> </tr> <c:forEach items="${rs}" var="r"> <tr> <td>${r.id}</td> <td>${r.name}</td> <td>${r.desc_}</td> <td> <c:forEach items="${role_permissions[r]}" var="p"> ${p.name} <br> </c:forEach> </td> <td><a href="editRole?id=${r.id}">编辑</a></td> <td><a href="deleteRole?id=${r.id}">删除</a></td> </tr> </c:forEach> </table> <div class="addOrEdit" > <form action="addRole" method="post"> 角色名称: <input type="text" name="name"> <br> 角色描述: <input type="text" name="desc_"> <br><br> <input type="submit" value="增加"> </form> </div> </div> </body> </html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <link rel="stylesheet" type="text/css" href="../static/css/style.css" /> </head> <body> <div class="workingroom"> <%@include file="include/menu.jsp" %> <div class="addOrEdit" > <form action="updateRole" method="post"> 角色名: <input type="text" name="name" value="${role.name}"> <br> 角色描述: <input type="text" name="desc_" value="${role.desc_}" > <br><br> 配置权限:<br> <div style="text-align:left;width:300px;margin:0px auto;padding-left:50px"> <c:forEach items="${ps}" var="p"> <c:set var="hasPermission" value="false" /> <c:forEach items="${currentPermissions}" var="currentPermission"> <c:if test="${p.id==currentPermission.id}"> <c:set var="hasPermission" value="true" /> </c:if> </c:forEach> <input type="checkbox" ${hasPermission?"checked='checked'":"" } name="permissionIds" value="${p.id}"> ${p.name}<br> </c:forEach> </div> <input type="hidden" name="id" value="${role.id}"> <input type="submit" value="修改"> </form> </div> </div> </body> </html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <link rel="stylesheet" type="text/css" href="../static/css/style.css" /> </head> <body> <div class="workingroom"> <%@include file="include/menu.jsp" %> <table> <tr> <td>id</td> <td>权限名称</td> <td>权限描述</td> <td>权限对应的路径</td> <td>编辑</td> <td>删除</td> </tr> <c:forEach items="${ps}" var="p"> <tr> <td>${p.id}</td> <td>${p.name}</td> <td>${p.desc_}</td> <td>${p.url}</td> <td><a href="editPermission?id=${p.id}">编辑</a></td> <td><a href="deletePermission?id=${p.id}">删除</a></td> </tr> </c:forEach> </table> <div class="addOrEdit" > <form action="addPermission" method="post"> 权限名称: <input type="text" name="name"> <br> 权限描述: <input type="text" name="desc_"> <br> 权限对应的url: <input type="text" name="url"> <br><br> <input type="submit" value="增加"> </form> </div> </div> </body> </html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <link rel="stylesheet" type="text/css" href="../static/css/style.css" /> </head> <body> <div class="workingroom"> <%@include file="include/menu.jsp" %> <div class="addOrEdit" > <form action="updatePermission" method="post"> 权限名称: <input type="text" name="name" value="${permission.name}"> <br> 权限描述: <input type="text" name="desc_" value="${permission.desc_}"> <br> 权限对应的url: <input type="text" name="url" value="${permission.url}"> <br><br> <input type="hidden" name="id" value="${permission.id}"> <input type="submit" value="修改"> </form> </div> </div> </body> </html>
样式做了些调整
span.desc{ margin-left:20px; color:gray; } div.workingroom{ margin:200px auto; width:600px; position:relative; } div.workingroom a{ /* display:inline-block; */ /* margin-top:20px; */ } div.loginDiv{ text-align: left; } div.errorInfo{ color:red; font-size:0.65em; } div.workingroom td{ border:1px solid black; } div.workingroom table{ border-collapse:collapse; width:100%; } div.workingroom td{ border:1px solid black; } div.workingroom div.menu{ position:absolute; left:-160px; top:-20px; } div.workingroom div.menu a{ display:block; margin-top:20px; } div.workingroom div.addOrEdit{ margin:20px; text-align:center; }
增加了中文过滤器,上一个知识点居然没这个。。。
<?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" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <!-- 中文过滤器 --> <filter> <filter-name>CharacterEncodingFilter</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> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- spring的配置文件--> <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:applicationContext.xml, classpath:applicationContext-shiro.xml </param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- spring mvc核心:分发servlet --> <servlet> <servlet-name>mvc-dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- spring mvc的配置文件 --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springMVC.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>mvc-dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!-- Shiro配置 --> <filter> <filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <init-param> <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> </web-app>
1. roleService.listRoles 改成了 roleService.listRoleNames
2. 因为现在有了增加用户功能(相当于注册),那么此时数据库里的密码也是加密状态的了。 那么校验工作,也使用 shiro 教程里另一个做法的DatabaseRealm 的方式来进行密码校验,而不是上个知识点 ssm 中的那样用明文校验了。
package com.how2java.realm; import java.util.Set; 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.authc.UsernamePasswordToken; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.codec.CodecException; import org.apache.shiro.crypto.UnknownAlgorithmException; import org.apache.shiro.crypto.hash.SimpleHash; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.util.ByteSource; import org.springframework.beans.factory.annotation.Autowired; import com.how2java.pojo.User; import com.how2java.service.PermissionService; import com.how2java.service.RoleService; import com.how2java.service.UserService; public class DatabaseRealm extends AuthorizingRealm { @Autowired private UserService userService; @Autowired private RoleService roleService; @Autowired private PermissionService permissionService; @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { //能进入到这里,表示账号已经通过验证了 String userName =(String) principalCollection.getPrimaryPrincipal(); //通过service获取角色和权限 Set<String> permissions = permissionService.listPermissions(userName); Set<String> roles = roleService.listRoleNames(userName); //授权对象 SimpleAuthorizationInfo s = new SimpleAuthorizationInfo(); //把通过service获取到的角色和权限放进去 s.setStringPermissions(permissions); s.setRoles(roles); return s; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { //获取账号密码 UsernamePasswordToken t = (UsernamePasswordToken) token; String userName= token.getPrincipal().toString(); //获取数据库中的密码 User user =userService.getByName(userName); String passwordInDB = user.getPassword(); String salt = user.getSalt(); //认证信息里存放账号密码, getName() 是当前Realm的继承方法,通常返回当前类名 :databaseRealm //盐也放进去 //这样通过applicationContext-shiro.xml里配置的 HashedCredentialsMatcher 进行自动校验 SimpleAuthenticationInfo a = new SimpleAuthenticationInfo(userName,passwordInDB,ByteSource.Util.bytes(salt),getName()); return a; } }
步骤 23 :

applicationContext-shiro.xml

edit
配合上个步骤DatabaseRealm,做了 shiro加密教程中的shiro.ini 中做的事情
设置密码匹配器

<!-- 密码匹配器 -->
<bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<property name="hashAlgorithmName" value="md5"/>
<property name="hashIterations" value="2"/>
<property name="storedCredentialsHexEncoded" value="true"/>
</bean>

让DatabaseRealm使用这个密码匹配器

<bean id="databaseRealm" class="com.how2java.realm.DatabaseRealm">
<property name="credentialsMatcher" ref="credentialsMatcher"/>
</bean>

只对业务功能进行权限管理,权限配置本身不需要没有做权限要求,这样做是为了不让初学者又要做业务的权限管理,又要做权限配置本身的权限管理,这样太过混乱

/config/**=anon
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:util="http://www.springframework.org/schema/util" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> <!-- 配置shiro的过滤器工厂类,id- shiroFilter要和我们在web.xml中配置的过滤器一致 --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <!-- 调用我们配置的权限管理器 --> <property name="securityManager" ref="securityManager" /> <!-- 配置我们的登录请求地址 --> <property name="loginUrl" value="/login" /> <!-- 如果您请求的资源不再您的权限范围,则跳转到/403请求地址 --> <property name="unauthorizedUrl" value="/unauthorized" /> <!-- 退出 --> <property name="filters"> <util:map> <entry key="logout" value-ref="logoutFilter" /> </util:map> </property> <!-- 权限配置 --> <property name="filterChainDefinitions"> <value> <!-- anon表示此地址不需要任何权限即可访问 --> /login=anon /index=anon /static/**=anon <!-- 只对业务功能进行权限管理,权限配置本身不需要没有做权限要求,这样做是为了不让初学者混淆 --> /config/**=anon /doLogout=logout <!--所有的请求(除去配置的静态资源请求或请求地址为anon的请求)都要通过登录验证,如果未登录则跳到/login --> /** = authc </value> </property> </bean> <!-- 退出过滤器 --> <bean id="logoutFilter" class="org.apache.shiro.web.filter.authc.LogoutFilter"> <property name="redirectUrl" value="/index" /> </bean> <!-- 会话ID生成器 --> <bean id="sessionIdGenerator" class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator" /> <!-- 会话Cookie模板 关闭浏览器立即失效 --> <bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie"> <constructor-arg value="sid" /> <property name="httpOnly" value="true" /> <property name="maxAge" value="-1" /> </bean> <!-- 会话DAO --> <bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO"> <property name="sessionIdGenerator" ref="sessionIdGenerator" /> </bean> <!-- 会话验证调度器,每30分钟执行一次验证 ,设定会话超时及保存 --> <bean name="sessionValidationScheduler" class="org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler"> <property name="interval" value="1800000" /> <property name="sessionManager" ref="sessionManager" /> </bean> <!-- 会话管理器 --> <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"> <!-- 全局会话超时时间(单位毫秒),默认30分钟 --> <property name="globalSessionTimeout" value="1800000" /> <property name="deleteInvalidSessions" value="true" /> <property name="sessionValidationSchedulerEnabled" value="true" /> <property name="sessionValidationScheduler" ref="sessionValidationScheduler" /> <property name="sessionDAO" ref="sessionDAO" /> <property name="sessionIdCookieEnabled" value="true" /> <property name="sessionIdCookie" ref="sessionIdCookie" /> </bean> <!-- 安全管理器 --> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="databaseRealm" /> <property name="sessionManager" ref="sessionManager" /> </bean> <!-- 相当于调用SecurityUtils.setSecurityManager(securityManager) --> <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> <property name="staticMethod" value="org.apache.shiro.SecurityUtils.setSecurityManager" /> <property name="arguments" ref="securityManager" /> </bean> <!-- 密码匹配器 --> <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"> <property name="hashAlgorithmName" value="md5"/> <property name="hashIterations" value="2"/> <property name="storedCredentialsHexEncoded" value="true"/> </bean> <bean id="databaseRealm" class="com.how2java.realm.DatabaseRealm"> <property name="credentialsMatcher" ref="credentialsMatcher"/> </bean> <!-- 保证实现了Shiro内部lifecycle函数的bean执行 --> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" /> </beans>
步骤 24 :

重启tomcat 访问测试

edit
重启Tomcat ,然后访问如下地址进行测试:

http://127.0.0.1:8080/shiro/config/listUser
原业务功能还是访问如下地址进行访问:

http://127.0.0.1:8080/shiro/index

不过此时的权限还是通过注解@@RequiresPermissions 实现,而非动态url. 在下面知识点就会讲解动态url了


HOW2J公众号,关注后实时获知最新的教程和优惠活动,谢谢。


问答区域    
2021-01-18 userExample是用来做什么得?
海东青

userExample是用来做什么得?是不是没必要要




2 个答案

FARO_Z
答案时间:2021-04-22
MybatisGenerator自动生成的,可以用来进行更高级的sql查询

打工人
答案时间:2021-02-04
这是Mybatis的逆向工程生成的辅助查询,可以根据自己的需求来拼凑查询条件,这个东西还是很有用的。mybatis教程里有说。



回答已经提交成功,正在审核。 请于 我的回答 处查看回答记录,谢谢
答案 或者 代码至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到




2020-08-25 desc_ 字段一定不能变为desc关键词 ,我就是因为漏写了导致sql报错了,还找了半天。。。。。
凌鹧202

desc_ 字段一定不能变为desc关键词 ,我就是因为漏写了导致sql报错了,还找了半天。。。。。




1 个答案

FARO_Z
答案时间:2021-04-22
别偷懒,写description吧



回答已经提交成功,正在审核。 请于 我的回答 处查看回答记录,谢谢
答案 或者 代码至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到




2020-07-25 步骤24不添加密码匹配器还好,添加了密码匹配器后反而出现了莫名其妙的错误
2019-09-16 Admin的权限为什么不能有删除产品的呢
2019-09-02 关于UserController类的update方法问题


提问太多,页面渲染太慢,为了加快渲染速度,本页最多只显示几条提问。还有 8 条以前的提问,请 点击查看

提问之前请登陆
提问已经提交成功,正在审核。 请于 我的提问 处查看提问记录,谢谢
关于 工具和中间件-Shiro-权限维护一套 的提问

尽量提供截图代码异常信息,有助于分析和解决问题。 也可进本站QQ群交流: 578362961
提问尽量提供完整的代码,环境描述,越是有利于问题的重现,您的问题越能更快得到解答。
对教程中代码有疑问,请提供是哪个步骤,哪一行有疑问,这样便于快速定位问题,提高问题得到解答的速度
在已经存在的几千个提问里,有相当大的比例,是因为使用了和站长不同版本的开发环境导致的,比如 jdk, eclpise, idea, mysql,tomcat 等等软件的版本不一致。
请使用和站长一样的版本,可以节约自己大量的学习时间。 站长把教学中用的软件版本整理了,都统一放在了这里, 方便大家下载: https://how2j.cn/k/helloworld/helloworld-version/1718.html

上传截图