最近几天,在shiro进行系统权限控制。在处理JSP页面的时候,遇到几个问题,纠结好几天,终于成功解决这些问题。
1、使用<shiro:principal>的时候,如何得到整个类的信息?
由于之前,在编写Realm的时候,习惯性的把用户登录名放进SimpleAuthenticationInfo类中,进行返回。当然了,使用<shiro:principal>的时候,就只能得到用户的登录名。其实,使用<shiro:principal>,效果和SecurityUtils.getSubject().getPrincipal()一致。
后面,修改代码,在返回SimpleAuthenticationInfo的时候,传递进整个User类对象。然后,就能够得到整个登录用户的全部信息。
代码:
@Override protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken token) throws AuthenticationException { String userName = (String)token.getPrincipal(); User user = userDao.searchPasswordThroughLoginName(userName); if(user == null) { throw new UnknownAccountException("登录名" + userName + "不存在!"); } SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getU_password(), getName()); info.setCredentialsSalt(ByteSource.Util.bytes(user.getU_salt())); return info; }
2、User对象中还有其他的类对象,在jsp页面中,如何通过<shiro:principal>得到相关信息?
public class User { private String u_id; //用户登录时所需信息 private String u_loginName; private String u_password; private String u_salt; //个人信息 private String u_name; private Date u_bornDate; private String u_sex; private String u_phone; private String u_email; private CompanyDepartment u_cd; private CompanyPosition u_cp; //省略getter和setter方法 }
<shiro:principal>中,含有一个property的属性。对于类似于u_id、u_loginName等信息可以通过<shiro:principal property="u_id"/>的形式,来获取该属性的值。那么,类似于CompanyDepartment类,如果想要获取该类中的cd_id,能不能通过<shiro:principal property="u_cd.cd_id"/>形式,获取得到User类下的CompanyDepartment类的cd_id属性的值呢?
答案是不可以的。因为系统报错,提示在User类中,找不到u_cd.id的属性。那么,c_id、c_loginName等信息如何能够通过<shiro:principal property="xxx"/>形式获取得到?其实,就是根据,User类中相关的getter方法取出相应的值。那么,只需要提供一个对应的get方法就可以实现这个目的。
public String getCdId() { return this.u_cd.getCd_id(); }
然后,使用<shiro:principal property="cdId"/>,就能够获取User类下的CompanyDepartment类的cd_id属性的值。(方法名的命名规范,最好遵循JavaBean的命名规范。)
3、使用<shiro:principal property="cdId"/>进行判断的时候,系统提示EL表达式语法错误,如何解决?
通过第二步,能够成功获取User中相关属性的值,那么,如果在User类中添加一个u_type属性,用于对用户类型进行判断,使用下面的jsp代码进行判断:
<c:if test="${<shiro:principal property="u_type"/> == ‘master‘ }"> </c:if>
系统报错,提出出现EL表达式语法错误。但是<shiro:principal property="u_type"/>能够拿出User类中的u_type属性的值。在这个过程中,纠结了很长时间,也没有解决这个问题。最后,退一步,加上这个判断,仅仅是为了判断登录用户的类型。那么,这个类型,可以在控制层中取出,并传回到前端JSP页面中,然后进行判断,就可以绕开这个问题。
@RequestMapping(value="login" , method=RequestMethod.GET) public String login(@ModelAttribute("user")User user , Model model) { /* * 如果当前用户已经登录,则不需要直接再次进行登录操作 */ User loginUser = ShiroUtils.getLoginUser(); if(loginUser != null) { String type = ((User)SecurityUtils.getSubject().getPrincipal()).getU_type(); model.addAttribute("userType", "master".equals(type) || "dupty".equals(type)); return "sys/systemLogin/index"; } return "sys/systemLogin/login"; }
然后在jsp页面处:
<c:if test="${userType == true }"> </c:if>
就能够成功实现类型判断。
好了,上面就是最近几天遇到的一些问题,纠结了好几天,才解决这些问题。如果各位大侠有更改的解决办法,请不吝赐教。