众筹网_管理员信息维护_CRUD

  • 管理员单条删除

admin-page.jsp

<!-- ${empty requestScope.pageInfo.list }判断是否为空 -->
<c:if test="${empty requestScope.pageInfo.list }">
    <tr>
        <!-- colspan="6"表示合并单元格 -->
        <td colspan="6">抱歉!没有查询到相关的数据!</td>
    </tr>
</c:if>
<c:if test="${!empty requestScope.pageInfo.list }">
    <!-- varStatus="myStatus"用于循环计数 -->
    <c:forEach items="${requestScope.pageInfo.list }" var="admin" varStatus="myStatus">
        <tr>
            <!-- ${myStatus.count }是单纯的循环计数器,这样是用来代替主键 -->
            <td>${myStatus.count }</td>
            <td><input type="checkbox"></td>
            <td>${admin.loginAcct }</td>
            <td>${admin.userName }</td>
            <td>${admin.email }</td>
            <td>
                <!-- xx按钮 --> 
                <a href="admin/xxx.html"
                class="btn btn-success btn-xs"> 
                <i class=" glyphicon glyphicon-check"></i></a> 
                <!-- 去修改按钮 --> 
                <a href="admin/to/update/page.html?adminId=${admin.id }"
                class="btn btn-primary btn-xs"> 
                <i class=" glyphicon glyphicon-pencil"></i></a> 
                <!-- 删除按钮 --> 
                <c:if test="${admin.id!=sessionScope.admin.id }">
                <a href="admin/remove/${admin.id }/${requestScope.pageInfo.pageNum }.html?keyword=${param.keyword }"
                class="btn btn-danger btn-xs"> <i
                class=" glyphicon glyphicon-remove"></i></a>
                </c:if>

            </td>
        </tr>
    </c:forEach>
</c:if>
  1. 若未查询到数据,则合并单元格,使用<c:if 标签和EL表达式empty运算符完成:<c:if test="${empty requestScope.pageInfo.list }">
  2. 通过<c:forEach 标签,取得列表中的每个admin<c:forEach items="${requestScope.pageInfo.list }" var="admin" varStatus="myStatus">
  3. ${requestScope.pageInfo.list }list为pageInfo中的属性,表示结果集,此处为admin列表
  4. 在<c:forEach 标签中使用varStatus="myStatus"<td>${myStatus.count }</td>表示计数器,用来表示循环次数,此处用来代替主键

1.删除按钮

<!-- 删除按钮 --> 
<c:if test="${admin.id!=sessionScope.admin.id }">
    <a href="admin/remove/${admin.id }/${requestScope.pageInfo.pageNum }.html?keyword=${param.keyword }"
        class="btn btn-danger btn-xs"> <i
        class=" glyphicon glyphicon-remove"></i>
    </a>
</c:if>
  1. 使用REST风格传值${admin.id }和${requestScope.pageInfo.pageNum },在AdminHandler中利用@PathVariable注解接收;
  2. keyword不确定是否有值所以用问号传值
  3. <c:if标签的作用是防止管理员删除自己

2.AdminHandler删除管理员方法

@RequestMapping("admin/remove/{adminId}/{pageNum}.html")
public String removeAdmin(
        // springMVC提供的注解@PathVariable注解可用于提取URL(参数名相同时可以不指定,和@RequestParam同一个道理)
        @PathVariable("adminId") Integer adminId, @PathVariable("pageNum") Integer pageNum, @RequestParam String keyword) {

    adminService.removeAdmin(adminId);
    
    // 跳转路径前面加“forward:”或"redirect:"前缀后,将不会由我们配置的视图解析器拼串,而是会独立解析,路径前一定要加“/”,表示根路径,不加就是相对路径,容易出问题。
    if (keyword == null || keyword.length() == 0) {
        return "redirect:/admin/get/page.html?pageNum=" + pageNum;
    } else {
        return "redirect:/admin/get/page.html?keyword=" + keyword + "&pageNum=" + pageNum;
    }
}
  1. @PathVariable注解:在@RequestMapping请求路径中,将需要传递的参数用花括号{}括起来,然后通过@PathVariable(“参数名称”)获取URL中对应的参数值。若未标明参数名称,则应和URL中参数名一致
  2. 路径问题:跳转路径前面加“forward:”或"redirect:"前缀后,将不会由我们配置的视图解析器拼串,而是会独立解析,路径前一定要加“/”,表示根路径,不加就是相对路径,容易出问题。

 

  •  管理员关键词查询

1.admin-page.jsp中的查询表单:具体代码略

  1. <form action=admin/get/page.html
  2. <input name="keyword"

2.AdminHandler查询管理员方法

@RequestMapping("admin/get/page.html")
public String getPageInfo(
        // 页面上有可能没提供关键词,要进行适配
        @RequestParam(value = "keyword", defaultValue = "") String keyword,
        // 浏览器未提供 pageSize 时,默认每页显示5条记录
        @RequestParam(value = "pageSize", defaultValue = "6") Integer pageSize,
        // 浏览器未提供 pageNum 时,默认前往第1页
        @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,

        ModelMap modelMap) {

    // 查询得到分页的管理员数据pageInfo(pageInfo中封装有AdminListByKeyword,不封装的话,无法用EL表达式取得List<Admin>)
    PageInfo<Admin> pageInfo = adminService.getPageInfo(keyword, pageSize, pageNum);

    // 将分页数据存入模型
    modelMap.addAttribute(CrowdConstant.ATTR_NAME_PAGE_INFO, pageInfo);

    return "admin-page";
}
  1.  通过@RequestParam(value = "keyword", defaultValue = "") String keyword,把显示全部管理员列表和查询带有关键词时的管理员列表结合成立一种情况
  2. 由于keyword语句可能为空,所以要处理SQL语句:adminMapper.xml中
    <!-- 可能有关键词的查询列表 -->
    <select id="selectAdminListByKeyword" resultMap="BaseResultMap" parameterType="string">
        select
        <include refid="Base_Column_List" />
        from t_admin 
        where 
        login_acct like CONCAT("%",#{keyword},"%") or
        user_name like CONCAT("%",#{keyword},"%") or 
        email like CONCAT("%",#{keyword},"%")
    </select>

     使用CONCAT("%",#{keyword},"%")拼接字符串,当keyword不存在时,keyword默认值为:“”,相当于查询全部管理员

 3.AdminService等部分见分页篇

 

  •  管理员新增

1.admin-page.jsp前往新增页面的按钮

<a href="admin/to/add/page.html" class="btn btn-primary" style="float: right;"> 
<i class="glyphicon glyphicon-plus"></i>新增
</a> 

2.AdminHandler新增管理员方法

@RequestMapping("admin/add.html")
public String saveAdmin(Admin admin) {
    adminService.saveAdmin(admin);
    // 跳转到最后一页,保证用户可以看见刚刚添加的数据
    return "redirect:/admin/get/page.html?pageNum=" + Integer.MAX_VALUE;
}

3.AdminService的saveAdmin方法

@Override
public void saveAdmin(Admin admin) {

    // 密码加密
    String userPswd = admin.getUserPswd();
    String encodedPswd = CrowdUtil.md5(userPswd);
    admin.setUserPswd(encodedPswd);

    // 判断账号是否重复
    String loginAcct = admin.getLoginAcct();
    if (LoginAcctIsExist(loginAcct)) {
        throw new LoginAcctInUsedException(CrowdConstant.MESSAGE_LOGINACCT_INUSED);
    }
    
    // 生成创建时间
    Date date = new Date();
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    String CreateTime = format.format(date);
    admin.setCreateTime(CreateTime);
    
    adminMapper.insert(admin);
}
  1. 密码加密后再存入数据库
  2. 判断账号是否已经存在,若存在则抛出异常
    @Override
    public boolean LoginAcctIsExist(String loginAcct) {
        // 根据登录账号查询 Admin 对象
        // ①创建 AdminExample 对象
        AdminExample adminExample = new AdminExample();
    
        // ②创建Criteria 对象
        Criteria criteria = adminExample.createCriteria();
    
        // ③在 Criteria对象中封装查询条件
        criteria.andLoginAcctEqualTo(loginAcct);
    
        // ④调用 AdminMapper 的方法执行查询
        List<Admin> adminList = adminMapper.selectByExample(adminExample);
    
        boolean isExist = !(adminList == null || adminList.size() == 0);
        return isExist;
    }
  3. 生成创建时间(生成时间的几种方法

4.新增管理员页面admin-add.jsp

  1. 表单中value="${param.userName }"value="${param.email }"是为了因“账号已被使用异常”返回admin-add页面时不用再输一遍,其余代码略

 

  • 管理员更新

1.admin-page.jsp前往修改页面按钮(在删除按钮旁边)

<!-- 去修改按钮 -->
<
a href="admin/to/update/page.html?adminId=${admin.id }" class="btn btn-primary btn-xs"> <i class=" glyphicon glyphicon-pencil"></i></a>
  1.  考虑到表单回显(在更新页面显示原信息),故把adminId传到handler中。adminId=${admin.id }

2.AdminHandler表单回显方法

@RequestMapping("admin/to/update/page.html")
public String toUpdate(@RequestParam("adminId") Integer adminId, ModelMap modelMap) {

    // 1.根据主键查询待更新的Admin对象(回显,重新查数据库)
    Admin admin = adminService.getAdminByPrimaryKey(adminId);

    // 2.将 Admin 对象存入模型
    modelMap.addAttribute(CrowdConstant.ATTR_NAME_LOGIN_ADMIN, admin);

    return "admin-update";
}

3.带着admin对象跳转到admin-update.jap:更新页面表单

<form action="admin/update.html" method="post" role="form">
    <input type="hidden" name="pageNum" value="${requestScope.pageInfo.pageNum }"> 
    <input type="hidden" name="keyword" value="${param.keyword }">
    <div class="form-group">
        <label for="exampleInputPassword1">登录账号</label> <input
            name="loginAcct" type="text" class="form-control" value="${requestScope.admin.loginAcct }"
            id="exampleInputPassword1" readonly="readonly">
    </div>
    <p>${requestScope.exception.message}</p>
    <div class="form-group">
        <label for="exampleInputPassword1">原密码</label> <input
            name="userPswd" type="password" 
            class="form-control" id="exampleInputPassword1"
            placeholder="请输入原密码">
    </div>
    <div class="form-group">
        <label for="exampleInputPassword1">新密码</label> <input
            name="userPswdNew" type="password" 
            class="form-control" id="exampleInputPassword1"
            placeholder="请输入新密码">
    </div>
    <div class="form-group">
        <label for="exampleInputPassword1">用户昵称</label> <input
            name="userName" type="text" value="${requestScope.admin.userName }"
            class="form-control" id="exampleInputPassword1"
            placeholder="请输入用户昵称">
    </div>
    <div class="form-group">
        <label for="exampleInputEmail1">邮箱地址</label> <input name="email"
            type="email" value="${requestScope.admin.email }" class="form-control"
            id="exampleInputEmail1" placeholder="请输入邮箱地址">
        <p class="help-block label label-warning">请输入合法的邮箱地址, 格式为:
            xxxx@xxxx.com</p>
    </div>
    <button type="submit" class="btn btn-success">
        <i class="glyphicon glyphicon-plus"></i> 修改
    </button>

    <button type="reset" class="btn btn-danger">
        <i class="glyphicon glyphicon-refresh"></i> 重置
    </button>
</form>
admin-update表单
  1. 通过表单隐藏域<input标签中type="hidden"传pageNum、keyword到handler。实际一个也没传过去,全是空的,不知道为什么,以后修改,一脸懵。
  2. 登录账号不可以改,在<input标签设置只读属性readonly="readonly"
  3. 通过<input标签中value="${requestScope.admin.loginAcct }"来回显表单

4.AdminHandler管理员更新方法

@RequestMapping("admin/update.html")
// pageNum keyword全是空的,不知道为什么!!!。。。。
// 要命:表单传过来的pageNum是String类型的 public String updateAdimn(Admin admin, @RequestParam("pageNum") String pageNum, @RequestParam("keyword") String keyword) { adminService.updateAdmin(admin); //return "redirect:/admin/get/page.html?pageNum="+pageNum+"&keyword="+keyword; if (keyword == null || keyword.length() == 0) {// 判断是否有关键字 return "redirect:/admin/get/page.html?pageNum=" + pageNum; } else { return "redirect:/admin/get/page.html?keyword=" + keyword + "&pageNum=" + pageNum; } }
  1. ${ }实际输出的值是不带双引号的(EL表达式详细介绍
  • 状态码400常见错误
  1. 前端传的参数类型或者名称与后台接收参数的实体类的属性类型或者名称不一致;
  2. 前端提交ajax请求的数据应该是json格式字符串的,但是却没有将对象转换成json格式的字符串。

5.AdminService的updateAdmin方法

@Override
public void updateAdmin(Admin admin) {

// 判断原密码是否正确
    String userPswd = admin.getUserPswd();
    String encodedUserPswd = CrowdUtil.md5(userPswd);
    // 判断密码需要结合账号,因为密码可能重复
    String loginAcct = admin.getLoginAcct();
    
    // ①创建 AdminExample 对象
    AdminExample adminExample = new AdminExample();

    // ②创建Criteria 对象
    Criteria criteria = adminExample.createCriteria();

    // ③在 Criteria对象中封装查询条件
    criteria.andUserPswdEqualTo(encodedUserPswd);
    criteria.andLoginAcctEqualTo(loginAcct);
    List<Admin> adminList = adminMapper.selectByExample(adminExample);
    
    // 判断非空,避免空指针
    if(adminList.size() == 0 || adminList == null) {
        // 搜索不到匹配的密码,抛出异常
        throw new IncorrectUserPswdException(CrowdConstant.MESSAGE_INCORRECT_PSWD);
    }
    // 密码正确,更新数据库
    Admin adminDB = adminList.get(0);
    String userPswdNew = admin.getUserPswdNew();
    String encodedUserPswdNew = CrowdUtil.md5(userPswdNew);
    adminDB.setUserPswd(encodedUserPswdNew);
    
    adminMapper.updateByPrimaryKeySelective(adminDB);
}
  1. 判断密码需要结合账号,因为密码可能重复
  2. criteria.andUserPswdEqualTo(encodedUserPswd);criteria.andLoginAcctEqualTo(loginAcct);在 Criteria对象中可以封装多个查询条件
  3. 在Admin实体类中新增了一个参数:UserPswdNew方便接收用户的新密码,和修改密码。构造方法里并不含这个参数
posted on 2021-07-29 21:32  魔法师多尼se  阅读(78)  评论(0)    收藏  举报