家居网购项目实现013

以下皆为部分代码,详见 https://github.com/liyuelian/furniture_mall.git

32.功能30-会员不能登录后台管理

32.1需求分析/图解

  1. 管理员admin登录后,可以访问所有页面
  2. 会员登录后,不能访问后台管理相关页面,其他页面可以访问
  3. 说明:假定管理员就是“admin”,其他皆为会员名

32.2思路分析

修改权限验证AutoFilter

添加逻辑:用户已经登录过了,但是用户名不为admin且访问的url中包含/manage/,就说明是非法用户访问后台,将其转发到首页即可。

32.3代码实现

AutoFilter:

day14-功能实现13-小白菜博客
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完成测试

登录普通用户

day14-功能实现13-小白菜博客

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

day14-功能实现13-小白菜博客

33.功能31-解决图片冗余的问题

33.1需求分析/图解

day14-功能实现13-小白菜博客
  1. 家居图片都放在一个文件夹,会越来越多,请尝试在assets/images/product-image/目录下 自动创建 年月日目录,比如21001010,以天为单位来存放上传图片
  2. 当上传新家居图片,原来的图片就没有用了,应当删除原来的家居图片

33.2思路分析

  1. 创建年月日目录按天存放图片

    解决方案:在创建保存路径时添加当天的时间即可

  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完成测试

登录后台管理,修改家居图片:

day14-功能实现13-小白菜博客

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

day14-功能实现13-小白菜博客

成功修改了信息:

day14-功能实现13-小白菜博客

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

day14-功能实现13-小白菜博客

34.功能32-完成分页导航条

34.1需求分析/图解

day14-功能实现13-小白菜博客
  1. 如果总页数<=5,就显示全部页数
  2. 如果总页数>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完成测试

day14-功能实现13-小白菜博客
day14-功能实现13-小白菜博客