后台管理(一)

news2024/11/27 20:58:47

1、管理员登录

1.1、创建Md5加密工具类:

 public static String md5(String source) {
        //判断source是否生效

        if (source == null || source.length() == 0) {
            //不是有效的数据
            throw new RuntimeException(CrowdConstant.MESSAGE_STRING_INVALIDATE);
        }

        String algorithm = "md5";
        //获取MessageDigest对象
        try {
            MessageDigest messageDigest = MessageDigest.getInstance(algorithm);

            // 获取明文字符串对应的字节数组
            byte[] input = source.getBytes();

            // 执行加密
            byte[] output = messageDigest.digest(input);

            // 创建BigInterger对象
            int signum = 1;
            BigInteger bigInteger = new BigInteger(signum, output);

            // 按照十六进制将bigInteger的值转换成字符串
            int base = 16;
            String encoded = bigInteger.toString(base).toUpperCase();

            return encoded;

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }

1.2、创建登录失败异常

package com.songzhishu.crowd.exception;


/**
 * @BelongsProject: CrowdFunding-parent
 * @BelongsPackage: com.songzhishu.crowd.exception
 * @Author: 斗痘侠
 * @CreateTime: 2023-10-29  15:32
 * @Description: 登录失败异常
 * @Version: 1.0
 */
public class LoginFailedException extends  RuntimeException {

    private static final long serialVersionUID = 1577454949343343608L;

    public LoginFailedException() {
    }

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

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

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

    public LoginFailedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

1.3、在异常处理器类中增加登录失败异常的处理

//登录异常
    @ExceptionHandler(value = LoginFailedException.class)
    public ModelAndView resolveNullPointerException(LoginFailedException exception, HttpServletRequest request, HttpServletResponse response) throws IOException {
        String viewName = "admin-longin";
        return commonResolve(viewName, exception, request, response);
    }

1.4、 在登录页面显示异常消息

<p>${requestScope.exception.message}</p>

1.5、Controller方法

@Controller
public class AdminController {
    @Autowired
    private AdminService adminService;

    @RequestMapping(value = "/admin/do/login.html")
    public String doLogin(@RequestParam("loginAcct") String loginAcct,
                          @RequestParam("userPswd") String userPswd,
                          HttpSession session
    ) {
        // 调用登录检查的方法 返回admin
        Admin admin = adminService.getAdminByLoginAcct(loginAcct, userPswd);
        
        // 将登录成功的数据存入session域
        session.setAttribute(CrowdConstant.ATTR_NAME_LOGIN_ADMIN,admin);
        
        //跳转后台主页面
        return "admin-main";
    }
}

1.6 service核心业务

@Override
    public Admin getAdminByLoginAcct(String loginAcct, String userPswd) {
        // 1查询用户

        // 1.1创建adminExample对象
        AdminExample adminExample = new AdminExample();

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

        // 1.3 在criteria中添加条件
        criteria.andLoginAcctEqualTo(loginAcct);
        List<Admin> adminList = adminMapper.selectByExample(adminExample);


        // 判断用户
        if (adminList == null||adminList.size()==0) {
           throw new LoginFailedException(CrowdConstant.MESSAGE_LOGIN_FAILED);
        }
        if (adminList.size()>1) {
            //数据错误
            throw  new LoginFailedException(CrowdConstant.MESSAGE_SYSTEM_ERROR_LOGIN_NOT_UNIQUE);

        }

        Admin admin = adminList.get(0);

        if (admin == null) {
            throw  new LoginFailedException(CrowdConstant.MESSAGE_LOGIN_FAILED);
        }

        // 获取密码
        String userPswdDBMD5 = admin.getUserPswd();

        // 加密
        String userPswdFormMD5 = CrowdUtil.md5(userPswd);

        // 比较
        if (!(Objects.equals(userPswdDBMD5,userPswdFormMD5))){
            throw  new LoginFailedException(CrowdConstant.MESSAGE_LOGIN_FAILED);
        }
        //返回数据
        return admin;
    }

1.7、跳转到后台管理页面:

        修改控制层代码:为了避免跳转到后台主页面再刷新浏览器导致重复提交登录表单,重定向到目标页面。

//跳转后台主页面
        return "redirect:/admin/to/main/page.html";

        使用视图控制器是因为,这个页面的访问不需要数据的,直接进行跳转就可以!

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

         这里遇见一个小问题就是,跳转后的页面的样式没有生效,然后我以为是可能和浏览器的缓存什么的也有关系,所以就清除数据,然后发现没有效果,就是不理解问什么找不到资源,然后网上查资料说是在配置SpringMVC中的前端控制器将所有的静态资源都给屏蔽啦,然后就导致数据不能正常的访问,然后我记得我也设置啦注解驱动,教程讲要加上一个

<mvc:default-servlet-handler></mvc:default-servlet-handler>

        但是加上后不起作用,然后我脑袋突然开窍,我定义啦一个base标签,我访问css资源的标签写在这个base标签上,然后导致找不到数据,哈哈哈哈,以后找不到数据的话可以试试绝对路径!

<c:set var="baseurl" value="${pageContext.request.contextPath }"></c:set>
<script type="text/javascript" src="${baseurl }/scripts/jquery-1.9.1.min.js"></script>

2、登录检查:

将部分资源保护起来,让没有登录的请求不能访问。

2.1、流程:

2.2、实现

2.2.1、创建拦截器类:
/**
 * @BelongsProject: CrowdFunding-parent
 * @BelongsPackage: com.songzhishu.crowd.mvc.interceptor
 * @Author: 斗痘侠
 * @CreateTime: 2023-10-30  11:32
 * @Description: 登录拦截器
 * @Version: 1.0
 */
public class LoginInterceptor extends HandlerInterceptorAdapter {

    /**
     * @description:  控制器之前执行
     * @author: 斗痘侠
     * @date: 2023/10/30 11:35
     * @param: null
     * @return: null
     **/
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 检测是否登录  获取session中的数据
        HttpSession session = request.getSession();

        Admin admin = (Admin) session.getAttribute(CrowdConstant.ATTR_NAME_LOGIN_ADMIN);

        // 判断
        if (admin == null) {
            throw new AccessForbiddenException(CrowdConstant.MESSAGE_LOGIN_FORBIDEN);
        }

        // 不为空 放行
        return true;
    }
}
2.2.2、自定义异常:
package com.songzhishu.crowd.exception;

/**
 * @BelongsProject: CrowdFunding-parent
 * @BelongsPackage: com.songzhishu.crowd.exception
 * @Author: 斗痘侠
 * @CreateTime: 2023-10-30  11:42
 * @Description: 表示用户没有登录就访问受保护的资源时的异常
 * @Version: 1.0
 */
public class AccessForbiddenException extends RuntimeException{
    private static final long serialVersionUID = -1279033257779871422L;

    public AccessForbiddenException() {
        super();
    }

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

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

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

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

2.2.3、注册拦截器类
 <!--注册拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--要拦截的资源  /* 只对应一层路径  /**拦截多层路径-->
            <mvc:mapping path="/**"/>
            <!--不拦截的资源  登录注册...-->
            <mvc:exclude-mapping path="/admin/to/login/page.html"/>
            <mvc:exclude-mapping path="/admin/do/login.html"/>
            <mvc:exclude-mapping path="/admin/do/logout.html"/>
            <!--配置拦截器的类-->
            <bean class="com.songzhishu.crowd.mvc.interceptor.LoginInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

3、权限管理之用户

3.1、分页查询(条件和不加条件

3.1.1、配置分页插件:

导入依赖

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

配置

<!--配置分页插件-->
        <property name="plugins">
            <array>
                <!-- 传入插件的对象 -->
                <bean class="com.github.pagehelper.PageInterceptor">
                    <property name="properties">
                        <props>
                            <prop key="helperDialect">mysql</prop>
                            <prop key="reasonable">true</prop>
                        </props>
                    </property>
                </bean>
            </array>
        </property>

        气死啦这个配置,<prop key="helperDialect">mysql</prop>, 耽误我好多时间,我一开始写啦dialect然后一直报错!我就查资料,然后有人用的数组有的人用的list集合,有的人写在MyBatis中,有的人整合到Spring中,有的人全类名写的是com.github.pagehelper.PageInterceptor,也有的人写的是com.github.pagehelper.PageHelper,看啦一整个头大,最后反正我就是不断的试错然后写出来的,反正以后再报错我就知道啦

mapper:

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

service

 @Override
    public PageInfo<Admin> getPageInfo(String keyword, Integer pageNum, Integer pageSize) {
        // 开启分页插件
        PageHelper.startPage(pageNum,pageSize);

        // 调用mapper
        List<Admin> adminList= adminMapper.selectAdminByKeyword(keyword);


        // 将数据封装到PageInfo
        return  new PageInfo<>(adminList);
    }

controller

 @RequestMapping(value = "/admin/get/page.html")
    public String getPageInfo(@RequestParam(value = "keyword", defaultValue = "") String keyword,
                              @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
                              @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
                              ModelMap modelMap
    ) {

        // 获取pageInfo
        PageInfo<Admin> pageInfo = adminService.getPageInfo(keyword, pageNum, pageSize);
        // 存入模型
        modelMap.addAttribute(CrowdConstant.ATTR_NAME_PAGE_INFO, pageInfo);

        return "admin-page";

    }

jsp

 <%--没有数据--%>
                            <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>

        写这个的时候要使用jstl标签,所以使用之前要先导入jstl的jar包,问题来了他有三个,导入哪一个呐,啧啧啧多试试就知道啦!

3.1.2、分页导航条:

导入js、css后处理前端页面;

<link rel="stylesheet" href="css/pagination.css">
<script type="text/javascript" src="jquery/jquery.pagination.js"></script>
<script type="text/javascript">
    $(function () {
    // 调用专门的函数初始化分页导航条
        initPagination();
    });

    // 声明一个函数用于初始化 Pagination
    function initPagination() {
        // 获取分页数据中的总记录数
        var totalRecord = ${requestScope.pageInfo.total};
        // 声明 Pagination 设置属性的 JSON 对象
        var properties = {
            num_edge_entries: 3, // 边缘页数
            num_display_entries: 5, // 主体页数
            callback: pageSelectCallback, // 用户点击“翻页”按钮之后执行翻页操作的回调函数

            current_page: ${requestScope.pageInfo.pageNum-1}, // 当前页,pageNum 从 1 开始,必须-1 后才可以赋值
            prev_text: "上一页",
            next_text: "下一页",
            items_per_page:${requestScope.pageInfo.pageSize} // 每页显示 1 项
        };
        // 调用分页导航条对应的 jQuery 对象的 pagination()方法生成导航条
        $("#Pagination").pagination(totalRecord, properties);
    }

    // 翻页过程中执行的回调函数
    // 点击“上一页”、“下一页”或“数字页码”都会触发翻页动作,从而导致当前函数被调用

    // pageIndex 是用户在页面上点击的页码数值
    function pageSelectCallback(pageIndex, jQuery) {
        // pageIndex 是当前页页码的索引,相对于 pageNum 来说,pageIndex 比 pageNum 小 1
        var pageNum = pageIndex + 1;
        // 执行页面跳转也就是实现“翻页”
        window.location.href = "admin/get/page.html?pageNum=" + pageNum;
        // 取消当前超链接的默认行为
        return false;
    }
</script>

显示

   <tfoot>
      <tr>
      <td colspan="6" align="center">
       <div id="Pagination" class="pagination"><!-- 这里显示分页 --></div>
      </td>
      </tr>
  </tfoot>

3.2、关键词查询

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>

        这样写只能查询一次,也就是说这在点击分页导航条的时候就不携带查询的关键字啦!

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

3.3、单条删除

jsp

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1153677.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

带你学习毫秒级的故障检测技术BFD

【微|信|公|众|号&#xff1a;厦门微思网络】 【微思网络http://www.xmws.cn&#xff0c;成立于2002年&#xff0c;专业培训21年&#xff0c;思科、华为、红帽、ORACLE、VMware等厂商认证及考试&#xff0c;以及其他认证PMP、CISP、ITIL等】 什么是BFD&#xff1f; BFD&#x…

【uniapp+vue3】scroll-view实现纵向自动滚动及swiper实现纵向自动滚动

scroll-view本身不支持自动滚动&#xff0c;通过scroll-top属性控制滚动&#xff0c;但是不可以循环滚动 <scroll-view class"notice-bar" scroll-y"true" ref"scrollViewRef" :scroll-top"data.scrollViewTop"scroll-with-animati…

Power BI 傻瓜入门 18. 让您的数据熠熠生辉

本章内容包括&#xff1a; 配置Power BI以使数据增量刷新发现使用Power BI Desktop and Services保护数据集的方法在不影响性能和完整性的情况下管理海量数据集 如果有更新的、更相关的数据可用&#xff0c;旧数据对组织没有好处。而且&#xff0c;老实说&#xff0c;如果数据…

一文搞懂“支付·清结算·账务”全局

《上帝视角看支付&#xff0c;总架构解析》 对支付的宏观层面做了分析&#xff0c;详解了整个支付体系每一层的架构和业务模型&#xff0c;而每一层的企业内部支付体系建设是什么样的&#xff1f;会涉及到哪些环节和系统&#xff1f;每个系统会涉及到哪些单据和逻辑&#xff0c…

工业级环网交换机的功效和用途

十年前&#xff0c;工业级环网交换机是一个被忽视的领域&#xff0c;在自动化中只占据了很小的一部分&#xff0c;并没有引起太多厂商的重视。随着自动化技术的不断成熟&#xff0c;工业以太网的广泛采用以及大型工业控制网络的建设&#xff0c;自动化厂商也不能忽视丰富产品线…

中文版goole浏览器支持小于12px的文字

1、说明&#xff1a; 中文版goole浏览器默认不支持小于12px的文字&#xff0c;英文版支持。 2、可浏览器设置&#xff1a; goole浏览器前往 chrome://settings/fonts&#xff0c;更改浏览器设置。 3、可代码设置 -webkit-transform:scale() 说明&#xff1a;transform:sca…

数字组合-第10届蓝桥杯省赛Python真题精选

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第1讲。 数字组合&#xff…

01-学成在线项目基础环境模块搭建

基础工程搭建 项目根目录 创建一个空工程xuecheng-plus即项目的根目录,进入Project Structure检查jdk是否配置正确 新增.gitignore文件用来设置工程中不需要向仓库提交的内容 HELP.md target/ !.mvn/wrapper/maven-wrapper.jar !**/src/main/** !**/src/test/** #### STS …

天津重点大数据培训 大数据培训的三个重要内容

随着互联网的发展和技术的进步&#xff0c;大数据的应用范围越来越广泛&#xff0c;对于企业和个人来说&#xff0c;学习和掌握大数据技术已经成为了必不可少的一项能力。大数据技术是当前和未来的发展方向&#xff0c;对于想进入互联网行业或从事相关技术工作的人来说&#xf…

毕业论文常用分析方法

毕业论文选题结束后&#xff0c;需要根据不同的研究主题以及研究目的确定相应的分析方法。同类型的研究方法有很多种&#xff0c;今天梳理了毕业论文写作的常用分析方法&#xff0c;分模块进行汇总整理&#xff0c;方便大家对照查找。 一、基本描述分析 基本描述统计分析包括频…

大坝水库安全监测终端MCU,智能化管理的新篇章!

我国目前拥有超过9.8万座水库大坝&#xff0c;其中超过95%为土石坝&#xff0c;这些大坝主要是在上世纪80年代以前建造的。这些水库大坝在保障防洪、发电、供水、灌溉等方面发挥了巨大的作用&#xff0c;但是同时也存在一定的安全风险&#xff0c;比如坝体结构破损、坝基渗漏、…

Linux环境基础开发工具使用(一)万字讲解

文章目录 一、Linux 软件包管理器 yum1、什么是软件包2、关于 rzsz3、查看软件包4、如何安装软件5、如何卸载软件 二、Linux编辑器——vim1、IDE例子2、Linux编辑器-vim使用3、 vim的基本概念4、 vim的基本操作5、 vim正常模式命令集1、插入模式2、从插入模式切换为命令模式3、…

建模和图表工具:Software Ideas Modeler Crack

用于图表、软件设计和分析的 CASE 工具 Software Ideas Modeler 是一款智能CASE 工具和 图表软件&#xff0c;支持 UML、SysML、ERD、BPMN、ArchiMate、流程图、用户故事、线框图。 提升用户体验和人工智能集成 - Software Ideas Modeler 14.05 最近发布的 14.05 版本带来了一…

uni-app微信小程序打开第三方地图

需求 小程序中有个按钮点击以后会调用手机中第三方地图进行导航。参数 位置信息 经度 与纬度。 实现方法 uni.openLocation({latitude: Number(地址纬度),longitude: Number(地址经度),name: 地址名称,address: 地址详情,success: function (res) {console.log(打开系统位置地…

每日汇评:通胀数据公布前,欧元复苏失去动力

欧元/美元周一上涨后回落至1.0600&#xff1b; 市场参与者将密切关注欧元区通胀数据&#xff1b; 如果价格跌破1.0580-1.0580区间&#xff0c;卖方可能会采取行动&#xff1b; EUR/USD积聚了多头动能&#xff0c;周一实现了一周以来最高的日内收盘价&#xff0c;超过1.0600。然…

想知道自己转本复习的效果,就试试这些方法吧

在你埋头苦学的时候&#xff0c;你觉得自己复习得怎么样&#xff1f;用下面的方法检测一下吧~ 01做题时间证明掌握程度 做题的快慢可以验证知识掌握和熟练程度。做题速度慢往往是因为对知识不熟悉。 像数学等理科&#xff0c;会对计算和解题速度要求比较高&#xff0c;需要先…

轻量级gif制作工具 GIFfun中文 for mac

GIFfun是一款GIF制作工具&#xff0c;可以帮助用户从照片和视频中创建GIF动画。该软件具有多种功能&#xff0c;例如GIF转视频、视频转GIF、照片转GIF、照片转视频、GIF转JPG、调整GIF大小、PDF转GIF、PDF转JPG、裁剪视频、GIF编辑等。 GIFfun还提供了专业版功能&#xff0c;如…

浅析 TLS(ECDHE)协议的握手流程(图解)

前言 通过 wireshark 抓取 HTTPS 包&#xff0c;理解 TLS 1.2 安全通信协议的握手流程。 重点理解几个点&#xff1a; TLS 握手流程&#xff1a;通过 wireshark 抓取 HTTPS 包理解。协商加密&#xff1a;双方通过 ECDHE 椭圆曲线的密钥交换算法&#xff0c;协商出共享的 会话…

高效管理用户权限:深入探索Spring Security的多用户类型认证、授权和Token刷新

前言 对于spring secutiry 来讲&#xff0c;其默认是只支持一种数据类型进行认证的&#xff0c;因为最后组件的方法仅为&#xff1a;loadUserByUsername(String username) 方法。 如果有多个系统来使用这个认证模块&#xff0c;会导致查询问题。这也就是不支持多用户类型认证…

C# TabControl控件设置多行属性multiline为true后切换页签出现空白

一、问题描述&#xff1a; 最近一直在做C#项目&#xff0c;随着项目的不断扩大&#xff0c;Form窗体中TabControl控件的内容一行已经放不下了&#xff0c;于是乎就设置了属性multiline为true&#xff0c;但是随之而来的就是一个新问题。当切换其他程序窗口返回后&#xff0c;就…