本案例和ssm+shiro+jsp标签这篇文章几乎没差别,差别主要在于spring.xml文件中controller跳转的前后缀的区别以及使用的页面的不同,这个案例页面是ftl,那个案例是jsp页面,并且jsp页面可以写shiro标签


步骤一:在pom.xml文件中导入依赖

 <spring.version>4.3.25.RELEASE</spring.version><shiro.version>1.2.2</shiro.version><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version></dependency><!-- 德鲁伊数据连接池 --><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.0.9</version></dependency><!--shiro相关依赖--><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-ehcache</artifactId><version>${shiro.version}</version></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>${shiro.version}</version></dependency><!--spring ioc/di--><dependency><groupId>org.springframework</groupId><artifactId>spring-core</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-beans</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-expression</artifactId><version>${spring.version}</version></dependency><!-- spring - aop --><dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>${spring.version}</version></dependency><dependency><groupId>aopalliance</groupId><artifactId>aopalliance</artifactId><version>1.0</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.8.10</version></dependency><dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>3.2.4</version></dependency><!-- spring tx--><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>${spring.version}</version></dependency><!--web项目  --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version></dependency><dependency><groupId>javax.servlet.jsp</groupId><artifactId>jsp-api</artifactId><version>2.2</version></dependency><dependency><groupId>javax.servlet</groupId><artifactId>jstl</artifactId><version>1.2</version></dependency><!--spring整合web项目 --><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>${spring.version}</version></dependency><!--springmvc --><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>${spring.version}</version></dependency><!-- json --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.8.9</version></dependency><!-- 文件上传--><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.3.1</version></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.4</version></dependency><!--数据库相关 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.48</version></dependency><dependency><groupId>com.mchange</groupId><artifactId>c3p0</artifactId><version>0.9.5.2</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.5</version></dependency><!-- 缓存--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-ehcache</artifactId><version>1.0.0</version></dependency><dependency><groupId>net.sf.ehcache</groupId><artifactId>ehcache-core</artifactId><version>2.6.5</version></dependency><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>4.1.6</version></dependency><!-- mybatis整合spring  --><!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>1.3.2</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId><version>${spring.version}</version></dependency><dependency><groupId>com.yunpian.sdk</groupId><artifactId>yunpian-java-sdk</artifactId><version>1.2.7</version></dependency><!-- quartz --><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId><version>${spring.version}</version></dependency><dependency><groupId>com.yunpian.sdk</groupId><artifactId>yunpian-java-sdk</artifactId><version>1.2.7</version></dependency><!-- freemarker--><dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.23</version></dependency></dependencies>

步骤二:在resources文件夹创建mybatis-config.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!--给类起别名,默认是包下的类名首字母小写,后面字母不变就是它对应的别名。这个别名是给mapper文件省略类路径用的,如parameter、resultType等。基本类型mybatis已经七号别名了,因此只用管我们自建的实体类即可--><!--<typeAliases>&lt;!&ndash;<typeAlias type="com.entity.Student" alias="abc"></typeAlias>&ndash;&gt;<package name="com.qf.entity"></package></typeAliases>--><!--   &lt;!&ndash;展示出mapper文件中执行的sql语句的详细情况&ndash;&gt;<settings><setting name="logImpl" value="STDOUT_LOGGING"></setting></settings>--><!--插件写在plugins标签中,这里使用的就是分页插件--><plugins><plugin interceptor="com.github.pagehelper.PageHelper"><property name="dialect" value="mysql"/></plugin></plugins>
</configuration>

步骤三:在resouces下创建spring.xml配置文件.设置freemarker的controller层跳转的前后缀

<?xml version="1.0" encoding="UTF-8"?>
<!--加p、tx、mvc、context命名空间-->
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><!--连接数据库,即创建数据库连接对象--><bean id="db" class="com.alibaba.druid.pool.DruidDataSource"><!--druid连接池包路径,其他两个连接池路径自己不知道可以网上找找。找到评论留言,分享给其他人吧--><property name="username" value="root"></property><!--你连接的数据库的用户名--><property name="password" value="root"></property><!--连接的数据库的密码--><property name="url" value="jdbc:mysql://localhost:3306/shiroweb"></property><!--连接的数据库的地址,此处的数据库名叫hospital--><property name="driverClassName" value="com.mysql.jdbc.Driver"></property><!--根据使用的数据库连接池以及数据库,找对应的连接池,三种连接池,druid,c3p0,dbcp。去百度吧。此处用的druid连接池和myql数据库--></bean><!--用context命名空间扫描注解包--><context:component-scan base-package="com"><!--扫描com包下的所有注解,这个com包是我们自定义的,我们创建的所有java类都放在该包下面,具体可见最下面的案例框架图的com包的位置--></context:component-scan><!--创建InternalResourceViewResolver视图解析器,注意下面这四行,尤其是前后缀的这两行会影响你在跳转页面的前后缀名,如return "/index.jsp",在使用这两句前后缀语句后,只需return "index"即可--><!--<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">--><!--<property name="prefix" value="/"></property> &lt;!&ndash;return跳转页面时加前缀&ndash;&gt;--><!--<property name="suffix" value=".jsp"></property>&lt;!&ndash;加后缀&ndash;&gt;--><!--</bean>--><!--用MVC命名空间加注解驱动--><mvc:annotation-driven></mvc:annotation-driven><!--也是用于转换json必不可少的部分,另一个就是jackson包--><!--创建sqlsesion工厂,专门读取xml文件的--><bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean"><!--org.mybatis.spring.SqlSessionFactoryBean整合了mybatis和sring中的sqlsession--><property name="dataSource" ref="db"></property><!--将数据库连接赋进dataSource属性中--><property name="mapperLocations" value="classpath:mapper/*.xml"></property><!--mapper文件下的所有xml文件,不然创建一个扫描一个。此处*.xml爆红代表你mapper文件夹下还没创建xml文件--><property name="configLocation" value="classpath:mybatis-config.xml"></property><!--加载mybatis-config.xml配置文件--></bean><!--使用dao层实现类的时候,需要得到sqlSessionTemplate对象<bean class="org.mybatis.spring.SqlSessionTemplate"><constructor-arg index="0" ref="factory"></constructor-arg>&lt;!&ndash;将上面创建好的sqlsesion对象当成SqlSessionTemplate类的一个构造参数&ndash;&gt;</bean>--><!--6.省略dao实现类,扫描dao层的接口--><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.qf.dao"></property><property name="sqlSessionFactoryBeanName" value="factory" ></property></bean><bean id="tx" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="db"></property></bean><tx:advice id="ad"  transaction-manager="tx" ></tx:advice><!--id必须起个名字--><!--8.配置静态资源,如果不写,静态资源无法显示在网页中。这段话是根据后缀名判断是否是静态资源的,这是其优势也是劣势。当controller的RequestMapping的请求地址为jsp时可测试出来。这是因为我们在web.xml文件中拦截了除jsp外的所有静态资源,而所有资源走的都是dispatcherservlet,然后dispatcherservlet会去找到handler,这也是为什么最终由RequestMapping请求路径后缀来判断--><mvc:default-servlet-handler></mvc:default-servlet-handler><!--freemarker解析器--><bean id="configruration"class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer"><!-- 模板放置的位置  / classpath resources--><property name="templateLoaderPath" value="/" /><!--"/"表示ftl模板文件必须放在webapp下。ftl模板放在WEB-INF下的ftl文件夹下时value=/WEB-INF/ftl/,这表示ftl模板文件的位置--><property name="defaultEncoding" value="UTF-8" /></bean><!-- 页面访问。访问ftl模板文件时,他会自动编译成html文件--><bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver"><!--使用了freemarker视图解析器则必须把InternalResourceViewResolver这个springmvc的视图解析器去掉--><property name="contentType" value="text/html;charset=utf-8"/><property name="prefix" value="/" /><!--前缀,此时省略也没事--><property name="suffix" value=".ftl" /><!--controller层跳转的后缀,当index.ftl模板文件放在webapp下时访问路径:http://localhost:8080/index.ftl--></bean></beans>

步骤四:自定义realm,继承AuthorizingRealm类

package com.qf.realm;import com.qf.entity.User;
import com.qf.service.UserService;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import javax.annotation.Resource;
import java.util.Set;//shiro 授权和赋予角色都是在自定义realm中完成的,这也是使用shiro的核心。这也是shiro和数据库建立连接的核心,因为这里用户的角色和权限都是调用service层查询数据库得到的信息,因此applicationContxt-shiro.xml和spring.xml配置文件一定要放在一起,都放在contextlistener中加载,不然因为这个realm类先加载,会导致service无法正常注入
public class MyRealm extends AuthorizingRealm{@Autowiredprivate UserService userService;//当这个为null,是因为spring.xml这个文件在applicationContxt-shiro.xml之后加载的,是配置shiro配置文件加载顺序有问题,我直接全放在contextLoaderListener加载配置文件//授权。根据用户名查询用户对应的角色,然后根据角色查询对应的权限,并将角色和权限通过set方法设置给shiro框架。其次授权的前提是一定认证了@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {User user=(User)principals.getPrimaryPrincipal();//获取用户信息Set<String> roles=userService.selectRolesByUsername(user.getUsername());//根据用户名查询用户对应的角色System.out.println("roles = " + roles);Set<String> permissions=userService.selectPermissionsByRoles(roles);//根据用户角色查询权限System.out.println("permissions = " + permissions);SimpleAuthorizationInfo simpleAuthorizationInfo=new SimpleAuthorizationInfo();simpleAuthorizationInfo.setRoles(roles);//设置角色simpleAuthorizationInfo.setStringPermissions(permissions);//设置权限return simpleAuthorizationInfo;}//注意自定义的realm中执行sql语句对应的方法即使出错也不会报异常//认证。该方法主要用于通过用户输入的账号查询数据库对应的用户信息,传递真实密码。并将查到的用户信息传给上面的授权方法,给用户进行授权@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {String username = (String)token.getPrincipal();//通过token获取用户输入的账号, token.getCredentials()才是获取密码User user = (User) userService.selectUserByUsername(username);System.out.println("user:"+user);if (user == null) {//这代表根据账号没查到return null;}else {//这代表根据账号查到了用户信息SimpleAuthenticationInfo authenticationInfo=new SimpleAuthenticationInfo(user,user.getPassword(),"myrealm");//将用户信息传给调用自定义realm的controller类那。第一个参数是用户信息,controller层可通过subject.getpricinple获取,一般显示登录用户名用;第二个是用户密码,这个就是调用这个realm的securityManager底层比对密码的真实密码;第三个是随便的一个名字return authenticationInfo;}}
}

步骤五:在resouces下创建applicationContxt-shiro.xml配置文件,配置自定义realm、securityManager、拦截哪些地址资源等信息。即配置shiro信息,整合shiro的核心文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 该文件需要配realm、 secritymanager即shiro三大组成部分的其中两个,另外一个是subject --><!-- realm --><bean id="myrealm" class="com.qf.realm.MyRealm"><!--告诉shiro过滤器我们自定义的realm在哪--><!-- 此处写密码匹配,使用什么加密--></bean><!-- 自定义退出登陆 --><bean id="logout" class="org.apache.shiro.web.filter.authc.LogoutFilter"><property name="redirectUrl" value="/userftl/login" /><!--shiro自带的退出登录,此处表示/userftl/login就是触发shiro自带的突出登录的请求地址--></bean><!--创建securityManager对象--><bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"><property name="realm" ref="myrealm" /></bean><!-- 创建shiro过滤器,用于授权管理。intercepter拦截器是spring所独有的,因此shiro底层授权用的是过滤器--><!-- 授权管理 --><bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"><property name="securityManager" ref="securityManager" /><!--配置登录页面,认证不通过的会自动跳转到这个页面--><property name="loginUrl" value="/userftl/login" /><!--loginUrl对应的值是shiro自带的登录页面,/userftl/login这个请求地址是我们自己写的,它对应的处理方法就只有跳转登录页面--><!-- 配置被拦截的未授权时跳转的页面--><property name="unauthorizedUrl" value="/userftl/403" /><!--/userftl/403这个请求地址在这个案例中它对应的方法就只写了个跳转去未授权页面的--><!--配置过滤链,这才是shiro拦截的核心,定义请求地址被那种方式访问。anon代表匿名地址即不登录就可以访问的;authc代表公共访问地址,需要授权才能访问--><!--anon定义的是不用登录(认证)就可以访问的请求地址,authc是必须登录(认证)才能放行。anon和authc其实就是两个不同条件的过滤器,本质就是过滤器--><property name="filterChainDefinitions"><!--格式:  请求地址=anon   ,反正左侧就是资源(请求地址、静态资源),右侧就是申明请求地址的类型--><value>/test=anon/userftl/login=anon/user/login=anon/=anon    <!--/代表项目启动后访问的默认页面-->/userftl/403=anon<!-- 静态资源一定要设置为匿名资源-->/css/**=anon/font/**=anon/image/**=anon/js/**=anon/store/**=anon/user/logout=logout
<!--                授权的前提一定是已经认证过了,这是shiro默认的,也就意味着想接触授权的地址,一定是用户已经登录了roles[1,2]同时需要拥有两个角色才可以访问 ! and的关系-->/productftl/add=roles[管理员]  <!--roles[管理员]代表只有被授予管理员角色的才能访问,如果为roles[管理员,普通用户]代表要同时是管理员又是普通用户才能访问的请求地址--><!--请求地址=perms[权限1,权限2]-->/**=authc        <!--/** 代表拦截所有路径,除了上面被定义为匿名地址的请求路径--></value></property></bean></beans>

步骤六:配置WEB-INF下的web.xml文件,加载配置文件以及加载shiro的全局过滤器,只有配置了这个全局过滤器拦截才生效

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"version="3.0"><!--头部信息换成3.0,不然</async-supported>会报错,--><display-name>Archetype Created Web Application</display-name><!--利用DispatcherServlet核心类加载spring.xml配置文件--><servlet><servlet-name>aa</servlet-name><!--与servlet-mapping中的servlet-name要保持一致--><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value></param-value><!--只有DispatcherServlet才能加载spring.xml文件,因为他是子容器,子容器能访问父容器--></init-param></servlet><servlet-mapping><servlet-name>aa</servlet-name><url-pattern>/</url-pattern></servlet-mapping><!--一定要用ContextLoaderListener加载applicationContxt-shiro.xml配置文件,不然会报错--><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring.xml,classpath:applicationContxt-shiro.xml</param-value><!--applicationContxt-shiro.xml一定要在ContextLoaderListener中加载,因为这是父容器。父容器先加载--></context-param><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><!--用于初始化shiro中的所有过滤器--><filter><filter-name>shiroFilter</filter-name><filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class><async-supported>true</async-supported><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><!--/*代表过滤所有请求,只有拦截完了,我们才好在applicationContxt-shiro.xml中去决定放行哪些请求--></filter-mapping><!--处理post乱码,设置字符集--><filter><filter-name>bb</filter-name><!--与下面的filter-mapping中的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>bb</filter-name><url-pattern>/*</url-pattern><!--给所有文件设置字符集--></filter-mapping></web-app>


本次案例ssm+shiro+jsp标签框架就搭配完了,下面就开始案例的书写



步骤七:创建案例要使用的controller层、service层、dao层以及数据库表对应的实体类

数据库表对应的实体类
第一个实体类:User

package com.qf.entity;import java.util.List;public class User {private Integer uid;private String username;private String password;private String nickname;List<Role>  roles;public List<Role> getRoles() {return roles;}public void setRoles(List<Role> roles) {this.roles = roles;}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 == null ? null : username.trim();}public String getPassword() {return password;}public void setPassword(String password) {this.password = password == null ? null : password.trim();}public String getNickname() {return nickname;}public void setNickname(String nickname) {this.nickname = nickname == null ? null : nickname.trim();}@Overridepublic String toString() {return "User{" +"uid=" + uid +", username='" + username + '\'' +", password='" + password + '\'' +", nickname='" + nickname + '\'' +", roles=" + roles +'}';}
}

第二个实体类:Role

package com.qf.entity;import java.util.List;public class Role {private Integer rid;private String rname;private String rinfo;private List<Permission> permissions;public List<Permission> getPermissions() {return permissions;}public void setPermissions(List<Permission> permissions) {this.permissions = permissions;}public Integer getRid() {return rid;}public void setRid(Integer rid) {this.rid = rid;}public String getRname() {return rname;}public void setRname(String rname) {this.rname = rname == null ? null : rname.trim();}public String getRinfo() {return rinfo;}public void setRinfo(String rinfo) {this.rinfo = rinfo == null ? null : rinfo.trim();}@Overridepublic String toString() {return "Role{" +"rid=" + rid +", rname='" + rname + '\'' +", rinfo='" + rinfo + '\'' +", permissions=" + permissions +'}';}
}

第三个实体类:Permission

package com.qf.entity;public class Permission {private Integer pid;private String pname;private String paction;private String pinfo;public Integer getPid() {return pid;}public void setPid(Integer pid) {this.pid = pid;}public String getPname() {return pname;}public void setPname(String pname) {this.pname = pname == null ? null : pname.trim();}public String getPaction() {return paction;}public void setPaction(String paction) {this.paction = paction == null ? null : paction.trim();}public String getPinfo() {return pinfo;}public void setPinfo(String pinfo) {this.pinfo = pinfo == null ? null : pinfo.trim();}
}

controller层的类:
本案例controller层的重点类:UserController

package com.qf.controller;import com.qf.entity.User;
import com.qf.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.support.SessionStatus;import javax.annotation.Resource;@RequestMapping("/user")
@Controller
public class UserController {@Resourceprivate UserService userService;@RequestMapping("/login")public String login(User user, ModelMap modelMap){// User封装登录页面表单传过来的用户名和密码String  path="login";//注意这种用变量表示路径的方式UsernamePasswordToken usernamePasswordToken=new UsernamePasswordToken(user.getUsername(),user.getPassword());//user.getUsername()为用户输入的账号,user.getPassword()为用户输入的密码Subject subject = SecurityUtils.getSubject();//获取用户对象try{subject.login(usernamePasswordToken);//shiro底层完成登录验证path="home";User loginUser = (User)subject.getPrincipal();//获取在自定义realm中想传过来的值;jsp页面中的shiro标签获取到的就是认证后的信息modelMap.addAttribute("user",loginUser);return path;}catch (Exception e){User user2 = (User) userService.selectUserByUsername(user.getUsername());modelMap.addAttribute("msg","认证失败");return path;}}@RequestMapping("/logout")public String logout(ModelMap modelMap, SessionStatus sessionStatus){sessionStatus.setComplete();modelMap.addAttribute("msg","退出登录成功");return "login";}
}

第二个controller类:ProductFtlController,用于测试页面用的

package com.qf.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;@Controller
@RequestMapping("/productftl")
public class ProductFtlController {@RequestMapping("/show")public  String jumpShow(){return  "show";}@RequestMapping("/add")public String humpAdd(){return "show";}
}

第三个controller类:UserFtlController,用于跳转页面的

package com.qf.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;@Controller
@RequestMapping("/userftl")
public class UserFtlController {@RequestMapping("/403")public String jump403(){System.out.println("UserFtlController.jump403");return "403";}@RequestMapping("/home")public String jumpHome(){System.out.println("UserFtlController.jumpHome");return "home";}@RequestMapping("login")public String jumpLogin(){System.out.println("UserFtlController.jumpLogin");return "login";}
}

service层的接口及其实现类:
service层接口:UserService

package com.qf.service;import com.qf.entity.User;import java.util.List;
import java.util.Map;
import java.util.Set;public interface UserService {
public User selectUserByUsername(String username);public   Set<String> selectRolesByUsername(String username);public Set<String> selectPermissionsByRoles(Set<String> roles);
}

service层UserService对应的实现类:UserServiceImpl

package com.qf.service.impl;import com.qf.dao.UserDao;
import com.qf.entity.User;
import com.qf.service.UserService;
import org.springframework.stereotype.Service;import javax.annotation.Resource;
import java.util.List;
import java.util.Set;@Service
public class UserServiceImpl implements UserService {@Resourceprivate UserDao userDao;@Overridepublic User selectUserByUsername(String username) {User user = userDao.selectUserAndRolesAndPerminssion(username);return user;}@Overridepublic Set<String> selectRolesByUsername(String username) {//根据用户名查询 角色信息Set<String> roles = userDao.selectRolesByUsername(username);return roles;}@Overridepublic Set<String> selectPermissionsByRoles(Set<String> roles) {//根据角色查权限信息Set<String> permissions = userDao.selectPermissionsByRoles(roles);return permissions;}
}

dao层的接口:

package com.qf.dao;import com.qf.entity.User;
import org.springframework.stereotype.Component;import java.util.List;
import java.util.Map;
import java.util.Set;
@Component
public interface UserDao {
public User  selectUserAndRolesAndPerminssion(String username);//根据用户名查询用户Set<String> selectRolesByUsername(String username);//根据用户名查询角色Set<String> selectPermissionsByRoles(Set<String> roles);//根据用户角色查询权限
}

步骤八:在resouces文件夹下创建mapper文件夹,用于写dao层对应的sql语句

在mapper文件夹下创建本次案例dao层对应的sql语句的xml文件:userMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qf.dao.UserDao"><resultMap id="BaseResultMap" type="com.qf.entity.User"><id column="uid" jdbcType="INTEGER" property="uid" /><result column="username" jdbcType="VARCHAR" property="username" /><result column="PASSWORD" jdbcType="VARCHAR" property="password" /><result column="nickname" jdbcType="VARCHAR" property="nickname" /></resultMap><resultMap id="selectUserAndRolesAndPerminssion" type="com.qf.entity.User"><id column="uid" jdbcType="INTEGER" property="uid" /><result column="username" jdbcType="VARCHAR" property="username" /><result column="PASSWORD" jdbcType="VARCHAR" property="password" /><result column="nickname" jdbcType="VARCHAR" property="nickname" /><collection property="roles" ofType="com.qf.entity.Role"><id column="rid" jdbcType="INTEGER" property="rid" /><result column="rname" jdbcType="VARCHAR" property="rname" /><result column="rinfo" jdbcType="VARCHAR" property="rinfo" /><collection property="permissions" ofType="com.qf.entity.Permission"><id column="pid" jdbcType="INTEGER" property="pid" /><result column="pname" jdbcType="VARCHAR" property="pname" /><result column="paction" jdbcType="VARCHAR" property="paction" /><result column="pinfo" jdbcType="VARCHAR" property="pinfo" /></collection></collection></resultMap><select id="selectUserAndRolesAndPerminssion" resultMap="selectUserAndRolesAndPerminssion">SELECT u.*,r.*,p.* FROM user u JOIN  user_role ur ON u.uid=ur.uidJOIN  role r ON ur.rid=r.ridJOIN role_permission rp on  rp.rid=r.ridJOIN permission p on rp.pid=p.pidWHERE  u.username=#{username}</select><select id="selectUserByUsername" resultMap="selectUserAndRolesAndPerminssion">SELECT u.*,r.*,p.* FROM user u JOIN  user_role ur ON u.uid=ur.uidJOIN  role r ON ur.rid=r.ridJOIN role_permission rp on  rp.rid=r.ridJOIN permission p on rp.pid=p.pidWHERE  u.username=#{username}</select><!--因为返回的结果类型为String类型,因此 resultMap="String"--><select id="selectRolesByUsername" resultType="java.lang.String" >SELECT r.rname from USER u JOIN  user_role ur on u.uid =ur.uidJOIN role r ON ur.rid=r.ridWHERE  u.username=#{username}</select><select id="selectPermissionsByRoles" resultType="java.lang.String" >SELECT p.pname FROM  role r join role_permission rp on r.rid = rp.ridjoin permission p on rp.pid = p.pidwhere  r.rname in<foreach collection="collection" open="("  close=")" separator="," item="rname">#{rname}</foreach></select></mapper>

步骤九:在webapp下定义本次案例用到的ftl模板文件

第一个ftl文件:login.ftl

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=9; IE=8; IE=7; IE=EDGE"/><title>商城展示登陆页面</title><link rel="stylesheet" href="/css/index.css" type="text/css"/><link href="/css/layui.css" rel="stylesheet" type="text/css"/><script src="/js/common/jquery-1.8.3.js" type="text/javascript"></script><script src="/js/layui.js" type="text/javascript"></script><style type="text/css">html,body{height: 100%;width: 100%;}</style></head>
<body><div class="container" style="height: 100%"><center><form class="layui-form" action="/user/login"  method="post" lay-filter="example" style="padding-top: 12%"><div class="layui-form-item"><label class="layui-form-label layui-col-sm-offset4 layui-col-sm1" >账号:</label><div class="layui-input-block  layui-col-sm4" ><input type="text" name="username" lay-verify="title" autocomplete="off" placeholder="请输入账号!" class="layui-input"></div></div><div class="layui-form-item"><label class="layui-form-label layui-col-sm-offset3 layui-col-sm1">密码:</label><div class="layui-input-block layui-col-sm4"><input type="password" name="password" placeholder="请输入密码!" autocomplete="off" class="layui-input"></div></div><div class="layui-form-item"><div class="layui-input-block"><button type="button" class="layui-btn layui-btn-normal" id="LAY-component-form-getval">注册</button><button type="submit" class="layui-btn" lay-submit="" lay-filter="demo1">登陆</button></div></div></form><font color="red" size="5">${msg!"欢迎登陆!"}</font></center>
</body></html>

第二个ftl模板文件:home.ftl

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=9; IE=8; IE=7; IE=EDGE"/><title>大众点评后台管理</title><link rel="stylesheet" href="/css/index.css" type="text/css"/><link href="/css/layui.css" rel="stylesheet" type="text/css"/><script src="/js/common/jquery-1.8.3.js" type="text/javascript"></script><script src="/js/layui.js" type="text/javascript"></script><style type="text/css">html,body{height: 100%;width: 100%;}</style></head>
<body><div class="container" style="height: 100%"><div id="head" class="layui-bg-blue" style="height: 7%"><ul class="layui-nav"><div style="float: right;"><li class="layui-nav-item"><a href="">控制台<span class="layui-badge">9</span></a></li><li class="layui-nav-item"><a href="">个人中心<span class="layui-badge-dot"></span></a></li><li class="layui-nav-item"><a href=""><img src="http://www.baidu.com/img/bd_logo.png" class="layui-nav-img">${user.nickname}</a><dl class="layui-nav-child"><dd><a href="/user/logout">退出登陆</a></dd></dl></li></div></ul></div><div id="content" style="height: 93%;"><div id="left" class="layui-col-md1" style="height: 100%"><ul class="layui-nav layui-nav-tree " lay-filter="test" style="height: 100%;width: 100%;"><!-- 侧边导航: <ul class="layui-nav layui-nav-tree layui-nav-side"> --><#list  user.roles as role><li class="layui-nav-item" ><a href="javascript:;">${role.rname}</a><dl class="layui-nav-child"><#list role.permissions as permission><#--role.permissions此地mapper文件没映射好导致此处为空,页面不出效果,疯狂报错--><dd><a data="${permission.paction}" href="${permission.paction}" onclick="navchick(this)">${permission.pname}</a></dd></#list></dl></li></#list><#--<#list user.roles as role>--><#--<li class="layui-nav-item" >--><#--<a href="javascript:;">${role.rname}</a>--><#--<dl class="layui-nav-child">--><#--<#list role.permissions as permission>--><#--<dd><a data="${permission.paction}" href="${permission.paction}" >${permission.pname}</a></dd>--><#--</#list>--><#--</dl>--><#--</li>--><#--</#list>--></ul></div><div id="right" class="layui-col-md11" style="height: 100%"><div class="layui-tab" lay-allowClose="true" lay-filter="test1" style="height: 7%"><ul class="layui-tab-title"><!-- 显示的tab的--><!-- <li class="layui-this" lay-id="111" >文章列表</li> --></ul><div class="layui-tab-content" style="height: 93%"></div></div></div></div></div></body>
<script>var element;layui.use('element', function(){//element操作导航条element = layui.element;});/*点击左侧导航条进行切换!item中data属性包含对应要跳转的路径!添加右侧对应的切换tab!并且添加添加显示内容对应的iframe!添加之前先要进行判断是否存在,tab id使用data属性设置!如果存在tabchange如果不存在!添加!并显示状态class="layui-this"*/function navchick(item) {// 就是路径  tab datavar data =  $(item).attr('data');  //获取的data属性//展示var text =  $(item).text();  //获取文本内容//查看data作为id是否出现 如果出现就切换  没有出现就添加//横着的列表var titleli_list = $(".layui-tab-title li");var exist = false;  //默认不存在titleli_list.each(function(){var temp = $(this).attr("lay-id");if (temp == data) {exist = true;return false;}});console.log(exist)if(exist){//如果存在,切换到对应位置即可//存在 切换//切换//c参数1 : lay-filter//参数2: tab的id}else{var iframe_id = 'i'+data;   //idvar iframe_src = data;//src内容//如果不存在,创建内容内别换显示//创建并切换element.tabAdd('test1',{title:text,id:data,content:"<iframe id='+' src='-' frameborder=\"0\" height=\"100%\" width=\"100%\"></iframe>".replace('+',iframe_id).replace('-',iframe_src)});}element.tabChange("test1",data);}</script>
</html>

第三个ftl模板文件:403.ftl

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=9; IE=8; IE=7; IE=EDGE"/><title>商城展示403</title><link rel="stylesheet" href="/css/index.css" type="text/css"/><link href="/css/layui.css" rel="stylesheet" type="text/css"/><script src="/js/common/jquery-1.8.3.js" type="text/javascript"></script><script src="/js/layui.js" type="text/javascript"></script><style type="text/css">html,body{height: 100%;width: 100%;}</style></head>
<body><div class="container" style="height: 100%"><center><h1>您没有权限!</h1></center>
</body>
</html>

第四个ftl模板文件:show.ftl

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=9; IE=8; IE=7; IE=EDGE"/><title>商城展示</title><link rel="stylesheet" href="/css/index.css" type="text/css"/><link href="/css/layui.css" rel="stylesheet" type="text/css"/><script src="/js/common/jquery-1.8.3.js" type="text/javascript"></script><script src="/js/layui.js" type="text/javascript"></script><style type="text/css">html,body{height: 100%;width: 100%;}</style></head>
<body><div class="container" style="height: 100%"><center><h1>展示页面!</h1></center>
</div>
</body>
</html>

第五个ftl模板文件:add.ftl

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=9; IE=8; IE=7; IE=EDGE"/><title>商城展示403</title><link rel="stylesheet" href="/css/index.css" type="text/css"/><link href="/css/layui.css" rel="stylesheet" type="text/css"/><script src="/js/common/jquery-1.8.3.js" type="text/javascript"></script><script src="/js/layui.js" type="text/javascript"></script><style type="text/css">html,body{height: 100%;width: 100%;}</style></head>
<body><div class="container" style="height: 100%"><center><h1>添加页面</h1></center>
</div>
</body>
</html>


案例结构图:

本次案例用到的数据库:shiroweb

/*
SQLyog Ultimate v12.09 (64 bit)
MySQL - 5.5.40 : Database - shiroweb
*********************************************************************
*//*!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*/`shiroweb` /*!40100 DEFAULT CHARACTER SET utf8 */;USE `shiroweb`;/*Table structure for table `permission` */DROP TABLE IF EXISTS `permission`;CREATE TABLE `permission` (`pid` int(11) NOT NULL AUTO_INCREMENT COMMENT '权限主键',`pname` varchar(20) NOT NULL COMMENT '权限的名称',`paction` varchar(100) NOT NULL COMMENT '权限的路径',`pinfo` varchar(200) DEFAULT NULL COMMENT '权限的描述',PRIMARY KEY (`pid`),UNIQUE KEY `pname` (`pname`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;/*Data for the table `permission` */insert  into `permission`(`pid`,`pname`,`paction`,`pinfo`) values (1,'商品添加','/productftl/add','aaa'),(2,'商品展示','/product/ftl/show','商品展示功能,认证用户随便访问');/*Table structure for table `product` */DROP TABLE IF EXISTS `product`;CREATE TABLE `product` (`pid` varchar(96) DEFAULT NULL,`pname` varchar(150) DEFAULT NULL,`market_price` double DEFAULT NULL,`shop_price` double DEFAULT NULL,`pimage` varchar(600) DEFAULT NULL,`pdate` date DEFAULT NULL,`pdesc` varchar(765) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;/*Data for the table `product` */insert  into `product`(`pid`,`pname`,`market_price`,`shop_price`,`pimage`,`pdate`,`pdesc`) values ('51','小米 4c 标准版',1399,1299,'products/1/c_0001.jpg','2015-11-02','小米 4c 标准版 全网通 白色 移动联通电信4G手机 双卡双待'),('10','华为 Ascend Mate7',2699,2599,'products/1/c_0010.jpg','2015-11-02','华为 Ascend Mate7 月光银 移动4G手机 双卡双待双通6英寸高清大屏,纤薄机身,智能超八核,按压式指纹识别!!选择下方“移动老用户4G飞享合约”,无需换号,还有话费每月返还!'),('51','小米 4c 标准版',1399,1299,'products/1/c_0001.jpg','2015-11-02','小米 4c 标准版 全网通 白色 移动联通电信4G手机 双卡双待'),('17','华为 Ascend Mate7',2699,2599,'products/1/c_0010.jpg','2015-11-02','华为 Ascend Mate7 月光银 移动4G手机 双卡双待双通6英寸高清大屏,纤薄机身,智能超八核,按压式指纹识别!!选择下方“移动老用户4G飞享合约”,无需换号,还有话费每月返还!'),('18','vivo X5Pro',2399,2298,'products/1/c_0014.jpg','2015-11-02','移动联通双4G手机 3G运存版 极光白【购机送蓝牙耳机+蓝牙自拍杆】新升级3G运行内存·双2.5D弧面玻璃·眼球识别技术'),('19','努比亚(nubia)My 布拉格',1899,1799,'products/1/c_0013.jpg','2015-11-02','努比亚(nubia)My 布拉格 银白 移动联通4G手机 双卡双待【嗨11,下单立减100】金属机身,快速充电!布拉格相机全新体验!'),('27','华为 麦芒4',2599,2499,'products/1/c_0012.jpg','2015-11-02','华为 麦芒4 晨曦金 全网通版4G手机 双卡双待金属机身 2.5D弧面屏 指纹解锁 光学防抖'),('28','vivo X5M',1899,1799,'products/1/c_0011.jpg','2015-11-02','vivo X5M 移动4G手机 双卡双待 香槟金【购机送蓝牙耳机+蓝牙自拍杆】5.0英寸大屏显示·八核双卡双待·Hi-Fi移动KTV'),('29','Apple iPhone 6 (A1586)',4399,4288,'products/1/c_0015.jpg','2015-11-02','Apple iPhone 6 (A1586) 16GB 金色 移动联通电信4G手机长期省才是真的省!点击购机送费版,月月送话费,月月享优惠,畅享4G网络,就在联通4G!'),('51','小米 4c 标准版',1399,1299,'products/1/c_0001.jpg','2015-11-02','小米 4c 标准版 全网通 白色 移动联通电信4G手机 双卡双待'),('17','华为 Ascend Mate7',2699,2599,'products/1/c_0010.jpg','2015-11-02','华为 Ascend Mate7 月光银 移动4G手机 双卡双待双通6英寸高清大屏,纤薄机身,智能超八核,按压式指纹识别!!选择下方“移动老用户4G飞享合约”,无需换号,还有话费每月返还!'),('32','vivo X5Pro',2399,2298,'products/1/c_0014.jpg','2015-11-02','移动联通双4G手机 3G运存版 极光白【购机送蓝牙耳机+蓝牙自拍杆】新升级3G运行内存·双2.5D弧面玻璃·眼球识别技术'),('33','努比亚(nubia)My 布拉格',1899,1799,'products/1/c_0013.jpg','2015-11-02','努比亚(nubia)My 布拉格 银白 移动联通4G手机 双卡双待【嗨11,下单立减100】金属机身,快速充电!布拉格相机全新体验!'),('34','华为 麦芒4',2599,2499,'products/1/c_0012.jpg','2015-11-02','华为 麦芒4 晨曦金 全网通版4G手机 双卡双待金属机身 2.5D弧面屏 指纹解锁 光学防抖'),('35','vivo X5M',1899,1799,'products/1/c_0011.jpg','2015-11-02','vivo X5M 移动4G手机 双卡双待 香槟金【购机送蓝牙耳机+蓝牙自拍杆】5.0英寸大屏显示·八核双卡双待·Hi-Fi移动KTV'),('36','Apple iPhone 6 (A1586)',4399,4288,'products/1/c_0015.jpg','2015-11-02','Apple iPhone 6 (A1586) 16GB 金色 移动联通电信4G手机长期省才是真的省!点击购机送费版,月月送话费,月月享优惠,畅享4G网络,就在联通4G!'),('51','小米 4c 标准版',1399,1299,'products/1/c_0001.jpg','2015-11-02','小米 4c 标准版 全网通 白色 移动联通电信4G手机 双卡双待'),('17','华为 Ascend Mate7',2699,2599,'products/1/c_0010.jpg','2015-11-02','华为 Ascend Mate7 月光银 移动4G手机 双卡双待双通6英寸高清大屏,纤薄机身,智能超八核,按压式指纹识别!!选择下方“移动老用户4G飞享合约”,无需换号,还有话费每月返还!'),('45','vivo X5Pro',2399,2298,'products/1/c_0014.jpg','2015-11-02','移动联通双4G手机 3G运存版 极光白【购机送蓝牙耳机+蓝牙自拍杆】新升级3G运行内存·双2.5D弧面玻璃·眼球识别技术'),('40','努比亚(nubia)My 布拉格',1899,1799,'products/1/c_0013.jpg','2015-11-02','努比亚(nubia)My 布拉格 银白 移动联通4G手机 双卡双待【嗨11,下单立减100】金属机身,快速充电!布拉格相机全新体验!'),('41','华为 麦芒4',2599,2499,'products/1/c_0012.jpg','2015-11-02','华为 麦芒4 晨曦金 全网通版4G手机 双卡双待金属机身 2.5D弧面屏 指纹解锁 光学防抖'),('42','vivo X5M',1899,1799,'products/1/c_0011.jpg','2015-11-02','vivo X5M 移动4G手机 双卡双待 香槟金【购机送蓝牙耳机+蓝牙自拍杆】5.0英寸大屏显示·八核双卡双待·Hi-Fi移动KTV'),('43','Apple iPhone 6 (A1586)',8888,4288,'products/1/c_0015.jpg','2015-11-02','Apple iPhone 6 (A1586) 16GB 金色 移动联通电信4G手机长期省才是真的省!点击购机送费版,月月送话费,月月享优惠,畅享4G网络,就在联通4G!'),('51','小米 4c 标准版',1399,1299,'products/1/c_0001.jpg','2015-11-02','小米 4c 标准版 全网通 白色 移动联通电信4G手机 双卡双待'),('17','华为 Ascend Mate7',2699,2599,'products/1/c_0010.jpg','2015-11-02','华为 Ascend Mate7 月光银 移动4G手机 双卡双待双通6英寸高清大屏,纤薄机身,智能超八核,按压式指纹识别!!选择下方“移动老用户4G飞享合约”,无需换号,还有话费每月返还!'),('46','vivo X5Pro',2399,2298,'products/1/c_0014.jpg','2015-11-02','移动联通双4G手机 3G运存版 极光白【购机送蓝牙耳机+蓝牙自拍杆】新升级3G运行内存·双2.5D弧面玻璃·眼球识别技术'),('47','努比亚(nubia)My 布拉格',1899,1799,'products/1/c_0013.jpg','2015-11-02','努比亚(nubia)My 布拉格 银白 移动联通4G手机 双卡双待【嗨11,下单立减100】金属机身,快速充电!布拉格相机全新体验!'),('48','华为 麦芒4',2599,2499,'products/1/c_0012.jpg','2015-11-02','华为 麦芒4 晨曦金 全网通版4G手机 双卡双待金属机身 2.5D弧面屏 指纹解锁 光学防抖'),('49','vivo X5M',1899,1799,'products/1/c_0011.jpg','2015-11-02','vivo X5M 移动4G手机 双卡双待 香槟金【购机送蓝牙耳机+蓝牙自拍杆】5.0英寸大屏显示·八核双卡双待·Hi-Fi移动KTV'),('50','Apple iPhone 6 (A1586)',4399,4288,'products/1/c_0015.jpg','2015-11-02','Apple iPhone 6 (A1586) 16GB 金色 移动联通电信4G手机长期省才是真的省!点击购机送费版,月月送话费,月月享优惠,畅享4G网络,就在联通4G!'),('51','小米 4c 标准版',1399,1299,'products/1/c_0001.jpg','2015-11-02','小米 4c 标准版 全网通 白色 移动联通电信4G手机 双卡双待'),('17','华为 Ascend Mate7',2699,2599,'products/1/c_0010.jpg','2015-11-02','华为 Ascend Mate7 月光银 移动4G手机 双卡双待双通6英寸高清大屏,纤薄机身,智能超八核,按压式指纹识别!!选择下方“移动老用户4G飞享合约”,无需换号,还有话费每月返还!');/*Table structure for table `role` */DROP TABLE IF EXISTS `role`;CREATE TABLE `role` (`rid` int(11) NOT NULL AUTO_INCREMENT COMMENT '角色的主键',`rname` varchar(20) NOT NULL COMMENT '角色名称',`rinfo` varchar(100) DEFAULT NULL COMMENT '角色的描述',PRIMARY KEY (`rid`),UNIQUE KEY `rname` (`rname`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;/*Data for the table `role` */insert  into `role`(`rid`,`rname`,`rinfo`) values (1,'用户','一个管理员'),(2,'管理员','哈哈'),(4,'超级管理员','有所有权限');/*Table structure for table `role_permission` */DROP TABLE IF EXISTS `role_permission`;CREATE TABLE `role_permission` (`rp_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '角色和权限表的主键',`rid` int(11) DEFAULT NULL COMMENT '角色表主键',`pid` int(11) DEFAULT NULL COMMENT '权限表主键',PRIMARY KEY (`rp_id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;/*Data for the table `role_permission` */insert  into `role_permission`(`rp_id`,`rid`,`pid`) values (1,1,2),(2,2,1),(3,2,2);/*Table structure for table `user` */DROP TABLE IF EXISTS `user`;CREATE TABLE `user` (`uid` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户的主键',`username` varchar(30) NOT NULL COMMENT '用户账号',`PASSWORD` varchar(200) NOT NULL COMMENT '用户密码',`nickname` varchar(20) DEFAULT '二狗子' COMMENT '用户昵称',PRIMARY KEY (`uid`),UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;/*Data for the table `user` */insert  into `user`(`uid`,`username`,`PASSWORD`,`nickname`) values (1,'customer','1111','二狗子'),(2,'admin','1111','二狗子');/*Table structure for table `user_role` */DROP TABLE IF EXISTS `user_role`;CREATE TABLE `user_role` (`ur_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户和角色的中间表主键',`uid` int(11) DEFAULT NULL COMMENT '用户的id',`rid` int(11) DEFAULT NULL COMMENT '角色的id',PRIMARY KEY (`ur_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;/*Data for the table `user_role` */insert  into `user_role`(`ur_id`,`uid`,`rid`) values (1,1,1),(2,2,2);/*!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 */;

ssm+shiro+freemarker。关键字:ftl。(作为了解即可,主要了解ssm+shiro+jsp标签这篇笔记)相关推荐

  1. ssm+shiro+jsp标签。关键字:shiro的jsp标签,访问拦截。本次ssm和以前的ssm整合中的依赖包不一样。写根据不同用户出现不同的按钮内容就用这shiro标签来解决。Set集合在sql中

    shiro标签只能在jsp和ftl页面文件中使用,无法在html文件中使用 shiro认证后的在jsp页面中的标签: 使用shiro标签就一定要搭配shiro框架使用,即一定要有自定义realm,因为 ...

  2. freemarker ftl java_通过springframework的mvc返回freemarker的ftl文件ModelAndView模板内容代码示例...

    一.前言 这边基于springframework的mvc框架,并通过freemarker的ftl视图渲染文件返回数据,在spring文件中配置对应org.springframework.web.ser ...

  3. 安全框架 - Shiro与springMVC整合的注解以及JSP标签

    Shiro想必大家都知道了,之前的文章我也有提过,是目前使用率要比spring security都要多的一个权限框架,本身spring自己都在用shiro,之前的文章有兴趣可以去扒一下 最近正好用到s ...

  4. Shiro教程(九)Shiro JSP标签的使用。

    Shiro  提供了 JSP  的一套 JSTL  标签,用于做 JSP  页面做权限控制的.可以控制一些按钮和一些超链接,或者一些显示内容. Freemarker Shiro标签讲解:https:/ ...

  5. Shiro集成Web时的Shiro JSP标签

    场景 从实例入手学习Shiro与Web的整合: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/90140802 在上面已经实现整合 ...

  6. Shiro JSP 标签

    Shiro JSP 标签 由 北公爵无欢 创建, 最后一次修改 2016-08-12 21:19:51 JSP 标签 Shiro 提供了 JSTL 标签用于在 JSP/GSP 页面进行权限控制,如根据 ...

  7. shiro学习--jsp标签

    在页面上,如果要实现对某些文本.按钮等的控制,例如需要有什么角色或者权限才可以看见这个按钮,利用shiro自带的shiro标签能很容易就实现 一.引入shiro标签库 首先得在jsp页面的头部引入EL ...

  8. SSM通用活动报名系统(会员、管理员)+SSM框架+mysql+tomcat+Maven项目(毕设学习)可以用于学习SSM、maven项目入门

    SSM通用活动报名系统(会员.管理员)+SSM框架+mysql+tomcat+Maven项目(毕设学习)可以用于学习SSM.maven项目入门 可以用于课程设计.毕业设计的知识点入门学习 提示:此资源 ...

  9. freemarker(FTL)常见语法大全

    FreeMarker的插值有如下两种类型: 1,通用插值${expr}; 2,数字格式化插值:#{expr}或#{expr;format}  通用插值: ${book.name?if_exists } ...

最新文章

  1. java -jar 未响应_Java 方法性能监控和统计工具 MyPerf4J
  2. PHP中绘制图像的一些函数总结
  3. python中输入17=x会引起错误_python新手常犯的17个错误
  4. 调试实战 | 通过转储文件分析程序无响应之使用 windbg + IDA 逆向篇
  5. centos7编译 openjdk8
  6. mysql的数据备份问题_mysql数据库备份的问题
  7. Hadoop2.4.1(QJM HA)+HBASE0.98 双MASTER问题分析
  8. linux bttrack服务,给centos7上的aria2添加BT Tracker服务器
  9. 闰年2月29号 通过apache的ftp工具从ftp上下载文件失败
  10. 如何设置变更Word页面颜色?干货经验!怎样操作更改word背景颜色?
  11. 水下光通信实现(1)----LED驱动电路
  12. 分享 百度网盘,不用开会员也可以免费同步上传视频和照片的方法
  13. thinkphp3.2读取Excel文件
  14. 注册验证码短信收不到是怎么回事
  15. idea安装zookeeper(zoolytic)可视化管理插件
  16. 计算机使用鼠标的课件,鼠标的基本操作ppt课件.ppt
  17. 判断当前手机设备的类型(安卓还是IOS)
  18. GO 语言中模板渲染的原理
  19. MapReduce中的自定义多目录/文件名输出HDFS
  20. 免杀veil的简单使用

热门文章

  1. 农村电商的市场规模以及未来发展趋势
  2. SEOer淘宝电商网站店铺优化使用的神奇工具
  3. 慧家生活技术服务支持
  4. 主流手机参数(不定期更新)
  5. 人工智能项目实战-使用OMR完成答题卡识别判卷
  6. 支付宝放大招 钻石会员免费提现额度达100万 | 附快速升级攻略
  7. SpringMVC——配置tomcat
  8. 银联无感支付自动缴费不停车快速离场
  9. 四六级英语学习(一)医疗健康类
  10. 7种实用的分布式框架