你的位置:首页 > Java教程

[Java教程]构建 shiro struts2 spring3 mybatis 的maven项目


书接上回 构建 struts2 spring3 mybatis 的maven项目 构建 pom.  

继续在原有框架下 融合shiro ,具体shiro是啥 这里就不解释了,恩 反正功能挺强大的

本着先会用再深入的原则,还是尝试着将shiro融入框架中

 

0 首先上下这个项目的整体结构图


 

 这里需要就是下 filterChainDefinitions 的value

  key 是 对应的跳转路径 这里都是指定的struts2的跳转 可以匹配通配符 *

  value 是对应的过滤权限 

    anon 不需要验证

    authc 需要登录验证

    roles[aa] 角色验证 中括号内为指定的角色

    perms[aaa] 权限验证 中括号内卫指定的权限

 

4 添加shiro的缓存配置文件

<ehcache>  <diskStore path="java.io.tmpdir/shiro-spring-sample"/>  <defaultCache      maxElementsInMemory="10000"      eternal="false"      timeToIdleSeconds="120"      timeToLiveSeconds="120"      overflowToDisk="false"      diskPersistent="false"      diskExpiryThreadIntervalSeconds="120"      />  <cache name="shiro-activeSessionCache"      maxElementsInMemory="10000"      eternal="true"      overflowToDisk="true"      diskPersistent="true"      diskExpiryThreadIntervalSeconds="600"/>  <cache name="org.apache.shiro.realm.SimpleAccountRealm.authorization"      maxElementsInMemory="100"      eternal="false"      timeToLiveSeconds="600"      overflowToDisk="false"/></ehcache>

View Code

 

5 角色 权限 实现

因为只是一个demo  所以就没有弄角色表和权限表  只是模拟了一下 用户--角色--权限 的5表结构

 用户是查的表 角色和权限只是假实现

6 修改 struts.

<struts>  <!-- 全局包设置 -->  <package name="defalutGlobal" namespace="/" extends="json-default">  </package>  <!-- 自定义开发包 -->  <package name="myDefault" extends="defalutGlobal">    <!--登录Action -->    <action name="login_*" class="loginAction" method="{1}" >      <result name="loginPage">WEB-INF/pages/login.html</result>      <result name="loginPageForm">WEB-INF/pages/login2.html</result>      <result name="home">WEB-INF/pages/home.html</result>      <result name="hello">WEB-INF/pages/hello.html</result>            <result name="success" type="json">        <param name="root">jsonResult</param>      </result>          </action>    <action name="other_*" class="otherAction" method="{1}">      <result name="error">WEB-INF/pages/other/error.html</result>    </action>  </package>        <package name="t1" extends="defalutGlobal" namespace="/t1">    <action name="t1_*" class="test1Action" method="{1}">      <result name="t1">/WEB-INF/pages/t1/t1.html</result>      <result name="t2">/WEB-INF/pages/t1/t2.html</result>      <result name="t3">/WEB-INF/pages/t1/t3.html</result>      <result name="toT2" type="redirect" >/t2/t2_t2.do</result>          </action>  </package>    <package name="t2" extends="defalutGlobal" namespace="/t2">      <action name="t2_*" class="test2Action" method="{1}">      <result name="t1">/WEB-INF/pages/t2/t1.html</result>      <result name="t2">/WEB-INF/pages/t2/t2.html</result>      <result name="t3">/WEB-INF/pages/t2/t3.html</result>    </action>  </package>    <package name="t3" extends="defalutGlobal" namespace="/t3">      <action name="t3_*" class="test3Action" method="{1}">      <result name="t1">/WEB-INF/pages/t3/t1.html</result>      <result name="t2">/WEB-INF/pages/t3/t2.html</result>      <result name="t3">/WEB-INF/pages/t3/t3.html</result>    </action>  </package>  </struts>

这里为了更好地测试shiro的权限角色控制 所以把 t1,t2,t3加了namespace

 

7 添加html

这里就没啥说的了  给个缩略图吧

 

 

8 实现reaml

public class ShiroDbRealm extends AuthorizingRealm {  @Autowired  private UserService userService;  @Autowired  private RoleService roleService;  @Autowired  private PermissionService permissionService;    /**   * 认证回调函数,登录时调用.   */  @Override  protected AuthenticationInfo doGetAuthenticationInfo(      AuthenticationToken authcToken) throws AuthenticationException {    UsernamePasswordToken token = (UsernamePasswordToken) authcToken;    User user = userService.getByUserName(token.getUsername());    if (user != null) {      return new SimpleAuthenticationInfo(new ShiroUser(user.getUsername(), user.getNickname()), user.getPassword(),getName());    } else {      return null;    }  }  /**   * 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用.   */  @Override  protected AuthorizationInfo doGetAuthorizationInfo(      PrincipalCollection principals) {    ShiroUser shiroUser = (ShiroUser) principals.getPrimaryPrincipal();        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();    // 加载用户的roles    List<Role> roles = roleService.getByUserName(shiroUser.username);    List<String> stringRoles = new ArrayList<String>(roles.size());    for (Role role : roles) {      stringRoles.add(role.getRolename());    }    info.addRoles(stringRoles);        // 加载用户的permissions    List<Permission> permissions = permissionService.getByUserName(shiroUser.username);    Set<String> stringPermissions = new HashSet<String>(permissions.size());    for (Permission permission : permissions) {      stringPermissions.add(permission.getPermissionname());    }    info.setStringPermissions(stringPermissions);        return info;  }    /**   * 自定义Authentication对象,使得Subject除了携带用户的登录名外还可以携带更多信息.   */  public static class ShiroUser implements Serializable {    private static final long serialVersionUID = -1373760761780840081L;    private String username;    private String nickname;    public ShiroUser(String username, String nickname) {      this.username = username;      this.nickname = nickname;    }    /**------getset略--------*/  }}

 

 

9 action

public class LoginAction extends BaseAction{    private String username;  private String password;  @Autowired  UserService userService;    /**   * 登录页面   */  public String loginPage(){return "loginPage";  }      /**   * home页面   */  public String home(){    return "home";  }    /**   * hello页面   */  public String hello(){    System.out.println(SecurityUtils.getSubject().hasRole("cc"));    return "hello";  }      /**   * 登录   */  public String login(){    Map<String,Object> map = new HashMap<String,Object>();    User u=new User(getUsername(),getPassword());    u=userService.check(u);    if("0".equals(u.getRes())){      map.put("res", "true");         AuthenticationToken token = new UsernamePasswordToken(username,password);// username和password是从表单提交过来的      Subject currentUser = SecurityUtils.getSubject();      currentUser.login(token);          }else{      map.put("res", "false");    }    JSONObject json = JSONObject.fromObject(map);//将map对象转换成json类型数据    setJsonResult(json.toString());//给result赋值,传递给页面    return "success";  }    /**   * 登录页面   */  public String loginPageForm(){    String result="loginPageForm";    return result;  }  /**   * 登录   */  public String loginForm(){    System.out.println("loginForm");    String result="loginPageForm";    User u=new User(getUsername(),getPassword());    u=userService.check(u);        if("0".equals(u.getRes())){      AuthenticationToken token = new UsernamePasswordToken(username,password);// username和password是从表单提交过来的      Subject currentUser = SecurityUtils.getSubject();      currentUser.login(token);      result="home";    }        return result;  }      /**   * 登出   */  public String logout(){    Subject currentUser = SecurityUtils.getSubject();if (currentUser.isAuthenticated()) {      currentUser.logout(); // session 会销毁,在SessionListener监听session销毁,清理权限缓存      if (LOG.isDebugEnabled()) {        LOG.debug("用户" + username + "退出登录");      }    }return "loginPage";  }
  /**--------getset略----------*/
}

这里就只上LoginAction了 其他的action 只是实现的跳转没有啥实际操作 就略过了

如果先看其他action 就只能下源码了 

这里还要说一下 登录页面写了两个 一个是ajax的一个是form 没有啥特别的 只是为了之后学习shiro remberme功能 打个提前量

 

10 数据库结果

create table base_user(  id          int not null auto_increment,  createtime      char(20),  username        char(20),  password        char(20),  nickname        char(20),  t1          char(100),  t2          char(30),  primary key (id));

 

好 完成 测试下 成功

 

最后总结下

1 不得不吐槽下 网上的关于shiro的教程虽然不算少 但大都是 springMVC的 关于struts2的还是比较少的

2 文档还是官方的好  放一个中文的shiro参考手册 下载

3 本人研究shiro时间不长 这里只是作为一个入门参考 如果文中有错误的地方 尽情支出 欢迎技术喷子

4 下次打算把shiro的 rememberme等功能研究下 再写一篇

5 本项目 下载