JavaWeb项目--网上商城 (6-5)

day5--后台管理模块开发

 1.模块分析

          案例1-后台所有分类展示
                                                需求:        在左侧的树上上添加一个连接 "分类列表",点击分类列表 将所有的分类展示在右边的主页面上
                                                步骤分析:
                                                                   1.在left.jsp上添加一个连接 父节点"分类管理",在分类管理下面添加一个子节点"分类列表"
                                                                      连接: /store/adminCategory?method=findAll
                                                                   2.编写adminCategoryservlet,继承baseservlet,编写findAll方法
                                                                      调用service 查询所有分类,返回值:List<Category>
                                                                      请求转发 /admin/category/list.jsp

                                              d-tree用法:

                                                                  1.项目中和页面中导入dtree.js
                                                                  2.项目中和页面中导入dtree.css
                                                                  3.在页面中创建一个div,添加样式 class="dtree"
                                                                 4.在div中编写js代码  创建一个树d = new dTree('d');
                                                                      添加节点
                                                                      方法及参数说明:
                                                                      d.add(当前节点id,父节点id,显示名称,点击时候打开的连接,放上去显示的名称,在那个地方打开这个连接)
                                                                      添加根节点
                                                                      根节点的父节点的id为-1
                                                                       添加其他节点
                                                                       5.最后通过document.write(d) 写到页面上即可                   

                                                                       6.例子:    d  = new dTree('d');
                                                                                       d.add('01',-1,'系统菜单树');
                                                                                       d.add('0102','01','分类管理','','','mainFrame');
                                                          d.add('010201','0102','分类列表','${pageContext.request.contextPath}/adminCategory?method=findAll','','mainFrame');
                                                          d.add('010202','0102','添加分类','${pageContext.request.contextPath}/adminCategory?method=addUI','','mainFrame');
                                                          d.add('0104','01','商品管理');
                                                          d.add('010401','0104','已上架商品列表','${pageContext.request.contextPath}/adminProduct?method=findAll','','mainFrame');
                                                          d.add('010402','0104','添加商品','${pageContext.request.contextPath}/adminProduct?method=addUI','','mainFrame');
                                                          d.add('0105','01','订单管理');
                                                          d.add('010501','0105','订单管理','${pageContext.request.contextPath}/adminOrder_findAll.action?page=1','','mainFrame');

                                                          document.write(d);

                                                      <!--id Number 唯一的ID号
                                                           pid Number 判定父节点的数字,根节点的值为
                                                            name String 节点的文本标签
                                                            url String 节点的Url
                                                            title String 节点的Title
                                                          target String 节点的target
                                                          icon String 用做节点的图标,节点没有指定图标时使用默认值
                                                           iconOpen String 用做节点打开的图标,节点没有指定图标时使用默认值
                                                           open Boolean 判断节点是否打开 -->

            案例2-后台添加分类
                                                需求:      
                                                                 在一个表单页面中,输入分类名称,点击保存,将分类保存到数据库
                                               步骤分析:
                                                                1.在left.jsp上添加一个连接 "添加分类"  /store/adminCategory?method=addUI
                                                                2.在admincategoryservlet下编写addUI方法  请求转发到 /admin/category/add.jsp
                                                                3.修改add.jsp, action:/store/adminCategory?method=save
                                                                    给分类input标签添加name属性
                                                                4,点击保存,发送 adminCategory一个请求 请求方法:save
                                                                        获取cname,设置cid
                                                                        封装category对象
                                                                       调用service完成添加操作
                                                                       重定向到分类列表页面
                                                                5.service  调用dao保存
                                                                     更新redis中数据(清空redis中该条记录)

            案例3-后台展示所有商品 
                                               需求:        点击左边树上的一个连接 "已上架商品列表",在右边的主页面上展示所有的商品
                                               步骤分析:
                                                               1.在left.jsp上添加一个连接 "已上架商品列表", /store/adminProduct?method=findAll
                                                               2.编写adminProductServlet,继承baseservlet,编写findAll方法
                                                                   调用service,获取所有的已上架的商品信息 返回值:list
                                                                    将list放入reque st中,请求转发 /admin/product/list.jsp

            案例4-后台添加商品
                                               需求: 

                                                   有一个商品的表单页面,填写商品信息,选择商品的图片,点击保存,将商品的信息保存到数据库中和web服务器上
                                              技术分析:
                                                   文件上传: 就是将客户端的数据发送到服务器上
                                                   文件上传要求:                                                        
                                                              浏览器端要求:                
                                                                                     1.表单提交方式 post
                                                                                     2.提供文件上传框(组件) input type="file"
                                                                                     3.表单entype属性必须为 multipart/form-data
                                                              服务器端要求:  request.getInputStream()
                                                                 注意:
                                                                          若表单使用了 multipart/form-data ,使用原生request去获取参数的时候都为null
                                                                          使用工具类或者框架去解析用户上传的内容
                                                                           commons -fileupload
                                                                          struts(底层:commons-fileupload)
                                                                          serlvet 3.0
                                                                          apache出品的一款专门处理文件上传的工具类 commons-fileupload
                                            使用步骤:
                                                                       1.导入jar包
                                                                       2.创建磁盘文件项工厂
                                                                         DiskFileItemFactory factory=new DiskFileItemFactory();
                                                                       3.创建核心上传对象
                                                                         ServletFileUpload upload=new ServletFileUpload(factory);
                                                                       4.解析请求,获取所有的上传组件 List<FileItem>
                                                                         List<FileItem> list=upload.parseRequest(request);
                                                                       5.遍历list 获取每一个上传项
                                                                        getFiledName():获取标签name属性的值
                                                                        isFormFiled():判断是否是普通上传 组件
                                                                         true:普通上传组件
                                                                         false:文件上传组件 <input type="file">
                                                                         普通上传组件
                                                                         getString("utf-8"):获取用户输入的内容
                                                                        文件上传组件
                                                                        getName():文件 名称
                                                                        getInputStream():获取文件的流
                                                                        delete():删除文件上传时候产生的临时文件

                                      上传注意问题:
                                                                           1.文件名称   浏览器不同,有可能获取的名称不同, 1.txt 或者 G:1.txt
                                                                           2.文件重名   给文件来一个随机名称
                                                                                               uuid方式  毫米值+三个随机数
                                                                                                数据库中可以存放多个字段: 文件名称和文件路径
                                                                                                文件名称:身份证正面.jpg
                                                                                               文件路径:g:123123123423sfsf.jpg
                                                                                                文件下载:
                                                                                               response.setHeader("content-disposition","attachment;filename="+真实名称);
                                                                           3.文件安全(fastDFS)
                                                                                               安全目录:web-inf meta-inf 项目之外的目录
                                                                                               不安全目录:项目目录(除去web-inf和meta-inf)
                                                                           4.目录分离 常用的方式:
                                                                                                  按用户划分 按时间划分  按数量划分   随机划分 

                                             步骤分析:
                                                          1.在left.jsp上添加一个连接,"添加商品",点击他,在主页面上打开一个表单页面
                                                                                 /store/adminProduct?method=addUI
                                                          2.在adminproductserlvet中编写addUI方法
                                                             调用categoryservice查询所有的分类 findList
                                                             请求转发到 /admin/product/add.jsp
                                                             分类信息没有查询出来:
                                                                    方式1:同步  方式2:异步
                                                            3.编辑表单页面   action: /store/addProduct  method:post     entype:multipart/form-data
                                                               给所有的子标签添加name属性  点击保存,向addProductServlet发送请求
                                                            4.编写addProductServlet
                                                                  封装prodcut对象
                                                                  让product的所有字段都有值
                                                                  将product的图片保存到服务器
                                                                  以前使用beanUtils.populate(Product bean,Map map);
                                                                 但是现在request.getParameterMap不好使,若还想使用上面的方法封装对象,
                                                                  我们需要创建一个map 且map中存放product对象的信息
                                                                  Map<String 字段名,Object 值> map
                                                                  字段名: getFieldName()
                                                                  值:getString("utf-8");
                                                                  除了图片
                                                                  将图片通过commons-fileupload保存到服务器上
                                                                  将图片的路径 put到map中
                                                                   调用service保存商品
                                                                   重定向到商品列表页面
                                                             5.service dao
                                                                     注意:  图片目录 保存 备份
 2.代码区

<%@ page language="java" pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>菜单</title>
<link href="${pageContext.request.contextPath}/css/left.css" rel="stylesheet" type="text/css"/>
<link rel="StyleSheet" href="${pageContext.request.contextPath}/css/dtree.css" type="text/css" />
</head>
<body>
<table width="100" border="0" cellspacing="0" cellpadding="0">
  <tr>
    <td height="12"></td>
  </tr>
</table>
<table width="100%" border="0">
  <tr>
    <td>
<div class="dtree">

    <a href="javascript: d.openAll();">展开所有</a> | <a href="javascript: d.closeAll();">关闭所有</a>
    
    <script type="text/javascript" src="${pageContext.request.contextPath}/js/dtree.js"></script>
    <script type="text/javascript">

        d = new dTree('d');
        d.add('01',-1,'系统菜单树');
        d.add('0102','01','分类管理','','','mainFrame');
        d.add('010201','0102','分类列表','${pageContext.request.contextPath}/adminCategory?method=findAll','','mainFrame');
        d.add('010202','0102','添加分类','${pageContext.request.contextPath}/adminCategory?method=addUI','','mainFrame');
        d.add('0104','01','商品管理');
        d.add('010401','0104','已上架商品列表','${pageContext.request.contextPath}/adminProduct?method=findAll','','mainFrame');
        d.add('010402','0104','添加商品','${pageContext.request.contextPath}/adminProduct?method=addUI','','mainFrame');
        d.add('0105','01','订单管理');
        d.add('010501','0105','订单管理','${pageContext.request.contextPath}/adminOrder_findAll.action?page=1','','mainFrame');
        document.write(d);        
    </script>
</div>    </td>
  </tr>
</table>
</body>
</html>
<!--id Number 唯一的ID号 
pid Number 判定父节点的数字,根节点的值为 
name String 节点的文本标签 
url String 节点的Url 
title String 节点的Title 
target String 节点的target 
icon String 用做节点的图标,节点没有指定图标时使用默认值 
iconOpen String 用做节点打开的图标,节点没有指定图标时使用默认值 
open Boolean 判断节点是否打开    -->    
left.jsp
<%@ page language="java" pageEncoding="UTF-8"%>
<html>
    <head>
        <meta http-equiv="Content-Language" content="zh-cn">
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <style>
        body
        {
            SCROLLBAR-ARROW-COLOR: #ffffff;  SCROLLBAR-BASE-COLOR: #dee3f7;
        }
    </style>
  </head>
  
<frameset rows="103,*,43" frameborder=0 border="0" framespacing="0">
  <frame src="${pageContext.request.contextPath}/admin/top.jsp" name="topFrame" scrolling="NO" noresize>
  <frameset cols="159,*" frameborder="0" border="0" framespacing="0">
        <frame src="${pageContext.request.contextPath}/admin/left.jsp" name="leftFrame" noresize scrolling="YES">
        <frame src="${pageContext.request.contextPath}/admin/welcome.jsp" name="mainFrame">
  </frameset>
  <frame src="${pageContext.request.contextPath}/admin/bottom.jsp" name="bottomFrame" scrolling="NO"  noresize>
</frameset>
</html>
home.jsp
package com.itheima.web.servlet;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.itheima.domain.Category;
import com.itheima.service.CategoryService;
import com.itheima.utils.BeanFactory;
import com.itheima.utils.UUIDUtils;
import com.itheima.web.servlet.base.BaseServlet;

/**
 * 后台分类管理模块
 */
public class AdminCategoryServlet extends BaseServlet {
    private static final long serialVersionUID = 1L;
    
    /**
     * 添加分类
     * @param request
     * @param response
     * @return
     * @throws ServletException
     * @throws IOException
     */
    public String save(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            //1.封装category对象
            Category c = new Category();
            c.setCid(UUIDUtils.getId());
            c.setCname(request.getParameter("cname"));
            
            //2.调用service完成添加操作
            CategoryService cs = (CategoryService) BeanFactory.getBean("CategoryService");
            cs.save(c);
            
            //3.重定向
            response.sendRedirect(request.getContextPath()+"/adminCategory?method=findAll");
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException();
        }
        return null;
    }
    
    /**
     * 跳转到添加页面
     * @param request
     * @param response
     * @return
     * @throws ServletException
     * @throws IOException
     */
    public String addUI(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        return "/admin/category/add.jsp";
    }
    /**
     * 展示所有分类
     * @param request
     * @param response
     * @return
     * @throws ServletException
     * @throws IOException
     */
    public String findAll(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            //1.调用service 获取所有的分类
            CategoryService cs = (CategoryService) BeanFactory.getBean("CategoryService");
            List<Category> list=cs.findList();
            
            //2.将返回值放入request域中 请求转发
            request.setAttribute("list", list);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException();
        }
        
        return "/admin/category/list.jsp";
    }

}
AdminCategoryServlet 后台分类管理模块
package com.itheima.web.servlet;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.IOUtils;

import com.itheima.constant.Constant;
import com.itheima.domain.Category;
import com.itheima.domain.Product;
import com.itheima.service.ProductService;
import com.itheima.utils.BeanFactory;
import com.itheima.utils.UUIDUtils;
import com.itheima.utils.UploadUtils;

/**
 * 保存商品
 */
public class AddProductServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            //0.使用fileuload保存图片和将商品的信息放入map中
            //0.1 创建map 存放商品的信息
            Map<String,Object> map=new HashMap<>();
            
            //0.2 创建磁盘文件项工厂 (设置临时文件的大小和位置)
            DiskFileItemFactory factory = new DiskFileItemFactory();
            
            //0.3 创建核心上传对象
            ServletFileUpload upload = new ServletFileUpload(factory);
            
            //0.4 解析request
            List<FileItem> list = upload.parseRequest(request);
            
            //0.5遍历list 获取每一个文件项
            for (FileItem fi : list) {
                //0.6获取name属性值
                String key = fi.getFieldName();
                
                //0.7判断是否是普通的上传组件
                if(fi.isFormField()){
                    //普通
                    map.put(key, fi.getString("utf-8"));
                }else{
                    //文件
                    //a.获取文件的名称  1.jpg
                    String name = fi.getName();
                    
                    //b.获取文件真实名称 1.jpg
                    String realName = UploadUtils.getRealName(name);
                    
                    //c.获取文件的随机名称  12312312434234.jpg
                    String uuidName = UploadUtils.getUUIDName(realName);
                    
                    //d.获取随机目录 /a/3
                    String dir = UploadUtils.getDir();
                    
                    //e.获取文件内容(输入流)
                    InputStream is = fi.getInputStream();
                    
                    //f.创建输出流
                    //获取products目录的真实路径
                    String productPath = getServletContext().getRealPath("/products");
                    
                    //创建随机目录
                    File dirFile = new File(productPath,dir);
                    if(!dirFile.exists()){
                        dirFile.mkdirs();
                    }
                    
                    // d:/tomcat/webapps/store/prouduct/a/3/12312312434234.jpg
                    FileOutputStream os = new FileOutputStream(new File(dirFile,uuidName));
                    
                    //g.对拷流
                    IOUtils.copy(is, os);
                    
                    //h.释放资源
                    os.close();
                    is.close();
                    
                    //i.删除临时文件
                    fi.delete();
                    
                    //j.将商品的路径放入map中   prouduct/a/3/12312312434234.jpg
                    map.put(key, "products"+dir+"/"+uuidName);
                }
            }
            
            //1.封装product对象
            Product p = new Product();
            //1.1.手动设置 pid
            map.put("pid", UUIDUtils.getId());
            
            //1.2.手动设置 pdate
            map.put("pdate", new Date());
            
            //1.3.手动设置 pflag  上架
            map.put("pflag", Constant.PRODUCT_IS_UP);
            
            //1.4.使用beanutils封装
            BeanUtils.populate(p, map);
            
            //1.5.手动设置 category
            Category c = new Category();
            c.setCid((String)map.get("cid"));
            p.setCategory(c);
            
            //2.调用service 完成保存
            ProductService ps = (ProductService) BeanFactory.getBean("ProductService");
            ps.save(p);
            
            //3.重定向
            response.sendRedirect(request.getContextPath()+"/adminProduct?method=findAll");
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("保存商品失败");
        }
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

}
AddProductServlet 保存商品
package com.itheima.utils;

import java.util.Random;
import java.util.UUID;

public class UploadUtils {
    /**
     * 获取文件真实名称
     * 由于浏览器的不同获取的名称可能为:c:/upload/1.jpg或者1.jpg 
     * 最终获取的为  1.jpg
     * @param name 上传上来的文件名称
     * @return    真实名称
     */
    public static String getRealName(String name){
        //获取最后一个"/"
        int index = name.lastIndexOf("\");
        return name.substring(index+1);
    }
    
    
    /**
     * 获取随机名称
     * @param realName 真实名称
     * @return uuid 随机名称
     */
    public static String getUUIDName(String realName){
        //realname  可能是  1.jpg   也可能是  1
        //获取后缀名
        int index = realName.lastIndexOf(".");
        if(index==-1){
            return UUID.randomUUID().toString().replace("-", "").toUpperCase();
        }else{
            return UUID.randomUUID().toString().replace("-", "").toUpperCase()+realName.substring(index);
        }
    }
    
    
    /**
     * 获取文件目录,可以获取256个随机目录
     * @return 随机目录
     */
    public static String getDir(){
        String s="0123456789ABCDEF";
        Random r = new Random();
        return "/"+s.charAt(r.nextInt(16))+"/"+s.charAt(r.nextInt(16));
    }
    
    public static void main(String[] args) {
        //String s="G:\day17-基础加强\resource\1.jpg";
        String s="1";
        String realName = getRealName(s);
        System.out.println(realName);
        
        String uuidName = getUUIDName(realName);
        System.out.println(uuidName);
        
        String dir = getDir();
        System.out.println(dir);
    }
}
UploadUtils


原文地址:https://www.cnblogs.com/ou-pc/p/7895720.html