尚筹网 —— 3、管理员维护

目录

1、分页显示管理员信息

1.1、目标

1.2、思路

1.3、代码

1.3.1、引入 PageHelper 依赖

1.3.2、在 SqlSessionFactoryBean 中配置 PageHelper

1.3.3、准备查询 Admin 的 SQL 语句

1.3.4、AdminMapper 的方法

1.3.5、准备 service 方法

1.3.6、添加 AdminHandler 方法

1.3.7、加入 Pagination 插件环境

1.3.8、准备 admin-page.jsp 页面

1.3.9、完成分页条

1.3.10、修改页面显示数据的表格

1.3.11、admin-page.jsp 最终页面

2、关键词查询

2.1、更改页面查询的表单

2.2、在翻页时保持 keyword 值

3、单条删除管理员信息

3.1、思路

3.2、代码

3.2.1、修改页面的删除按钮

3.2.2、添加 service 方法

3.2.3、添加 handle 方法

4、新增管理员

4.1、目标

4.2、思路

4.3、代码

4.3.1、给 t_admin 表的账号添加唯一性约束

4.3.2、修改页面的新增按钮

4.3.3、配置 view-controller 跳转到添加页面

4.3.4、创建新增管理员的页面

4.3.5、创建添加时账号重复的异常类

4.3.6、重写 service 层方法

4.3.7、handle 方法

4.3.8、设置账号重复时的异常映射处理

5、更新管理员信息

5.1、目标

5.2、思路

5.3、代码

5.3.1、修改 admin-page.jsp 页面的修改按钮

5.3.2、添加 service 层方法

5.3.3、添加去修改页面的 handle 方法

5.3.4、添加修改管理员的页面

5.3.5、添加管理员修改页面

5.3.6、添加修改帐号已有的异常类 

5.3.7、配置修改帐号已有的异常映射

5.3.8、添加执行修改的 service 层方法

5.3.9、添加执行修改的 handle 方法


1、分页显示管理员信息

1.1、目标

以分页的形式把管理员信息显示到页面上。特殊需求:兼顾关键词查询,让后端代 码不管有没有查询条件都能够以分页形式显示数据。

1.2、思路

1.3、代码

1.3.1、引入 PageHelper 依赖

确认是否加入了 PageHelper 依赖

        <!-- MyBatis分页插件 -->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
        </dependency>

1.3.2、在 SqlSessionFactoryBean 中配置 PageHelper

    <!-- 配置SqlSessionFactoryBean -->
    <bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 装配数据源-->
        <property name="dataSource" ref="dataSource"/>
        <!-- 指定MyBatis 全局配置文件位置-->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <!-- 指定Mapper 配置文件位置-->
        <property name="mapperLocations" value="classpath:mybatis/mapper/*Mapper.xml"/>
        <!-- 配置插件 -->
        <property name="plugins">
            <array>
                <!-- 配置PageHelper插件 -->
                <bean class="com.github.pagehelper.PageHelper">
                    <property name="properties">
                        <props>
                            <!-- 配置数据库方言,告诉PageHelper当前使用的数据库 -->
                            <prop key="dialect">mysql</prop>
                            <!-- 配置页码的合理化修正,在1~总页码之间修正页码,大于总页码返回最大页码,小于1返回1 -->
                            <prop key="reasonable">true</prop>
                        </props>
                    </property>
                </bean>
            </array>
        </property>
    </bean>

1.3.3、准备查询 Admin 的 SQL 语句

  <select id="selectAdminByKeyword" resultMap="BaseResultMap">
    select id, login_acct, user_pswd, user_name, email, create_time
    from t_admin
    where login_acct like concat("%", #{keyword}, "%") or
          user_name like concat("%", #{keyword}, "%") or
          email like concat("%", #{keyword}, "%")
  </select>

1.3.4、AdminMapper 的方法

List<Admin> selectAdminByKeyword(String keyword);

1.3.5、准备 service 方法

AdminService 接口

    /**
     * 根据关键字分页获取admin
     * @param keyword 关键词
     * @param pageNum 页码数
     * @param pageSize 每页的数据量
     * @return
     */
    PageInfo<Admin> getPageInfo(String keyword, Integer pageNum, Integer pageSize);

AdminServiceImpl 实现类

    /**
     * 根据关键字分页获取admin
     * @param keyword 关键词
     * @param pageNum 页码数
     * @param pageSize 每页的数据量
     * @return
     */
    @Override
    public PageInfo<Admin> getPageInfo(String keyword, Integer pageNum, Integer pageSize) {
        // 调用PageHelper的静态方法开启分页功能
        // 体现了PageHelper的“非侵入式”设计:原本要做的查询不必有任何修改
        PageHelper.startPage(pageNum, pageSize);

        // 执行查询
        List<Admin> list = adminMapper.selectAdminByKeyword(keyword);

        // 封装到PageInfo对象中
        return new PageInfo<>(list);
    }

1.3.6、添加 AdminHandler 方法

    /**
     * 根据关键词分页获取admin信息并跳转到显示页面
     * @param keyword 关键词
     * @param pageNum 页码数
     * @param pageSize 每页的数据量
     * @param ModelMap 
     * @return
     */
    @RequestMapping("/admin/get/page.html")
    public String getPageInfo(
            @RequestParam(value = "keyword", defaultValue = "") String keyword, // 若请求没有关键字,默认为空字符串
            @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum, // 默认为第一页
            @RequestParam(value = "pageSize", defaultValue = "5") Integer pageSize, // 默认每页5条数据
            ModelMap ModelMap
    ){
        PageInfo<Admin> pageInfo = adminService.getPageInfo(keyword, pageNum, pageSize);
        ModelMap.addAttribute(CrowdConstant.ATTR_NAME_PAGE_INFO, pageInfo);
        return "admin-page";
    }

1.3.7、加入 Pagination 插件环境

① 加入所需的 css 和 jquery 

② 在使用的页面引入(注意先后顺序)

<%@include file="/WEB-INF/include-head.jsp" %>

<%-- 引入Pagination插件 --%>
<link rel="stylesheet" href="css/pagination.css" />
<script type="text/javascript" src="jquery/jquery.pagination.js"></script>

1.3.8、准备 admin-page.jsp 页面

将资料中的内容复制进去 

1.3.9、完成分页条

① 修改分页条

                            <tfoot>
                                <tr>
                                    <td colspan="6" align="center">
                                        <div id="Pagination" class="pagination"></div>
                                    </td>
                                </tr>
                            </tfoot>

② 编写 Pagination 代码

<script type="text/javascript">
    // 生成页码导航条
    function initPagination(){
        // 获取总记录数
        var totalRecord = "${requestScope.pageInfo.total}";

        // 声明一个JSON对象存储Pagination要设置的属性
        var properties = {
            num_edge_entries: 3, // 边缘页数,如 1,2,3...20,21,22,...50,51,52 的边缘页数为3(1,2,3  50,51,52)
            num_display_entries: 4, // 主体页数
            callback: pageselectCallback,  // 用户点击翻页的按钮时跳转页面的回调函数
            items_per_page: ${requestScope.pageInfo.pageSize}, // 每页显示的数据量
            current_page: ${requestScope.pageInfo.pageNum - 1},  // 当前选中的页面,Pagination内部使用pageIndex来管理页面,pageIndex从0开始,pageNum从1开始,所以要减一
            prev_text: "上一页",  // “前一页”分页按钮上显示的文本,默认是"Next"
            next_text: "下一页",  // “下一页”分页按钮上显示的文本,默认是"Next"
        }

        // 生成页码导航条
        $("#Pagination").pagination(totalRecord, properties)
    }

    // 回调函数:声明后不是给自己调用,而是交给系统或框架调用
    // 用户点击”上一页、1、2、3、下一页“等这样的页码时调用这个函数实现页面跳转
    // page_index是Pagination传给我们的从0开始的页码
    function pageselectCallback(page_index, jQuery){
        // 根据page_index计算出pageNum
        var pageNum = page_index + 1;

        // 跳转页面
        window.location.href = "admin/get/page.html?pageNum=" + pageNum;

        // 由于每一个页码按钮都是超链接,所以在这个函数最后要取消超链接的默认行为
        return false;
    }


    $(function (){
        // 调用对页码导航条进行初始化操作
        initPagination();
    });
</script>

③ 修改 jquery.pagination.js 代码

问题:

问题的解决:不让 Pagination 在页码导航条初始化完成时就调用回调函数

将最后的调用回调函数的代码注释掉 

1.3.10、修改页面显示数据的表格

admin-page.jsp 

                        <table class="table  table-bordered">
                            <thead>
                            <tr>
                                <th width="30">#</th>
                                <th width="30"><input type="checkbox"></th>
                                <th>账号</th>
                                <th>名称</th>
                                <th>邮箱地址</th>
                                <th width="100">操作</th>
                            </tr>
                            </thead>
                            <tbody>
                            <%-- 没有找到admin数据 --%>
                            <c:if test="${empty requestScope.pageInfo.list}">
                                <tr>
                                    <td colspan="6" align="center">抱歉!没有查询到您要的数据!</td>
                                </tr>
                            </c:if>

                            <c:if test="${!empty requestScope.pageInfo.list}">
                                <c:forEach items="${requestScope.pageInfo.list}" var="admin" varStatus="mystatus">
                                    <tr>
                                        <td>${mystatus.count}</td>
                                        <td><input type="checkbox"></td>
                                        <td>${admin.loginAcct}</td>
                                        <td>${admin.userName}</td>
                                        <td>${admin.email}</td>
                                        <td>
                                            <button type="button" class="btn btn-success btn-xs"><i
                                                    class=" glyphicon glyphicon-check"></i></button>
                                            <button type="button" class="btn btn-primary btn-xs"><i
                                                    class=" glyphicon glyphicon-pencil"></i></button>
                                            <button type="button" class="btn btn-danger btn-xs"><i
                                                    class=" glyphicon glyphicon-remove"></i></button>
                                        </td>
                                    </tr>
                                </c:forEach>
                            </c:if>
                            </tbody>

1.3.11、admin-page.jsp 最终页面

<%--
  Created by IntelliJ IDEA.
  User: zhang
  Date: 2022/5/4
  Time: 21:25
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html lang="zh-CN">
<%@include file="/WEB-INF/include-head.jsp" %>

<%-- 引入Pagination插件 --%>
<link rel="stylesheet" href="css/pagination.css" />
<script type="text/javascript" src="jquery/jquery.pagination.js"></script>

<script type="text/javascript">
    // 生成页码导航条
    function initPagination(){
        // 获取总记录数
        var totalRecord = "${requestScope.pageInfo.total}";

        // 声明一个JSON对象存储Pagination要设置的属性
        var properties = {
            num_edge_entries: 3, // 边缘页数,如 1,2,3...20,21,22,...50,51,52 的边缘页数为3(1,2,3  50,51,52)
            num_display_entries: 4, // 主体页数
            callback: pageselectCallback,  // 用户点击翻页的按钮时跳转页面的回调函数
            items_per_page: ${requestScope.pageInfo.pageSize}, // 每页显示的数据量
            current_page: ${requestScope.pageInfo.pageNum - 1},  // 当前选中的页面,Pagination内部使用pageIndex来管理页面,pageIndex从0开始,pageNum从1开始,所以要减一
            prev_text: "上一页",  // “前一页”分页按钮上显示的文本,默认是"Next"
            next_text: "下一页",  // “下一页”分页按钮上显示的文本,默认是"Next"
        }

        // 生成页码导航条
        $("#Pagination").pagination(totalRecord, properties)
    }

    // 回调函数:声明后不是给自己调用,而是交给系统或框架调用
    // 用户点击”上一页、1、2、3、下一页“等这样的页码时调用这个函数实现页面跳转
    // page_index是Pagination传给我们的从0开始的页码
    function pageselectCallback(page_index, jQuery){
        // 根据page_index计算出pageNum
        var pageNum = page_index + 1;

        // 跳转页面
        window.location.href = "admin/get/page.html?pageNum=" + pageNum;

        // 由于每一个页码按钮都是超链接,所以在这个函数最后要取消超链接的默认行为
        return false;
    }


    $(function (){
        // 调用对页码导航条进行初始化操作
        initPagination();
    });
</script>

<body>

<%@include file="/WEB-INF/include-nav.jsp" %>

<div class="container-fluid">
    <div class="row">
        <%@include file="/WEB-INF/include-sidebar.jsp" %>
        <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
            <div class="panel panel-default">
                <div class="panel-heading">
                    <h3 class="panel-title"><i class="glyphicon glyphicon-th"></i> 数据列表</h3>
                </div>
                <div class="panel-body">
                    <form class="form-inline" role="form" style="float:left;">
                        <div class="form-group has-feedback">
                            <div class="input-group">
                                <div class="input-group-addon">查询条件</div>
                                <input class="form-control has-success" type="text" placeholder="请输入查询条件">
                            </div>
                        </div>
                        <button type="button" class="btn btn-warning"><i class="glyphicon glyphicon-search"></i> 查询
                        </button>
                    </form>
                    <button type="button" class="btn btn-danger" style="float:right;margin-left:10px;"><i
                            class=" glyphicon glyphicon-remove"></i> 删除
                    </button>
                    <button type="button" class="btn btn-primary" style="float:right;"
                            onclick="window.location.href='add.html'"><i class="glyphicon glyphicon-plus"></i> 新增
                    </button>
                    <br>
                    <hr style="clear:both;">
                    <div class="table-responsive">
                        <table class="table  table-bordered">
                            <thead>
                            <tr>
                                <th width="30">#</th>
                                <th width="30"><input type="checkbox"></th>
                                <th>账号</th>
                                <th>名称</th>
                                <th>邮箱地址</th>
                                <th width="100">操作</th>
                            </tr>
                            </thead>
                            <tbody>
                            <%-- 没有找到admin数据 --%>
                            <c:if test="${empty requestScope.pageInfo.list}">
                                <tr>
                                    <td colspan="6" align="center">抱歉!没有查询到您要的数据!</td>
                                </tr>
                            </c:if>

                            <c:if test="${!empty requestScope.pageInfo.list}">
                                <c:forEach items="${requestScope.pageInfo.list}" var="admin" varStatus="mystatus">
                                    <tr>
                                        <td>${mystatus.count}</td>
                                        <td><input type="checkbox"></td>
                                        <td>${admin.loginAcct}</td>
                                        <td>${admin.userName}</td>
                                        <td>${admin.email}</td>
                                        <td>
                                            <button type="button" class="btn btn-success btn-xs"><i
                                                    class=" glyphicon glyphicon-check"></i></button>
                                            <button type="button" class="btn btn-primary btn-xs"><i
                                                    class=" glyphicon glyphicon-pencil"></i></button>
                                            <button type="button" class="btn btn-danger btn-xs"><i
                                                    class=" glyphicon glyphicon-remove"></i></button>
                                        </td>
                                    </tr>
                                </c:forEach>
                            </c:if>
                            </tbody>

                            <tfoot>
                                <tr>
                                    <td colspan="6" align="center">
                                        <div id="Pagination" class="pagination"></div>
                                    </td>
                                </tr>
                            </tfoot>

                        </table>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

</body>
</html>

2、关键词查询

2.1、更改页面查询的表单

admin-page.jsp

                    <form action="admin/get/page.html" method="post" class="form-inline" role="form" style="float:left;">
                        <div class="form-group has-feedback">
                            <div class="input-group">
                                <div class="input-group-addon">查询条件</div>
                                <input name="keyword" class="form-control has-success" type="text" placeholder="请输入查询条件">
                            </div>
                        </div>
                        <button type="submit" class="btn btn-warning"><i class="glyphicon glyphicon-search"></i> 查询
                        </button>
                    </form>

2.2、在翻页时保持 keyword 值

在 admin-page.jsp 页面修改翻页的回调函数

    // 回调函数:声明后不是给自己调用,而是交给系统或框架调用
    // 用户点击”上一页、1、2、3、下一页“等这样的页码时调用这个函数实现页面跳转
    // page_index是Pagination传给我们的从0开始的页码
    function pageselectCallback(page_index, jQuery){
        // 根据page_index计算出pageNum
        var pageNum = page_index + 1;

        // 跳转页面
        window.location.href = "admin/get/page.html?pageNum=" + pageNum + "&keyword=${param.keyword}";

        // 由于每一个页码按钮都是超链接,所以在这个函数最后要取消超链接的默认行为
        return false;
    }

<form action="admin/get/page.html" method="post" class="form-inline" role="form" style="float:left;">
    <div class="form-group has-feedback">
        <div class="input-group">
            <div class="input-group-addon">查询条件</div>
            <input name="keyword" value="${param.keyword}" class="form-control has-success" type="text" placeholder="请输入查询条件">
        </div>
    </div>
    <button type="submit" class="btn btn-warning"><i class="glyphicon glyphicon-search"></i> 查询
    </button>
</form>

3、单条删除管理员信息

3.1、思路

3.2、代码

3.2.1、修改页面的删除按钮

admin-page.jsp

<a href="admin/remove/${admin.id}/${requestScope.pageInfo.pageNum}/${param.keyword}.html" class="btn btn-danger btn-xs">
    <i class=" glyphicon glyphicon-remove"></i>
</a>

3.2.2、添加 service 方法

AdminService

    /**
     * 根据ID删除管理员信息
     * @param adminId 要删除的管理员的ID
     */
    void remove(Integer adminId);

AdminServiceImpl

    /**
     * 根据ID删除管理员信息
     * @param adminId 要删除的管理员的ID
     */
    @Override
    public void remove(Integer adminId) {
        adminMapper.deleteByPrimaryKey(adminId);
    }

3.2.3、添加 handle 方法

AdminHandle

    /**
     * 单个删除管理员信息
     * @param adminId 要删除的管理员的ID
     * @param pageNum 当前页码
     * @param keyword 关键词
     * @return
     */
    @RequestMapping("/admin/remove/{adminId}/{pageNum}/{keyword}.html")
    public String remove(
            @PathVariable("adminId") int adminId,
            @PathVariable("pageNum") int pageNum,
            @PathVariable("keyword") String keyword
    ){
        // 执行删除
        adminService.remove(adminId);

        // 重定向回显示页面,避免重复删除
        return "redirect:/admin/get/page.html?pageNum="+pageNum+"&keyword="+keyword;
    }

4、新增管理员

4.1、目标

创建新的管理员信息,通过表单提交给后端程序并保存到数据库。

4.2、思路

4.3、代码

4.3.1、给 t_admin 表的账号添加唯一性约束

ALTER TABLE `project_crowd`.`t_admin` ADD UNIQUE INDEX (`login_acct`); 

4.3.2、修改页面的新增按钮

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

4.3.3、配置 view-controller 跳转到添加页面

spring-web-mvc.xml

<mvc:view-controller path="/admin/to/add/page.html" view-name="admin-add"/>

4.3.4、创建新增管理员的页面

<%--
  Created by IntelliJ IDEA.
  User: zhang
  Date: 2022/5/5
  Time: 19:31
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html lang="zh-CN">
<%@include file="/WEB-INF/include-head.jsp" %>

<body>

<%@include file="/WEB-INF/include-nav.jsp" %>

<div class="container-fluid">
    <div class="row">
        <%@include file="/WEB-INF/include-sidebar.jsp" %>
        <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
            <ol class="breadcrumb">
                <li><a href="/admin/to/main/page.html">首页</a></li>
                <li><a href="/admin/get/page.html">数据列表</a></li>
                <li class="active">新增</li>
            </ol>
            <div class="panel panel-default">
                <div class="panel-heading">表单数据<div style="float:right;cursor:pointer;" data-toggle="modal" data-target="#myModal"><i class="glyphicon glyphicon-question-sign"></i></div></div>
                <div class="panel-body">
                    <form action="admin/save.html" method="post" role="form">
                        <p>${requestScope.exception.message}</p>
                        <div class="form-group">
                            <label for="exampleInputPassword1">登录账号</label>
                            <input name="loginAcct" type="text" class="form-control" id="exampleInputPassword1" placeholder="请输入登录账号">
                        </div>
                        <div class="form-group">
                            <label for="exampleInputPassword1">登录密码</label>
                            <input name="userPswd" type="text" class="form-control" id="exampleInputPassword1" placeholder="请输入登录密码">
                        </div>
                        <div class="form-group">
                            <label for="exampleInputPassword1">用户昵称</label>
                            <input name="userName" type="text" class="form-control" id="exampleInputPassword1" placeholder="请输入用户名称">
                        </div>
                        <div class="form-group">
                            <label for="exampleInputEmail1">邮箱地址</label>
                            <input name="email" type="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>
                </div>
            </div>
        </div>
    </div>
</div>

</body>
</html>

4.3.5、创建添加时账号重复的异常类

package com.atguigu.crowd.exception;

/**
 * @Author zhang
 * @Date 2022/5/5 - 21:13
 * @Version 1.0
 */

/**
 * 保存或更新Admin时,若检测到账号重复抛出此异常
 */
public class LoginAcctAlreadyInUseException extends RuntimeException{

    private static final long serialVersionUID = 1L;

    public LoginAcctAlreadyInUseException() {
        super();
    }

    public LoginAcctAlreadyInUseException(String message) {
        super(message);
    }

    public LoginAcctAlreadyInUseException(String message, Throwable cause) {
        super(message, cause);
    }

    public LoginAcctAlreadyInUseException(Throwable cause) {
        super(cause);
    }

    protected LoginAcctAlreadyInUseException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

4.3.6、重写 service 层方法

AdminServiceImpl

    /**
     * 保存管理员信息
     * @param admin 要保存的管理员信息
     */
    @Override
    public void saveAdmin(Admin admin) {
        // 密码加密
        String userPswd = CrowdUtil.MD5(admin.getUserPswd());
        admin.setUserPswd(userPswd);

        // 生成创建时间
        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);
    }

4.3.7、handle 方法

AdminHandle

    /**
     * 保存管理员信息
     * @param admin 要保存的管理员信息
     */
    @Override
    public void saveAdmin(Admin admin) {
        // 密码加密
        String userPswd = CrowdUtil.MD5(admin.getUserPswd());
        admin.setUserPswd(userPswd);

        // 生成创建时间
        Date date = new Date();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String createTime = format.format(date);
        admin.setCreateTime(createTime);

        // 执行保存
        try {
            adminMapper.insert(admin);
        } catch (Exception e) {
            e.printStackTrace();
            if(e instanceof DuplicateKeyException){
                throw new LoginAcctAlreadyInUseException(CrowdConstant.MESSAGE_LOGIN_ACCT_ALREADY_IN_USE);
            }
        }
    }

4.3.8、设置账号重复时的异常映射处理

① 基于注解 

CrowdExceptionResolver

    /**
     * 新增管理员信息时抛出账号重复异常的异常映射
     * @param exception
     * @param request
     * @param response
     * @return
     * @throws IOException
     */
    @ExceptionHandler(value = LoginAcctAlreadyInUseException.class)
    public ModelAndView resolveLoginAcctAlreadyInUseException(LoginAcctAlreadyInUseException exception, HttpServletRequest request, HttpServletResponse response) throws IOException {
        String viewName = "admin-add";
        return commonResolve(viewName, exception, request, response);
    }

② 基于 XML

spring-web-mvc.xml 

    <!-- 配置基于XML的异常映射 -->
    <bean id="simpleMappingExceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <!-- 配置异常类型和具体视图页面的对应关系 -->
        <property name="exceptionMappings">
            <props>
                <!-- key属性指定异常的全类名   标签体中写对应的视图(去掉前后缀) -->
                <prop key="java.lang.Exception">system-error</prop>
                <prop key="com.atguigu.crowd.exception.AccessForbiddenException">admin-login</prop>
                <prop key="com.atguigu.crowd.exception.LoginAcctAlreadyInUseException">admin-add</prop>
            </props>
        </property>
    </bean>

5、更新管理员信息

5.1、目标

通过提交页面上的表单修改某个 Admin 的数据。

5.2、思路

5.3、代码

5.3.1、修改 admin-page.jsp 页面的修改按钮

<a href="admin/to/edit/page.html?adminId=${admin.id}&pageNum=${requestScope.pageInfo.pageNum}&keyword=${param.keyword}"
   class="btn btn-primary btn-xs">
	<i class=" glyphicon glyphicon-pencil"></i>
</a>

5.3.2、添加 service 层方法

AdminService

    /**
     * 根据adminId查询管理员信息
     * @param adminId 要查询的管理员的ID
     * @return
     */
    Admin getAdminById(Integer adminId);

AdminServiceImpl

    /**
     * 根据adminId查询管理员信息
     * @param adminId 要查询的管理员的ID
     * @return
     */
    @Override
    public Admin getAdminById(Integer adminId) {
        return adminMapper.selectByPrimaryKey(adminId);
    }

5.3.3、添加去修改页面的 handle 方法

AdminHandle

    /**
     * 跳转到修改管理员信息页面
     * @param adminId 要修改的管理员的ID
     * @param modelMap
     * @return
     */
    @RequestMapping("admin/to/edit/page.html")
    public String toEditPage(
            @RequestParam("adminId") Integer adminId,
            ModelMap modelMap
    ){
        Admin admin = adminService.getAdminById(adminId);
        modelMap.addAttribute("admin", admin);
        return "admin-edit";
    }

5.3.4、添加修改管理员的页面

<a href="admin/to/edit/page.html?adminId=${admin.id}&pageNum=${requestScope.pageInfo.pageNum}&keyword=${param.keyword}"
   class="btn btn-primary btn-xs">
	<i class=" glyphicon glyphicon-pencil"></i>
</a>

5.3.5、添加管理员修改页面

这里通过表单的 hidden 将 pageNum 和  keyword 发送给服务器

<%--
  Created by IntelliJ IDEA.
  User: zhang
  Date: 2022/5/5
  Time: 23:09
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html lang="zh-CN">
<%@include file="/WEB-INF/include-head.jsp" %>

<body>

<%@include file="/WEB-INF/include-nav.jsp" %>

<div class="container-fluid">
    <div class="row">
        <%@include file="/WEB-INF/include-sidebar.jsp" %>
        <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
            <ol class="breadcrumb">
                <li><a href="/admin/to/main/page.html">首页</a></li>
                <li><a href="/admin/get/page.html">数据列表</a></li>
                <li class="active">修改</li>
            </ol>
            <div class="panel panel-default">
                <div class="panel-heading">表单数据<div style="float:right;cursor:pointer;" data-toggle="modal" data-target="#myModal"><i class="glyphicon glyphicon-question-sign"></i></div></div>
                <div class="panel-body">
                    <form action="admin/update.html" method="post" role="form">
                        <input type="hidden" name="id" value="${requestScope.admin.id}">
                        <input type="hidden" name="pageNum" value="${param.pageNum}">
                        <input type="hidden" name="keyword" value="${param.keyword}">
                        <p>${requestScope.exception.message}</p>
                        <div class="form-group">
                            <label for="exampleInputPassword1">登录账号</label>
                            <input name="loginAcct" value="${requestScope.admin.loginAcct}" type="text" class="form-control"
                                   id="exampleInputPassword1" placeholder="请输入登录账号">
                        </div>
                        <div class="form-group">
                            <label for="exampleInputPassword1">用户昵称</label>
                            <input name="userName" value="${requestScope.admin.userName}" type="text" class="form-control"
                                   id="exampleInputPassword1" placeholder="请输入用户名称">
                        </div>
                        <div class="form-group">
                            <label for="exampleInputEmail1">邮箱地址</label>
                            <input name="email" value="${requestScope.admin.email}" type="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-edit"></i> 更新</button>
                        <button type="reset" class="btn btn-danger"><i class="glyphicon glyphicon-refresh"></i> 重置</button>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>

</body>
</html>

5.3.6、添加修改帐号已有的异常类 

package com.atguigu.crowd.exception;

/**
 * @Author zhang
 * @Date 2022/5/5 - 21:13
 * @Version 1.0
 */

/**
 * 保存或更新Admin时,若检测到账号重复抛出此异常
 */
public class LoginAcctAlreadyInUseForUpdateException extends RuntimeException{

    private static final long serialVersionUID = 1L;

    public LoginAcctAlreadyInUseForUpdateException() {
        super();
    }

    public LoginAcctAlreadyInUseForUpdateException(String message) {
        super(message);
    }

    public LoginAcctAlreadyInUseForUpdateException(String message, Throwable cause) {
        super(message, cause);
    }

    public LoginAcctAlreadyInUseForUpdateException(Throwable cause) {
        super(cause);
    }

    protected LoginAcctAlreadyInUseForUpdateException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

5.3.7、配置修改帐号已有的异常映射

CrowdExceptionResolver

    /**
     * 修改帐号已有的异常映射
     * @param exception
     * @param request
     * @param response
     * @return
     * @throws IOException
     */
    @ExceptionHandler(value = LoginAcctAlreadyInUseForUpdateException.class)
    public ModelAndView resolvLoginAcctAlreadyInUseForUpdateException(LoginAcctAlreadyInUseForUpdateException exception, HttpServletRequest request, HttpServletResponse response) throws IOException {
        String viewName = "system-error";
        return commonResolve(viewName, exception, request, response);
    }

5.3.8、添加执行修改的 service 层方法

AdminService

    /**
     * 修改管理员信息(有选择更新,参数admin中属性为null的不更新)
     * @param admin 要修改的修改管理员信息
     */
    void update(Admin admin);

AdminServiceImpl

    /**
     * 修改管理员信息(有选择更新,参数admin中属性为null的不更新)
     * @param admin 要修改的修改管理员信息
     */
    @Override
    public void update(Admin admin) {
        try {
            adminMapper.updateByPrimaryKeySelective(admin);
        } catch (Exception e) {
            e.printStackTrace();
            if(e instanceof DuplicateKeyException){
                throw new LoginAcctAlreadyInUseException(CrowdConstant.MESSAGE_LOGIN_ACCT_ALREADY_IN_USE);
            }
        }
    }

5.3.9、添加执行修改的 handle 方法

AdminHandle

    @RequestMapping("/admin/update.html")
    public String update(
            Admin admin,
            @RequestParam("pageNum") Integer pageNum,
            @RequestParam("keyword") String keyword
    ){
        adminService.update(admin);
        return "redirect:/admin/get/page.html?pageNum="+pageNum+"&keyword="+keyword;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值