用户和角色和资源的绑定问题

1 用户和角色和资源的绑定问题

1.1 用户绑定角色

1. 1. 1 页面

  • 点击绑定角色按钮,弹出角色列表
//弹出绑定资源的窗口
        $("#bindResBtn").click(function(){
            //判断只能选择一个
            var rows = $("#list").datagrid("getSelections");
            if(rows.length!=1){
                $.messager.alert("提示","只能绑定一个角色","warning");
                return;
            }

            //在window引入另一个页面
            var content = "";
            $("#bindResWin").window({
                content:content
            });

            //弹出窗口
            $("#bindResWin").window("open");
        });
  • 新建一个 bindRole.jsp
<%@ 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">
  <title>角色管理title>
  <script type="text/javascript" src="../../js/easyui/jquery.min.js">script>
  <link rel="stylesheet" type="text/css" href="../../js/easyui/themes/default/easyui.css">
  <link rel="stylesheet" type="text/css" href="../../js/easyui/themes/icon.css">
  <link rel="stylesheet" type="text/css" href="../../css/default.css">
  <script type="text/javascript" src="../../js/easyui/jquery.easyui.min.js">script>
  <script type="text/javascript" src="../../js/easyui/locale/easyui-lang-zh_CN.js">script>
  <script type="text/javascript" src="../../js/form.js">script>
  head>
  <body>
  
  <table id="list">table>

  
  <div id="toolbar">
    <a id="bindRoleBtn" href="#" class="easyui-linkbutton" data-options="iconCls:'icon-save'">绑定a>
  div>


  <script type="text/javascript">
    //当前模块的action
    var action = "role";

    //表格的列数据
    var columns = [ [ {
        field : "id",
        checkbox : true
    }, {
        field : "name",
        title : "角色名",
        width : 120,
        align : "center"
    }, {
        field : "keyword",
        title : "角色关键字",
        width : 120,
        align : "center"
    }, {
        field : "description",
        title : "备注",
        width : 120,
        align : "center"
    } ] ];

    //弹出绑定资源的窗口
    $("#list").datagrid({
        url:"../../"+action+"/listByPage.action",
        columns:columns,
        //显示分页
        pagination:true,
        //绑定工具条div
        toolbar:"#toolbar"
    });



    //绑定角色和资源
    $("#bindRoleBtn").click(function(){
        //1.需要 绑定角色ID(1个)
        var userId = "${param.userId}";

        //2.需要绑定资源ID(n个)
        var rows = $("#list").datagrid("getSelections");   
        var roleIdArray=new Array();
        $(rows).each(function(i){
            roleIdArray.push(rows[i].id);
        });
        var roleIds = roleIdArray.join(",");


        //把所有id传递到后台
        $.post("../../user/bindRoleToUser.action",{userId:userId,roleIds:roleIds},function(data){
            if(data.success){
                //需求:在子页面操作父页面:window.parent
                window.parent.$.messager.alert("提示","用户绑定角色成功","info");
                //关闭
                window.parent.$("#bindRoleWin").window("close");
            }else{
                $.messager.alert("提示","用户绑定角色失败"+data.msg,"error");
            }
        },"json");

    });
  script>
  body>
  html>

1. 1. 2 Action

private String validCode;
pubulic String getValidCode(){
    return validCode;
}
public void setValidCode(String validCode ){
    this.validCode=validCode;
}
@Action("login")
public void login(){
    User user = this.getModel();
    //从session中取出生成的验证码
    String key= ActionContext.getContext.getSession.get0("key");
    if(! key.equals(validCode)){
        result.put("success",false);
        result.put("msg","验证码有误");
    }else {
        try{
            User loginUser = userService.login(user);
            //登录成功 
            result.put("success",true);
            //把登录信息放入session域
            ActionContext.getContext.getSession.put("user",loginUser);
        } catch (UnknownUserException e){
            //用户名不存在
            result.put("success",false);
            result.put("msg","用户名不存在");
        }catch ( IncorrectPasswordException e){
            result.put("success",false);
            result.put("msg","密码错误");
        }catch (Exception e){
            result.put("success",false);
            result.put("msg",e.getMessage);
        }
    }
    writeJson(result);
}

1. 1. 3 Service

1. 1. 3. 1接口

  • UserService
USer login(User user)throws UnknownUserException, IncorrectPasswException;

1. 1. 3. 2 service实现类

//...
//注入UserDao
    @Autowired
    private UserDao userDao;

    //注入
    @Autowired
    private RoleDao roleDao;

    @Override
    public void bindRoleToUser(Long userId, String roleIds) {
        //1.获取一个需要绑定用户
        User user =userDao.findOne(userId);

        Setroles =new HashSet();
        if(StringUtils.isNoneBlank(roleIds)) {
            String[] roleIdArray =roleIds.split(",");
            for (String roleId : roleIdArray) {
                roles.add(  roleDao.findOne(Long.parseLong(roleId)) );
            }
        }
        //给用户绑定角色   
        user.setRoles(roles);
    }

1. 2 回显绑定过用户的角色列表

1. 2. 1 修改Role实体类

//添加一个临时属性checked,用于回显角色
    @Transient
    private Boolean checked=false;
    public Boolean getChecked() {
        return checked;
    }
    public void setChecked(Boolean checked) {
        this.checked = checked;
    }
  • 修改实体类后需要更改页面方法

1. 2. 2 修改 bindRole.jsp

//弹出绑定资源的窗口
        $("#list").datagrid({
            url:"../../"+action+"/listByPageAndChecked.action?userId=${param.userId}",
            columns:columns,
            //显示分页
            pagination:true,
            //绑定工具条div
            toolbar:"#toolbar" 
        });

1. 2. 3 RoleAction

//模型驱动接收用户的userId
    private String userId;
    public String getUserId() {
        return userId;
    }
    public void setUserId(String userId) {
        this.userId = userId;
    }
    /**
     * 角色列表,带回显功能
     * @throws IOException 
     */
    @Action("listByPageAndChecked")
    public void listByPageAndChecked() throws Exception {
        // 1.封装Pageable对象
        Pageable pageable = new PageRequest(this.getPage() - 1, this.getRows());

        Specification spec = buildSpecification();

        // 2.分页查询
        Page pageBean = roleService.findAll(spec, pageable,Long.parseLong(userId));

        // 3.取出结果
        // 3.1 当前页数据列表
        List content = pageBean.getContent();
        // 3.2 总记录数
        long total = pageBean.getTotalElements();

        // 4.放入数据给result
        result.put("total", total);
        result.put("rows", content);

        // 5.转换result为json字符串
        writeJson(result);

    }

1. 2. 4 角色业务层

1. 2. 4. 1 RoleService

Page findAll(Specification spec, Pageable pageable, Long userId);

1. 2. 4. 2 RoleServiceImpl

@Override
    public Page findAll(Specification spec, Pageable pageable, Long roleId) {
        PagePageBean = roleDao.findAll(spec,pageable);

        //查询该用户绑定过的角色
        User user = userDao.findOne(roleId);
        Set roles = user.getRoles();
        //把id封装成集合
        SetroleIdSet = new HashSet();
        for (Role role : roles) {
            roleIdSet.add(role.getId());
            System.out.println(role);
        }

        //遍历Role对象,修改Role的checked属性
        for(Role role :PageBean) {
            role.setChecked(roleIdSet.contains( role.getId()    ));
        }
        return PageBean;
    }
  • 当绑定角色时,回显的是整行变色的,是以整行变色为基准的,不是以每行前面的√为基准,所有要修复页面以√为基准.

1. 2. 5 修复页面

//弹出绑定资源的窗口
        $("#list").datagrid({
            url:"../../"+action+"/listByPageAndChecked.action?userId=${param.userId}",
            columns:columns,
            //显示分页
            pagination:true,
            //绑定工具条div
            toolbar:"#toolbar",
            //添加数据,重写onLoadSuccess函数
            onLoadSuccess:function(data){

                //遍历rows
                $(data.rows).each(function(i){
                    //判断勾选的行
                    if(data.rows[i].checked){
                        //选择行
                        $("#list").datagrid("selectRow",i);
                    }
                });
            } 
        });

1. 3 修复修改用户,角色,资源时丢失中间表数据

  • 原因:修改User对象时,在表单没有回传Role相关的数据,导致User对象的role为 null,在 hibernate最终保存用户的时候,把中间表的关联数据清空了.
  • 解决方案:

1. 3. 1 UserServiceImpl重写save方法

/**
     * 修复修改用户和角色时中间表数据丢失问题
     * 重写save方法
     */
    @Override
    public void save(User model) {
        //1.判断是否是修改操作
        if(model.getId() != 0) {
        //查询当前用户绑定的角色
            User dBUser =userDao.findOne(model.getId());
            //把原来的角色赋值给model
            model.setRoles(dBUser.getRoles());
        }
        super.save(model);
    }

1. 3. 2 RoleServiceImpl 重写save()方法

/**
     * 修复修改角色对象和资源对象时中间表数据丢失问题
     * 重写save()方法
     */
    @Override
    public void save(Role model) {
        //1.判断如果是修改操作   
        if(model.getId() != 0) {
            //查询当前角色绑定的资源
            Role dbRole =roleDao.findOne(model.getId());
            //把原来的角色赋值给model
            model.setResources(dbRole.getResources());
        }
        super.save(model);
    }   

2 用户登录

2. 1 用户登录

2. 1 .1 jsp页面

$(function(){
            //用户登录
            $("#loginBtn").click(function(){
                $.post("user/login.action",$("#loginform").serialize(),function(data){
                    if(data.success){
                        window.location.href="index.jsp";
                    }else {
                        alert("登录失败:"+data.msg);
                    }
                },"json");
            });
        });
  • 修改表单
class="form-horizontal" id="loginform" name="loginform" method="post" action=""> <div class="form-group" id="idInputLine"> <div class="col-sm-8"> id="loginform:idInput" type="text" name="username" class="form-control" placeholder="请输入手机号/邮箱/用户名"> div> div> <div class="form-group" id="pwdInputLine"> <div class="col-sm-8"> for="pwdInput" type="password" class="form-control" id="password" name="password" placeholder="请输入您的密码"> div> div> <div class="form-group"> <div class="col-sm-4"> "text" name="validCode" class="form-control" id="inputaccount" placeholder="请输入验证码"> div> <div class="col-sm-4"> id="loginform:vCode" src="validatecode.jsp" onclick="javascript:document.getElementById('loginform:vCode'). src='validatecode.jsp?'+Math.random();" /> div> div> <div class="form-group"> <div class="col-sm-offset-3 col-sm-4"> "checkbox">class="size12"> 记住用户名 div> <div class="col-sm-4"> "#">class="size12 forget">忘记密码 div> div> <div class="col-md-offset-3 col-md-8"> "javascript:void(0)" id="loginBtn" name="loginform:j_id19" class="btn btn-danger" target="_blank">立即登录 div>

2. 1. 2 Action

    /**
     * 用户登录
     * @throws IOException 
     */
    @Action("login")
    public void login() throws IOException {
        String key=(String)ActionContext.getContext().getSession().get("key");

        if(! key.equals(validCode)) {
            result.put("success", false);
            result.put("msg", "验证码输入有误");
            writeJson(result);
            return ;
        }
        //判断用户登录
        try {
            User user =userService.login(this.getModel());
            //登录成功
            //把用户对象保存在session
            ActionContext.getContext().getSession().put("user", user);

            result.put("success", true);

        } catch (NoneUsernameException e) {
            //登录失败
            result.put("success", false);
            result.put("msg","用户不存在");
        }catch (ErrorPasswordException e) {
            //登录失败
            result.put("success", false);
            result.put("msg","密码错误");
        }catch (Exception e) {
            e.printStackTrace();
            //登录失败
            result.put("success", false);
            result.put("msg",e.getMessage());
        }finally {
            writeJson(result);      
        }
    }

2. 1. 3 业务层

  • 接口
    User login(User model) throws NoneUsernameException, ErrorPasswordException;
  • 实现类
@Override
    public User login(User model) throws NoneUsernameException, ErrorPasswordException {
        //判断用户是否存在
        User user = userDao.findByUsername(model.getUsername());

        if(user == null) {
            throw new NoneUsernameException();
        }
        if(! model.getPassword().equals(user.getPassword())) {
            throw  new ErrorPasswordException();
        }
        return user;
    }

2. 1. 4 持久层

User findByUsername(String username);

2. 1. 5 修改显示页面

  • 在首页显示当前登录用户和IP
<div id="sessionInfoDiv" style="position: absolute;right: 5px;top:10px;">
                [<strong>${user.nickname}strong>],欢迎你!您使用[<strong><%=request.getRemoteHost() %>strong>]IP登录!
            div>
  • 弹出窗口显示登录用户
// 页面加载后 右下角 弹出窗口
                window.setTimeout(function(){
                    $.messager.show({
                        title:"消息提示",
                        msg:'欢迎登录,${user.nickname}! " onclick="top.showAbout();">联系管理员',
                        timeout:5000
                    });
                },3000);

2. 2 根据登录用户绑定的角色展示动态菜单

2. 2. 1 index.jsp页面

//2.请求后台获取节点数据
                $.post("user/findMyMenu.action",function(data){
                    //3.使用init方法加载数据
                    $.fn.zTree.init($("#menuTree"), setting, data);
                },"json"); 

2. 2. 3 控制层

/**
     * 加载页面时,加载对应用户的菜单
     * @throws IOException 
     */
    @Action("findMyMenu")
    public void findMyMenu() throws IOException{
         //1.获取登录用户
        User loginUser  = (User)ActionContext.getContext().getSession().get("user");
        if(loginUser != null) {
            //2.查询我的菜单
            ListmenuList =userService.findMyMenu(loginUser.getId());
            //3.返回给页面
            removeDuplicateWithOrder(menuList);
            writeJson(menuList);
        }
    }

2. 2. 4 业务层

  • 接口
List findMyMenu(long id);
  • 实现类
/**
     * 获取登录用户的资源列表
     */
    @Override
    public List findMyMenu(long userId) {
        Listlists =userDao.findById(userId);
        return lists;
    }

2. 2. 5 持久层

@Query("select res from User user "
            + "inner join user.roles role "
            + "inner join role.resources res "
            + "where user.id =? and res.resourceType='0'")
    List findById(long userId);
  • 当业务写完后启动项目后,我们发现显示不出资源菜单列表

2. 2. 6 修复显示不出资源菜单问题

  • 原因:前端jsp页面显示的id为pid,而后台输入的id为”_parentId”
  • 解决方案
// index.jsp
//1.定义setting变量
                var setting = {
                        data:{
                            //简单json
                            simpleData:{
                                enable:true,
                                //修改PID的值
                                pIdKey:"_parentId   "
                            }
                        },
                        callback:{
                            //单击
                            onClick:clickTree
                        }
                };

你可能感兴趣的:(java,权限)