后台管理(一)

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

1.6 service核心业务

@Overridepublic 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**/@Overridepublic 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_adminwhere login_acct like concat("%",#{keyword},"%") or user_name like concat("%",#{keyword},"%") or email like concat("%",#{keyword},"%")</select>

service

 @Overridepublic PageInfo<Admin> getPageInfo(String keyword, Integer pageNum, Integer pageSize) {// 开启分页插件PageHelper.startPage(pageNum,pageSize);// 调用mapperList<Admin> adminList= adminMapper.selectAdminByKeyword(keyword);// 将数据封装到PageInforeturn  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) {// 获取pageInfoPageInfo<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"><iclass=" glyphicon glyphicon-check"></i></button><button type="button" class="btn btn-primary btn-xs"><iclass=" glyphicon glyphicon-pencil"></i></button><button type="button" class="btn btn-danger btn-xs"><iclass=" 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();});// 声明一个函数用于初始化 Paginationfunction 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 小 1var 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.hqwc.cn/news/154931.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Python 常用脚本及命令系列 9 -- 图片文字识别 EasyOCR使用】

文章目录 1.1 EasyOCR 介绍1.1.1 EasyOCR 安装1.1.2 EasyOCR 使用方法1.1.2.1 EasyOCR 支持的语言种类1.1.2.2 EasyOCR 支持的图像格式 EasyOCR 提高图片文字识别正确率1.3 问题总结 1.1 EasyOCR 介绍 Python中有一个不错的OCR库-EasyOCR&#xff0c;在GitHub已有9700 star。它…

SRA ToolKit (sra-tools) 的安装和使用

文章目录 前言从哪里下载 SRA ToolKit如何安装怎么用 前言 事情的起因是从NCBI SRA Database下载数据时的一个报错&#xff1a;   path not found while resolving tree within virtual file system module - SRR17****** cannot be found 上次下载数据的时候还是上次&…

Javascript基础-BOM

文章目录 BOM——Browser Object Model定时器--延时函数 JS执行机制具体流程 三个常见对象location对象navigator对象history对象 本地存储介绍sessionStoragesessionStorage 存储复杂数据类型字符串拼接 正则表达式元字符 BOM——Browser Object Model 浏览器对象模型&#x…

多输入多输出 | Matlab实现k-means-LSTM(k均值聚类结合长短期记忆神经网络)多输入多输出组合预测

多输入多输出 | Matlab实现k-means-LSTM&#xff08;k均值聚类结合长短期记忆神经网络&#xff09;多输入多输出组合预测 目录 多输入多输出 | Matlab实现k-means-LSTM&#xff08;k均值聚类结合长短期记忆神经网络&#xff09;多输入多输出组合预测预测效果基本描述程序设计参…

你被骗了吗?别拿低价诱骗机器视觉小白,4000元机器视觉系统怎么来的?机器视觉工程师自己组装一个2000元不到,还带深度学习

淘宝闲鱼&#xff0c;大家搜搜铺价格&#xff0c;特别是机器视觉小白。 机架&#xff1a;&#xff08;新的&#xff09;200元以下。(看需求&#xff0c;自己简单打光&#xff0c;买个50元的。如果复杂&#xff0c;就拿给供应商免费打光) 相机&#xff0c;镜头&#xff1a;&am…

【OpenCV实现图像:用Python生成图像特效,报错ValueError: too many values to unpack (expected 3)】

文章目录 概要读入图像改变单个通道黑白特效颜色反转将图像拆分成四个子部分 概要 Python是一种功能强大的编程语言&#xff0c;也是图像处理领域中常用的工具之一。通过使用Python的图像处理库&#xff08;例如Pillow、OpenCV等&#xff09;&#xff0c;开发者可以实现各种各…

草莓熊代码

话不多说直接上代码 如果需要exe文件电脑可以不依赖环境直接运行请评论或者私信 注意: 不需要年月日显示 注释 879-894 行不需要雪花显示 注释 895-908 行不需要礼物显示 注释 771 行653行 可以修改 祝你节日快乐内容657行 可以修改 草莓熊 内容修改程序标题 第 16 行# -*- co…

简述JVM

文章目录 JVM简介JVM运行时数据区堆(线程共享)方法区/元空间/元数据区(线程共享)栈程序计数器 JVM类加载类加载过程双亲委派模型 垃圾回收机制(GC)判断对象是否为垃圾判断是否被引用指向 如何清理垃圾, 释放对象? JVM简介 JVM 是 Java Virtual Machine 的简称, 意为Java虚拟机…

加速计算卡设计方案:389-基于KU5P的双路100G光纤网络加速计算卡

基于KU5P的双路100G光纤网络加速计算卡 一、板卡概述 基于Xilinx UltraScale16 nm KU5P芯片方案基础上研发的一款双口100 G FPGA光纤以太网PCI-Express v3.0 x8智能加速计算卡&#xff0c;该智能卡拥有高吞吐量、低延时的网络处理能力以及辅助CPU进行网络功能卸载的能力…

Spring Security 6.1.x 系列(2)—— 基于过滤器的基础原理及源码解析(一)

一、过滤器 Spring Security 的 Servlet 支持基于 Servlet 过滤器&#xff0c;因此首先了解过滤器的作用会很有帮助。 下图为单个 HTTP 请求的处理程序的典型分层。 客户端向应用程序发送一个请求&#xff0c;运行容器创建一个FilterChain&#xff08;过滤链&#xff09;&…

Realtek 5G pcie网卡 RTL8126-CG简介

总shu&#xff1a;PCIE 5G网卡方案“RTL8126-CG”采用QFN56封装&#xff0c;面积8 x 8毫米&#xff0c;非常小巧&#xff0c;提供一个RJ-45网口、两个USB 3.x接口。它走的是PCIe 3.0 x1系统通道&#xff0c;搭配超五类网线&#xff0c;可以在长达100米的距离上提供满血的5Gbps网…

股权比例设计的九条生命线

股权比例设计——绝对控制线67% 【释义】一些重大事项如公司的股本变化&#xff0c;关于公司的增减资&#xff0c;修改公司章程&#xff0c; 分立/合并、变更主营项目等重大决策&#xff0c;需要2/3以上&#xff08;含2/3&#xff09;票数支持的。 股权比例设计——相对控制线…