day14-功能实现13
家居网购项目实现013
以下皆为部分代码,详见 https://github.com/liyuelian/furniture_mall.git
32.功能30-会员不能登录后台管理
32.1需求分析/图解
- 管理员admin登录后,可以访问所有页面
- 会员登录后,不能访问后台管理相关页面,其他页面可以访问
- 说明:假定管理员就是“admin”,其他皆为会员名
32.2思路分析
修改权限验证AutoFilter
添加逻辑:用户已经登录过了,但是用户名不为admin且访问的url中包含/manage/,就说明是非法用户访问后台,将其转发到首页即可。
32.3代码实现
AutoFilter:

package com.li.furns.filter; import com.google.gson.Gson; import com.li.furns.entity.Member; import com.li.furns.utils.WebUtils; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.util.Arrays; import java.util.HashMap; import java.util.List; /** * 这是用于权限验证的过滤器,对指定的url进行验证 * 如果登录过,就放行;如果没有登录,就返回登录页面 * * @author 李 * @version 1.0 */ public class AuthFilter implements Filter { //后面我们把要排除的url放入到excludedUrls中 private List<String> excludedUrls; public void init(FilterConfig config) throws ServletException { //获取到配置的excludedUrls String strExcludedUrls = config.getInitParameter("excludedUrls"); //进行分割 String[] splitUrl = strExcludedUrls.split(","); //将splitUrl转成List,赋给excludedUrls excludedUrls = Arrays.asList(splitUrl); System.out.println("excludedUrls=>" + excludedUrls); } public void destroy() { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException { //权限验证 HttpServletRequest req = (HttpServletRequest) request; //得到请求的url String url = req.getServletPath(); //判断是否要验证 if (!excludedUrls.contains(url)) {//如果url不在配置的规则中,就进行校验 //得到session中的member对象 Member member = (Member) req.getSession().getAttribute("member"); if (member == null) {//说明用户没有登录过 .... .... .... } return;//返回 } else {//否则说明用户已经登录过了 if (!member.getUsername().equals("admin") && url.contains("/manage/")) { //如果该用户不是admin但请求的url属于后台管理,就将其转发到首页 req.getRequestDispatcher("/index.jsp").forward(request, response); return;//返回 } } } //否则就放行 chain.doFilter(request, response); } }
32.4完成测试
登录普通用户

直接在地址栏访问后台资源,访问失败,页面被转发到首页:

33.功能31-解决图片冗余的问题
33.1需求分析/图解

- 家居图片都放在一个文件夹,会越来越多,请尝试在assets/images/product-image/目录下 自动创建 年月日目录,比如21001010,以天为单位来存放上传图片
- 当上传新家居图片,原来的图片就没有用了,应当删除原来的家居图片
33.2思路分析
-
创建年月日目录按天存放图片
解决方案:在创建保存路径时添加当天的时间即可
-
删除原来的家居图片
解决方案:在保存新图片的同时,在数据库中获取旧图片的路径,然后删除旧图片即可
33.3代码实现
utils包WebUtils:
public static String getYearMonthDay() { //如何得到当前的日期 LocalDateTime ldt = LocalDateTime.now(); int year = ldt.getYear(); int monthValue = ldt.getMonthValue(); int dayOfMonth = ldt.getDayOfMonth(); String yearMonthDay = "/" + year + "/" + monthValue + "/" + dayOfMonth; return yearMonthDay; }
web层修改FurnServlet.update()方法
/** * 处理修改家居的请求 * * @param req * @param resp * @throws ServletException * @throws IOException */ protected void update(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //....略 File fileRealPathDirectory = new File(fileRealPath + WebUtils.getYearMonthDay());//构建带有日期的目录 if (!fileRealPathDirectory.exists()) {//如果文件目录不存在 fileRealPathDirectory.mkdirs();//创建 } //....略 //获取旧的家居文件图片路径 String oldImgPath = furn.getImgPath(); //获取旧图片的绝对路径 String oldImgRealPath = req.getServletContext().getRealPath(oldImgPath); //删除内存中旧的图片,防止图片占用空间过大 File file = new File(oldImgRealPath); if (file.exists()) { file.delete();//删除旧图片 } //更新数据库中家居的图片路径 furn.setImgPath(WebUtils.FURN_IMG_DIRECTORY + WebUtils.getYearMonthDay() + "/" + name); //....略 }
33.4完成测试
登录后台管理,修改家居图片:

写入新的家居信息,点击修改:

成功修改了信息:

服务器按照年月日的目录存放图片,并且将旧图片删除:

34.功能32-完成分页导航条
34.1需求分析/图解

- 如果总页数<=5,就显示全部页数
- 如果总页数>5,就按照如下规则显示:
- 如果 当前页数 是前3页,就显示1-5页
- 如果 当前页数 是后3页,就显示最后5页
- 如果 当前页数 是中间页,就显示 当前页的前2页,当前页,当前页的后2页 即可
34.2思路分析
略
34.3代码实现
furn_manage.jsp(部分)
<ul> <%--如果当前页大于1,就显示上一页--%> <c:if test="${requestScope.page.pageNo>1}"> <li><a href="manage/furnServlet?action=page&pageNo=${requestScope.page.pageNo-1}">上页</a></li> </c:if> <%-- 显示所有的分页数 先确定开始页数 begin 第一页 再确定结束页数 end 第page.TotalCount页 --%> <%-- 1. 如果总页数<=5,就显示全部页数 2. 如果总页数>5,就按照如下规则显示: - 如果 当前页数 是前3页,就显示1-5页 - 如果 当前页数 是后3页,就显示最后5页 - 如果 当前页数 是中间页,就显示 当前页的前2页,当前页,当前页的后2页 即可 这里的关键就是要根据不同的情况来初始化begin,end --%> <c:choose> <%--如果总页数<=5,就显示全部页数--%> <c:when test="${requestScope.page.pageTotalCount <= 5}"> <c:set var="begin" value="1"/> <c:set var="end" value="${requestScope.page.pageTotalCount}"/> </c:when> <%--如果总页数>5,就按照如下规则显示--%> <c:when test="${requestScope.page.pageTotalCount > 5}"> <c:choose> <%--如果 当前页数 是前3页,就显示1-5页--%> <c:when test="${requestScope.page.pageNo <= 3}"> <c:set var="begin" value="1"/> <c:set var="end" value="5"/> </c:when> <%--如果 当前页数 是后3页,就显示最后5页--%> <c:when test="${requestScope.page.pageNo > requestScope.page.pageTotalCount -3}"> <c:set var="begin" value="${requestScope.page.pageTotalCount - 4}"/> <c:set var="end" value="${requestScope.page.pageTotalCount}"/> </c:when> <%--如果 当前页数 是中间页,就显示 当前页的前2页,当前页,当前页的后2页 即可--%> <c:otherwise> <c:set var="begin" value="${requestScope.page.pageNo - 2}"/> <c:set var="end" value="${requestScope.page.pageNo + 2}"/> </c:otherwise> </c:choose> </c:when> </c:choose> <c:forEach begin="${begin}" end="${end}" var="i"> <%--如果i为当前页,就使用class=active来修饰--%> <c:if test="${i==requestScope.page.pageNo}"> <li><a class="active" href="manage/furnServlet?action=page&pageNo=${i}">${i}</a></li> </c:if> <c:if test="${i!=requestScope.page.pageNo}"> <li><a href="manage/furnServlet?action=page&pageNo=${i}">${i}</a></li> </c:if> </c:forEach> <%-- --%> <%-- 如果当前页小于总页数,就往下一页--%> <c:if test="${requestScope.page.pageNo < requestScope.page.pageTotalCount}"> <li><a href="manage/furnServlet?action=page&pageNo=${requestScope.page.pageNo+1}">下页</a></li> </c:if> <li><a>共${requestScope.page.pageTotalCount}页</a></li> <li><a>共${requestScope.page.totalRow}记录</a></li> </ul>
index.jsp同理
34.4完成测试


【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!