SpringBoot基本操作(七)——SpringBoot整合Shiro权限管理(完整demo+界面) 女爷i 2022-05-14 03:27 123阅读 0赞 ## SpringBoot2.0笔记 ## (一)[SpringBoot基本操作——环境搭建及项目][SpringBoot][创建][SpringBoot][(有demo)][SpringBoot] (二)[SpringBoot基本操作——使用IDEA打war包发布及测试][SpringBoot_IDEA_war] (三)[SpringBoot基本操作——SpringBoot整合SpringDataJpa(有demo)][SpringBoot_SpringBoot_SpringDataJpa_demo] (四)[SpringBoot基本操作——SpringBoot使用RedisTemplate整合Redis(有demo)][SpringBoot_SpringBoot_RedisTemplate_Redis_demo] (五)[SpringBoot基本操作——SpringBoot使用Jedis整合Redis(有demo)][SpringBoot_SpringBoot_Jedis_Redis_demo] (六)[SpringBoot基本操作——SpringBoot使用Junit4单元测试(有demo)][SpringBoot_SpringBoot_Junit4_demo] (七)[SpringBoot基本操作——SpringBoot整合Shiro权限管理(完整demo+界面)][SpringBoot_SpringBoot_Shiro_demo] 这篇花了我挺久的时间做整合,因为包含了最完整的示例,很早之前我就准备做一个整合shiro的示例出来,为什么呢?因为我自己在开发中遇到了权限管理的需求,但是我在网上参考了很多大牛的文章,发现并没有一个完整的示例可以给出来的,所以我曾经自己手写了一个基于RBAC的权限管理功能,[详见这里][Link 1],这个模块目前也在我们的系统中运行着,但是随着系统越来越庞大,我发现这个东西没那么好用了,很多我并不需要加入权限的操作受限于白名单管理,维护变得麻烦起来,现在我以shiro替换掉了,以下我给出的这个demo是从我们目前的项目中抽离开出来的,配合我之前发布的springboot2.0基础demo做了精简整合,这个模块可以直接嵌入你的springboot项目系统中。本篇部分参考了[纯洁的微笑][Link 2]大大的文章。 本文使用idea工具构建Springboot2.0+SpringMvc+Thymeleaf+SpringDataJPA+MySql+Shiro项目 GitHub地址:[https://github.com/jwwam/springbootShiro.git][https_github.com_jwwam_springbootShiro.git] ### 一、预览,这是一个怎样的项目 ### 1.登录模块,包含注册功能,动态GIF验证码 ![70][] 2.管理员登录后台界面,包含权限模块最基本的用户管理、角色管理、资源管理。 ![70 1][] 3.用户管理包括最基本的增删改查+角色分配+状态修改 ![70 2][] 4.添加用户界面 ![70 3][] 5.为用户分配角色 ![70 4][] 6.为角色分配资源 ![70 5][] 7.资源的新建删除及修改 ![70 6][] ![70 7][] 以上就是整个权限管理系统的界面浏览,下面将整理出完整的实现代码。 ### 二、项目构建目录和maven依赖 ### ![70 8][] 关键maven依赖 <!-- shiro spring. --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.2.2</version> </dependency> <!-- shiro ehcache --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-ehcache</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib</artifactId> <version>2.4</version> <classifier>jdk15</classifier> </dependency> ### 三、Shiro配置 ### 首先需要一个用户实体UserInfo.java package com.springboot.demo.base.entity; import javax.persistence.*; import java.io.Serializable; import java.util.Date; import java.util.List; @Table(name="user_info") @SuppressWarnings("serial") @Entity public class UserInfo implements Serializable { @Id @GeneratedValue private Integer uid=1; @Column(unique =true) private String username;//帐号 private String name;//名称(昵称或者真实姓名,不同系统不同定义) private String password; //密码; private String salt= "8d78869f470951332959580424d4bf4f";//加密密码的盐 private int state=0;//用户状态,0:创建未认证(比如没有激活,没有输入验证码等等)--等待验证的用户 , 1:正常状态,2:用户被锁定.3: 已上传认证资料未审核. 4: 已上传认证资料审核未通过 @Column(name= "create_date") //创建时间 Date createDate = new Date(); @Column(name= "update_date")//修改时间 Date updateDate = new Date(); @Column(name= "remarks") private String remarks;//描述 private String phone;//手机 private String reason;//审核原因 @ManyToMany(fetch= FetchType.EAGER)//立即从数据库中进行加载数据; @JoinTable(name = "SysUserRole", joinColumns = { @JoinColumn(name = "uid") }, inverseJoinColumns ={@JoinColumn(name = "roleId") }) private List<SysRole> roleList;// 一个用户具有多个角色 public Integer getUid() { return uid; } public void setUid(Integer uid) { this.uid = uid; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getSalt() { return salt; } public void setSalt(String salt) { this.salt = salt; } public int getState() { return state; } public void setState(int state) { this.state = state; } public List<SysRole> getRoleList() { return roleList; } public void setRoleList(List<SysRole> roleList) { this.roleList = roleList; } public Date getCreateDate() { return createDate; } public void setCreateDate(Date createDate) { this.createDate = createDate; } public Date getUpdateDate() { return updateDate; } public void setUpdateDate(Date updateDate) { this.updateDate = updateDate; } public String getRemarks() { return remarks; } public void setRemarks(String remarks) { this.remarks = remarks; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getReason() { return reason; } public void setReason(String reason) { this.reason = reason; } /** * 密码盐. * @return */ public String getCredentialsSalt(){ return this.username+this.salt; } //重新对盐重新进行了定义,用户名+salt,这样就更加不容易被破解 } 添加ShiroConfig.java 这里需要配置shiro的过滤规则 package com.springboot.demo.base.config; import java.util.LinkedHashMap; import java.util.Map; import java.util.Properties; import org.apache.shiro.authc.credential.HashedCredentialsMatcher; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver; @Configuration public class ShiroConfig { @Bean public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) { System.out.println("ShiroConfiguration.shirFilter()"); ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); //拦截器. Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>(); // 配置不会被拦截的链接 顺序判断 //filterChainDefinitionMap.put("/static/**", "anon"); //配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了 filterChainDefinitionMap.put("/logout", "logout"); //<!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了; //<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问--> filterChainDefinitionMap.put("/static/templates/**", "authc"); // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面 shiroFilterFactoryBean.setLoginUrl("/login/loginUser"); // 登录成功后要跳转的链接 shiroFilterFactoryBean.setSuccessUrl("/login/home"); //未授权界面; shiroFilterFactoryBean.setUnauthorizedUrl("/base/error"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; } /** * 凭证匹配器 * (由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了 * ) * @return */ @Bean public HashedCredentialsMatcher hashedCredentialsMatcher(){ HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher(); hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法:这里使用MD5算法; hashedCredentialsMatcher.setHashIterations(2);//散列的次数,比如散列两次,相当于 md5(md5("")); return hashedCredentialsMatcher; } @Bean public ShiroRealm myShiroRealm(){ ShiroRealm myShiroRealm = new ShiroRealm(); myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher()); return myShiroRealm; } @Bean public SecurityManager securityManager(){ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(myShiroRealm()); return securityManager; } /** * 开启shiro aop注解支持. * 使用代理方式;所以需要开启代码支持; * @param securityManager * @return */ @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){ AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); return authorizationAttributeSourceAdvisor; } @Bean(name="simpleMappingExceptionResolver") public SimpleMappingExceptionResolver createSimpleMappingExceptionResolver() { SimpleMappingExceptionResolver r = new SimpleMappingExceptionResolver(); Properties mappings = new Properties(); mappings.setProperty("DatabaseException", "/base/databaseError");//数据库异常处理 mappings.setProperty("UnauthorizedException","/base/error"); r.setExceptionMappings(mappings); // None by default //r.setDefaultErrorView("error"); // No default r.setDefaultErrorView("/base/login"); // 访问错误,直接访问登录页面 r.setExceptionAttribute("ex"); // Default is "exception" //r.setWarnLogCategory("example.MvcLogger"); // No default return r; } } ShiroRealm.java 这里主要进行用户身份的校验 package com.springboot.demo.base.config; import javax.annotation.Resource; import com.springboot.demo.base.entity.SysPermission; import com.springboot.demo.base.entity.SysRole; import com.springboot.demo.base.entity.UserInfo; import com.springboot.demo.base.service.UserInfoService; 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.apache.shiro.util.ByteSource; public class ShiroRealm extends AuthorizingRealm { @Resource private UserInfoService userInfoService; @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { System.out.println("权限配置-->MyShiroRealm.doGetAuthorizationInfo()"); SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); UserInfo userInfo = (UserInfo)principals.getPrimaryPrincipal(); for(SysRole role:userInfo.getRoleList()){ authorizationInfo.addRole(role.getRole()); for(SysPermission p:role.getPermissions()){ authorizationInfo.addStringPermission(p.getPermission()); } } //CacheUntil.setCacheTree(authorizationInfo); return authorizationInfo; } /*主要是用来进行身份认证的,也就是说验证用户输入的账号和密码是否正确。*/ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { System.out.println("ShiroRealm.doGetAuthenticationInfo()"); //获取用户的输入的账号. String username = (String)token.getPrincipal(); //通过username从数据库中查找 User对象,如果找到,没找到. //实际项目中,这里可以根据实际情况做缓存,如果不做,Shiro自己也是有时间间隔机制,2分钟内不会重复执行该方法 UserInfo userInfo = userInfoService.findByUsername(username); if(userInfo == null){ return null; } SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo( userInfo, //用户名 userInfo.getPassword(), //密码 ByteSource.Util.bytes(userInfo.getCredentialsSalt()),//salt=username+salt getName() //realm name ); return authenticationInfo; } } LoginController.java loginUser方法进行登录信息的校验,根据shiro返回的不同异常进行提示 package com.springboot.demo.base.controller; import com.springboot.demo.base.entity.UserInfo; import com.springboot.demo.base.utils.Captcha; import com.springboot.demo.base.utils.GifCaptcha; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.*; import org.apache.shiro.subject.Subject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.awt.*; import java.io.IOException; import java.util.Random; @Controller @RequestMapping("/login") public class LoginController extends BaseController{ protected final Logger logger = LoggerFactory.getLogger(this.getClass()); /** * 获取验证码(Gif版本) * @param response */ @RequestMapping(value="getGifCode",method = RequestMethod.GET) public void getGifCode(HttpServletResponse response,HttpServletRequest request){ try { response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 0); response.setContentType("image/gif"); /** * gif格式动画验证码 * 宽,高,位数。 */ HttpSession session = request.getSession(true); Captcha captcha = new GifCaptcha(146,33,4); /* 输出 */ captcha.out(response.getOutputStream()); String vcodeText = captcha.text().toLowerCase(); //存入Session session.setAttribute("_code",vcodeText); logger.info("保存vcode:"+vcodeText); System.out.println("------"+session.getAttribute("_code")); } catch (Exception e) { e.printStackTrace(); System.err.println("获取验证码异常:"+e.getMessage()); } } @RequestMapping("") public String index(){ logger.info("初始化登录页面...."); return"/base/login"; } @RequestMapping("/home") public String home(HttpServletResponse response){ UserInfo ui = this.getCurrentUser(); if( ui == null ){ try { response.sendRedirect("../login"); } catch (IOException e) { e.printStackTrace(); } } logger.info("初始化home页面...."); return"/base/home"; } @RequestMapping("/loginUser") public String loginUser(HttpServletRequest request,String username,String password,String vcode) { HttpSession session = request.getSession(); //转化成小写字母 vcode = vcode.toLowerCase(); String v = (String)session.getAttribute("_code");//还可以读取一次后把验证码清空,这样每次登录都必须获取验证码; logger.info("获取保存vcode:"+v); logger.info("验证vcode:"+vcode); if(!vcode.equals(v)){ logger.info("对用户[" + username + "]验证码不通过"); request.setAttribute("message", "验证码不正确"); return "/base/login";//返回登录页面 } logger.info("进行账号"+username+",密码验证"+password+"....."); UsernamePasswordToken usernamePasswordToken=new UsernamePasswordToken(username,password); Subject subject = SecurityUtils.getSubject(); try { subject.login(usernamePasswordToken); //完成登录 UserInfo user=(UserInfo) subject.getPrincipal(); session.setAttribute("user", user); session.setAttribute("clickId","home"); return "/base/loadHome"; }catch(UnknownAccountException uae){ logger.info("对用户[" + username + "]进行登录验证..验证未通过,未知账户"); request.setAttribute("message", "未知账户"); return "/base/login";//返回登录页面 }catch(IncorrectCredentialsException ice){ logger.info("对用户[" + username + "]进行登录验证..验证未通过,错误的凭证"); request.setAttribute("message", "密码不正确"); return "/base/login";//返回登录页面 }catch(LockedAccountException lae){ logger.info("对用户[" + username + "]进行登录验证..验证未通过,账户已锁定"); request.setAttribute("message", "账户已锁定"); return "/base/login";//返回登录页面 }catch(ExcessiveAttemptsException eae){ logger.info("对用户[" + username + "]进行登录验证..验证未通过,错误次数过多"); request.setAttribute("message", "用户名或密码错误次数过多"); return "/base/login";//返回登录页面 }catch(AuthenticationException ae){ //通过处理Shiro的运行时AuthenticationException就可以控制用户登录失败或密码错误时的情景 logger.info("对用户[" + username + "]进行登录验证..验证未通过,堆栈轨迹如下"); ae.printStackTrace(); request.setAttribute("message", "用户名或密码不正确"); return "/base/login";//返回登录页面 } } @RequestMapping("/logOut") public String logOut(HttpSession session) { Subject subject = SecurityUtils.getSubject(); subject.logout(); session.removeAttribute("user"); return "/base/login"; } @RequestMapping("/403") public String unauthorizedRole(){ System.out.println("------没有权限-------"); return "403"; } /** * 给定范围获得随机颜色 * @param fc * @param bc * @return */ private Color getRandColor(int fc, int bc) { Random random = new Random(); if (fc > 255) fc = 255; if (bc > 255) bc = 255; int r = fc + random.nextInt(bc - fc); int g = fc + random.nextInt(bc - fc); int b = fc + random.nextInt(bc - fc); return new Color(r, g, b); } } 在ShiroConfig.java中我们开启了shiro鉴权的aop支持,下面我们看如何使用它,关于用户UserInfo的增删改查及service、dao不再列出。 新建StudentController.java,配置一个访问路径RequestMapping为student/studentView,在方法上加入shiro鉴权注解@RequiresPermissions("student:view"),这里注意,在界面上的配置如下图,和权限字符串保持一致即可。 ![70 9][] 这样我们就添加了一个学生管理菜单,后面将其分配给不同角色,那么属于该角色的用户将能够访问student/studentView的内容。 注意application.properties需配置静态资源的路径,否则会获取不到静态文件。 #数据源 spring.datasource.url=jdbc:mysql://localhost:3306/demo_test?useUnicode=true&zeroDateTimeBehavior=convertToNull&autoReconnect=true spring.datasource.username=root spring.datasource.password=1234 spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.jpa.properties.hibernate.hbm2ddl.auto=update #热部署生效 spring.devtools.restart.enabled=true #mvc静态文件配置 #/css/**,/js/**,/componets/**,/images/** spring.mvc.static-path-pattern=/** spring.resources.static-locations=classpath:/static/,classpath:/templates/ 最后给出完整的表结构和pom包 /* Navicat MySQL Data Transfer Source Server : localhost Source Server Version : 50717 Source Host : localhost:3306 Source Database : demo_test Target Server Type : MYSQL Target Server Version : 50717 File Encoding : 65001 Date: 2018-09-01 20:17:12 */ SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for hibernate_sequence -- ---------------------------- DROP TABLE IF EXISTS `hibernate_sequence`; CREATE TABLE `hibernate_sequence` ( `next_val` bigint(20) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of hibernate_sequence -- ---------------------------- INSERT INTO `hibernate_sequence` VALUES ('10'); INSERT INTO `hibernate_sequence` VALUES ('10'); INSERT INTO `hibernate_sequence` VALUES ('10'); -- ---------------------------- -- Table structure for sys_permission -- ---------------------------- DROP TABLE IF EXISTS `sys_permission`; CREATE TABLE `sys_permission` ( `id` int(11) NOT NULL, `available` bit(1) DEFAULT NULL, `name` varchar(255) DEFAULT NULL, `number_sort` datetime DEFAULT NULL, `parent_id` bigint(20) DEFAULT NULL, `parent_ids` varchar(255) DEFAULT NULL, `permission` varchar(255) DEFAULT NULL, `resource_type` enum('menu','button') DEFAULT NULL, `url` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of sys_permission -- ---------------------------- INSERT INTO `sys_permission` VALUES ('1', '\0', '用户管理', '2018-06-25 11:30:51', '0', '0/', 'userInfo:view', 'menu', 'userInfo/userView'); INSERT INTO `sys_permission` VALUES ('2', '\0', '用户添加', '2018-06-25 11:34:51', '1', '0/1', 'userInfo:add', 'button', 'userInfo/userAdd'); INSERT INTO `sys_permission` VALUES ('3', '\0', '用户禁用', '2018-06-25 11:35:51', '1', '0/1', 'userInfo:del', 'button', 'userInfo/updateState'); INSERT INTO `sys_permission` VALUES ('4', '\0', '角色管理', '2018-06-25 11:40:51', '0', null, 'roleInfo:view', 'menu', 'roleInfo/roleView'); INSERT INTO `sys_permission` VALUES ('5', '\0', '资源管理', '2018-06-25 11:40:51', '0', null, 'sysPermission:view', 'menu', 'sysPermission/permissionView'); INSERT INTO `sys_permission` VALUES ('9', '\0', '学生管理', '2018-09-01 20:08:46', '0', null, 'student:view', 'menu', 'student/studentView'); -- ---------------------------- -- Table structure for sys_role -- ---------------------------- DROP TABLE IF EXISTS `sys_role`; CREATE TABLE `sys_role` ( `id` int(11) NOT NULL, `available` bit(1) DEFAULT NULL, `description` varchar(255) DEFAULT NULL, `role` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of sys_role -- ---------------------------- INSERT INTO `sys_role` VALUES ('2', '\0', '新注册用户', '新用户'); INSERT INTO `sys_role` VALUES ('1', '\0', '管理员', 'admin'); -- ---------------------------- -- Table structure for sys_role_permission -- ---------------------------- DROP TABLE IF EXISTS `sys_role_permission`; CREATE TABLE `sys_role_permission` ( `permission_id` int(11) NOT NULL, `role_id` int(11) NOT NULL, KEY `FK9q28ewrhntqeipl1t04kh1be7` (`role_id`), KEY `FKomxrs8a388bknvhjokh440waq` (`permission_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of sys_role_permission -- ---------------------------- INSERT INTO `sys_role_permission` VALUES ('5', '1'); INSERT INTO `sys_role_permission` VALUES ('4', '1'); INSERT INTO `sys_role_permission` VALUES ('1', '1'); INSERT INTO `sys_role_permission` VALUES ('3', '1'); INSERT INTO `sys_role_permission` VALUES ('2', '1'); INSERT INTO `sys_role_permission` VALUES ('6', '1'); -- ---------------------------- -- Table structure for sys_user_role -- ---------------------------- DROP TABLE IF EXISTS `sys_user_role`; CREATE TABLE `sys_user_role` ( `uid` int(11) NOT NULL, `role_id` int(11) NOT NULL, KEY `FKhh52n8vd4ny9ff4x9fb8v65qx` (`role_id`), KEY `FKgkmyslkrfeyn9ukmolvek8b8f` (`uid`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of sys_user_role -- ---------------------------- INSERT INTO `sys_user_role` VALUES ('1', '1'); -- ---------------------------- -- Table structure for user -- ---------------------------- DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` varchar(255) NOT NULL, `create_date` datetime DEFAULT NULL, `update_date` datetime DEFAULT NULL, `age` int(11) DEFAULT NULL, `name` varchar(100) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of user -- ---------------------------- INSERT INTO `user` VALUES ('56a514fc657d4dc09cb12b09f39d6846', '2018-08-28 01:42:20', '2018-08-28 01:42:20', '0', '老王的儿子'); INSERT INTO `user` VALUES ('c9e56bc8d15c45bb838a63786f931908', '2018-08-28 15:07:32', null, '25', '老王'); INSERT INTO `user` VALUES ('739086403d084de397282e8173d29f73', '2018-08-28 15:35:44', null, '22', '老王2'); INSERT INTO `user` VALUES ('c6bae69dad8c4b538ad4bafd435837c3', '2018-08-28 16:46:02', null, '18', '老王4'); -- ---------------------------- -- Table structure for user_info -- ---------------------------- DROP TABLE IF EXISTS `user_info`; CREATE TABLE `user_info` ( `uid` int(11) NOT NULL, `create_date` datetime DEFAULT NULL, `name` varchar(255) DEFAULT NULL, `password` varchar(255) DEFAULT NULL, `phone` varchar(255) DEFAULT NULL, `reason` varchar(255) DEFAULT NULL, `remarks` varchar(255) DEFAULT NULL, `salt` varchar(255) DEFAULT NULL, `state` int(11) NOT NULL, `update_date` datetime DEFAULT NULL, `username` varchar(255) DEFAULT NULL, PRIMARY KEY (`uid`), UNIQUE KEY `UK_f2ksd6h8hsjtd57ipfq9myr64` (`username`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of user_info -- ---------------------------- INSERT INTO `user_info` VALUES ('1', '2018-06-23 17:07:40', '管理员', 'd3c59d25033dbf980d29554025c23a75', null, null, null, '8d78869f470951332959580424d4bf4f', '1', '2018-08-31 15:56:33', 'admin'); INSERT INTO `user_info` VALUES ('3', '2018-08-31 16:13:53', '张三', '79332ad51f315fdcdaaa0394c46ffcd7', null, null, '', '8d78869f470951332959580424d4bf4f', '0', '2018-08-31 16:13:53', 'zhangsan'); <?xml version="1.0" encoding="UTF-8"?> <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.springboot</groupId> <artifactId>springbootJpa</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <name>springbootJpa</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.4.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <!--<scope>provided</scope>--> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> <exclusions> <exclusion> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> </exclusion> <exclusion> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.2.10.Final</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- shiro spring. --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.2.2</version> </dependency> <!-- shiro ehcache --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-ehcache</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib</artifactId> <version>2.4</version> <classifier>jdk15</classifier> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> 全文完,2018/9/1 写博文不易,转载请注明出处。 [SpringBoot]: https://blog.csdn.net/zhulier1124/article/details/81988471 [SpringBoot_IDEA_war]: https://blog.csdn.net/zhulier1124/article/details/82012829 [SpringBoot_SpringBoot_SpringDataJpa_demo]: https://blog.csdn.net/zhulier1124/article/details/82121461 [SpringBoot_SpringBoot_RedisTemplate_Redis_demo]: https://blog.csdn.net/zhulier1124/article/details/82154937 [SpringBoot_SpringBoot_Jedis_Redis_demo]: https://blog.csdn.net/zhulier1124/article/details/82193182 [SpringBoot_SpringBoot_Junit4_demo]: https://blog.csdn.net/zhulier1124/article/details/82228831 [SpringBoot_SpringBoot_Shiro_demo]: https://blog.csdn.net/zhulier1124/article/details/82289736 [Link 1]: https://blog.csdn.net/zhulier1124/article/details/79224876 [Link 2]: http://www.ityouknow.com/springboot/2017/06/26/springboot-shiro.html [https_github.com_jwwam_springbootShiro.git]: https://github.com/jwwam/springbootShiro.git [70]: /images/20220514/ff90bc4fc7364adc8cc99b3c0edcbbde.png [70 1]: /images/20220514/5c5ba1bf28ff4600ac26801addb2b6cd.png [70 2]: /images/20220514/53d34c9c8a42401b8afa1dd3cc040171.png [70 3]: /images/20220514/af3f84a5991946339a4ea2feabfe9f08.png [70 4]: /images/20220514/17880eb2e5594b6a94b1b1cc6544d805.png [70 5]: /images/20220514/190bd966eca04244883789daf38dbcad.png [70 6]: /images/20220514/51cbde699c904fbf9fc0e04493309ea1.png [70 7]: /images/20220514/5a2925ce86054bf5abdc51a86749d828.png [70 8]: /images/20220514/b4cb833112d54227a4a20b7ebe5e8703.png [70 9]: /images/20220514/844cfa66d2c44154b12a248ab8644007.png
还没有评论,来说两句吧...