美文网首页
16、商品案例

16、商品案例

作者: sunhaiyu | 来源:发表于2017-04-18 10:23 被阅读24次

    商品案例

    实现商品图片的上传,显示商品名称、价格 、数量、图片、描述等。可以对商品进行增改查。

    导包、配置文件和工具类准备

    1. 导入commons-beanutils.jarcommons-fileupload.jarcommons-io.jarcommons-logging.jarmysql-connector-java-bin.jar放到WEB-INF/lib下。

    2. 数据库配置文件

      ClassName=com.mysql.jdbc.Driver
      url=jdbc\:mysql\://localhost\:3306/example
      user=root
      password=admin
      
    3. 数据库连接工具类

    package utils;
    
    import java.io.InputStream;
    import java.sql.*;
    import java.util.Properties;
    
    public class JDBCUtil {
        private static String driver;
        private static String url;
        private static String user;
        private static String password;
    
        // 静态代码块,随着类的加载而加载,只加载一次
        static {
            try {
                Properties prop = new Properties();
                
                // 下面这个是本机使用的就填写项目所在位置,但是我们是要部署到服务器的,所以获取WEB-INF/classes目录下的,注意要加"/"
                // InputStream is = new FileInputStream("/product/src/jdbc_setting.properties");
                InputStream is = JDBCUtil.class.getResourceAsStream("/jdbc_setting.properties");
                // load()接收InputStream,所以向上转型
                prop.load(is);
    
                driver = prop.getProperty("ClassName");
                url = prop.getProperty("url");
                user = prop.getProperty("user");
                password = prop.getProperty("password");
                Class.forName(driver);
                
    
                is.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public static Connection getConnection() {
            Connection connection = null;
            try {
                connection = DriverManager.getConnection(url, user, password);
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException("创建连接失败!");
            }
            return connection;
        }
        // 释放资源
        // 参数可能为空
        // 调用close要抛出异常,即使出现异常也能关闭
       public void close(Connection conn, Statement state, ResultSet result) {
            try {
                if (result != null) {          
                    result.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (state != null) {
                    state.close();
                    }
                } catch (SQLException e) {
                        e.printStackTrace();
                    } finally {
                         try {
                            if (conn != null) {
                                conn.close();
                            }
                        } catch (SQLException e) {
                            e.printStackTrace();
                    }
                }
            }
        }
    }
    

    写一个Bean封装商品数据

    package bean;
    
    public class Product {
        
        private int id;
        private String name;
        private double price;
        private int pnum;
        private String descreption;
        private String type;
        private String imgurl;
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public double getPrice() {
            return price;
        }
        public void setPrice(double price) {
            this.price = price;
        }
        public int getPnum() {
            return pnum;
        }
        public void setPnum(int pnum) {
            this.pnum = pnum;
        }
        public String getDescreption() {
            return descreption;
        }
        public void setDescreption(String descreption) {
            this.descreption = descreption;
        }
        public String getType() {
            return type;
        }
        public void setType(String type) {
            this.type = type;
        }
        public String getImgurl() {
            return imgurl;
        }
        public void setImgurl(String imgurl) {
            this.imgurl = imgurl;
        }
        @Override
        public String toString() {
            return "Product [id=" + id + ", name=" + name + ", price=" + price + ", pnum=" + pnum + ", descreption="
                    + descreption + ", type=" + type + ", imgurl=" + imgurl + "]";
        }
        
        
    }
    
    

    定义用户保存商品信息的接口并实现

    package dao;
    
    import java.util.List;
    
    import bean.Product;
    
    public interface ProductDao {
       // 保存商品
       void save(Product p);
       // 获得所有商品
       List<Product> getAllProducts();
       //根据商品id获得商品对象
       Product getById(int id);
       //更新商品数据
       void update(Product p);
    }
    
    

    实现上面的接口,之所以定义为接口是因为实现里面可能尽不相同。在这里主要是sql语句的不同,写成接口更加灵活。

    package dao.imple;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.ArrayList;
    import java.util.List;
    
    import bean.Product;
    import dao.ProductDao;
    import utils.JDBCUtil;
    
    public class ProductDaoImple implements ProductDao {
    
        @Override
        public void save(Product p) {
            // 1. 获得连接
            Connection connection = JDBCUtil.getConnection();
            // 2. 准备sql语句
            String sql = "insert into `example`.`t_product` ("
                    + "`id`,`name`,`price`,`pnum`,`descreption`,`type`,`imgurl`) " + "values "
                    + "(NULL, ?, ?, ?, ?, ?, ?);";
            // 3.获得PreparedStatement
            PreparedStatement ps = null;
            try {
                ps = connection.prepareStatement(sql);
                // 4. 设置参数, 1表示第一个?
                ps.setString(1, p.getName());
                ps.setDouble(2, p.getPrice());
                ps.setInt(3, p.getPnum());
                ps.setString(4, p.getDescreption());
                ps.setString(5, p.getType());
                ps.setString(6, p.getImgurl());
    
                // 5. 执行sql
                int rows = ps.executeUpdate();
                // 这里只是新增了一行,不等于1说明添加失败
                if (rows != 1) {
                    throw new RuntimeException("添加商品失败!");
                }
    
            } catch (SQLException e) {
                e.printStackTrace();
                throw new RuntimeException("添加商品失败!");
            } finally {
                // 关闭资源
                JDBCUtil.close(connection, ps, null);
            }
    
        }
    
        @Override
        public List<Product> getAllProducts() {
            List<Product> list = new ArrayList<>();
            // 1. 建立连接
            Connection connection = JDBCUtil.getConnection();
            // 2. 准备sql语句
            String sql = "select * from t_product;";
            // 3. 创建PreparedStatement
            PreparedStatement pStatement = null;
            ResultSet rs = null;
            try {
                pStatement = connection.prepareStatement(sql);
                // 4. 执行查询
                rs = pStatement.executeQuery();
    
                // 5. 遍历结果集
                while (rs.next()) {
                    // 将结果集中的数据封装到Product对象中
                    Product p = new Product();
                    p.setId(rs.getInt("id"));
                    p.setName(rs.getString("name"));
                    p.setPrice(rs.getDouble("price"));
                    p.setPnum(rs.getInt("pnum"));
                    p.setDescreption(rs.getString("descreption"));
                    p.setType(rs.getString("type"));
                    p.setImgurl(rs.getString("imgurl"));
    
                    list.add(p);
    
                }
    
            } catch (SQLException e) {
                e.printStackTrace();
                throw new RuntimeException("查询商品数据失败!");
            } finally {
                // 6 关闭资源
                JDBCUtil.close(connection, pStatement, rs);
            }
    
            // 返回产品列表
            return list;
    
        }
    
        public Product getById(int id) {
            // 1 获得连接
            Connection conn = JDBCUtil.getConnection();
            // 2 sql语句
            String sql = "select * from t_product where id = ?;";
            // 3 创建PrepareStatement
            PreparedStatement ps = null;
            ResultSet rs = null;
            Product p = null;
            try {
                ps = conn.prepareStatement(sql);
                // 设置参数
                ps.setInt(1, id);
                // 4 执行sql
                rs = ps.executeQuery();
                // 5 遍历结果集
                if (rs.next()) {
                    // 将结果集中的数据封装到Product对象中
                    p = new Product();
                    p.setName(rs.getString("name"));
                    p.setId(rs.getInt("id"));
                    p.setPrice(rs.getDouble("price"));
                    p.setPnum(rs.getInt("pnum"));
                    p.setType(rs.getString("type"));
                    p.setImgurl(rs.getString("imgurl"));
                    p.setDescreption(rs.getString("descreption"));
    
                }
    
            } catch (SQLException e) {
                e.printStackTrace();
                throw new RuntimeException("根据id查询商品数据失败!");
            } finally {
                // 6 关闭资源
                JDBCUtil.close(conn, ps, rs);
            }
            // 7 返回产品集合
            return p;
        }
        
        // 更新产品 
        public void update(Product p) {
            // 进行判断,edit.jsp里面只是将图片进行显示。如果不上传新的图片,imgurl为空。所以EditServlet里面应该对FileItem的大小就行判断。
            // 即fileItem .getSize() > 0 才执行保存imgurl,更新数据库的图片地址。否则不会更改数据库的图片地址
            boolean hasNewImg = p.getImgurl() != null;
    
            // 1 获得连接
            Connection conn = JDBCUtil.getConnection();
            // 2 准备sql
            String sql = "UPDATE " + "`t_product`" + " SET                    "
                    + " `name` = ?, " + "`price` = ?," + "`pnum` = ?,          "
                    + "`descreption` = ?," + "`type` = ? ";
            if (hasNewImg) {
                sql += ",`imgurl` = ?" + " WHERE `id` = ?;";
            } else {
                sql += " WHERE `id` = ?;";
            }
    
            PreparedStatement ps = null;
            try {
                // 3 获得PrepareStatement
                ps = conn.prepareStatement(sql);
                // 4 设置参数
                ps.setString(1, p.getName());
                ps.setDouble(2, p.getPrice());
                ps.setInt(3, p.getPnum());
                ps.setString(4, p.getDescreption());
                ps.setString(5, p.getType());
                if (hasNewImg) {
                    ps.setString(6, p.getImgurl());
                    ps.setInt(7, p.getId());
                } else {
                    ps.setInt(6, p.getId());
                }
    
                // 5 执行sql
                int rowcount = ps.executeUpdate();
                if (rowcount != 1) {
                    throw new RuntimeException("修改商品数据失败!");
                }
    
            } catch (SQLException e) {
                e.printStackTrace();
                throw new RuntimeException("修改商品数据失败!");
            } finally {
                // 6 关闭资源
                JDBCUtil.close(conn, ps, null);
            }
    
        }
    
    }
    
    

    接下来是一个商品服务类,就更简单了。只是简单调用了上面实现类的save方法而已。

    package service;
    
    
    import java.util.List;
    
    import bean.Product;
    import dao.imple.ProductDaoImple;
    
    public class ProductService {
        
        ProductDaoImple productDaoImple = new ProductDaoImple();
        
        public void save(Product p) {
            productDaoImple.save(p);
        }
        
        public List<Product> getAllProducts() {
            return productDaoImple.getAllProducts();
        }
        
      //根据id查询商品对象
        public Product getById(int id){
            return productDaoImple.getById(id);
                    
        }
        public void update(Product p){
            productDaoImple.update(p);
        }
    }
    
    

    添加商品的界面

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <base href="<%=basePath%>">
        
        <title>My JSP 'login.jsp' starting page</title>
        
        <meta http-equiv="pragma" content="no-cache">
        <meta http-equiv="cache-control" content="no-cache">
        <meta http-equiv="expires" content="0">    
        <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
        <meta http-equiv="description" content="This is my page">
        <!--
        <link rel="stylesheet" type="text/css" href="styles.css">
        -->
    
      </head>
      
      <body>
        <form action="/product/AddProductServlet" method="post" enctype="multipart/form-data" >
            <table border="1">
            <tr>
                <th colspan="2" align="center" >
                    添加商品
                </th>
            </tr>
            <tr>
                <td>商品名称</td>
                <td><input type="text" name="name" /></td>
            </tr>
            
            <tr>
                <td>商品价格</td>
                <td><input type="text" name="price" /></td>
            </tr>
            
            <tr>
                <td>商品库存</td>
                <td><input type="text" name="pnum" /></td>
            </tr>
            
            <tr>
                <td>类别</td>
                <td>
                    <select name="type">
                        <option value="日用百货">日用百货</option>
                        <option value="电子产品">电子产品</option>
                        <option value="零食">零食</option>
                    </select>
                </td>
            </tr>
                 
            <tr>
                <td>商品图片</td>
                <td><input type="file" name="img" /></td>
            </tr>
            
            <tr>
                <td>商品描述</td>
                <td><textarea name="descreption" cols="40" rows="10"/></textarea></td>
            </tr>
            
            <tr>
                 <td colspan="2" align="center" >
                    <input type="submit" value="添加" />
                </td>
            </tr>           
        </table>
    </form>
    
      </body>
    </html>
    
    

    保存到数据库

    package web;
    
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.lang.reflect.InvocationTargetException;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.UUID;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    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.FileUploadException;
    import org.apache.commons.fileupload.disk.DiskFileItemFactory;
    import org.apache.commons.fileupload.servlet.ServletFileUpload;
    import org.apache.commons.io.IOUtils;
    
    import bean.Product;
    import service.ProductService;
    import utils.PathUtils;
    
    @WebServlet("/AddProductServlet")
    public class AddProductServlet extends HttpServlet {
        private ProductService productService = new ProductService();
        Product product = new Product();
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            // 1. 创建配置工厂
            DiskFileItemFactory factory = new DiskFileItemFactory();
            // 2. 创建解析器
            ServletFileUpload upload = new ServletFileUpload(factory);
            // 用来存放表单中的键值对
            Map<String, String[]> map = new HashMap<>();
    
            // 3. 解析request
            List<FileItem> fileItems = null;
    
            try {
                fileItems = upload.parseRequest(request);
                // 4. 遍历FileItem
                if (fileItems != null) {
                    for (FileItem fileItem : fileItems) {
                        // 是普通段
                        if (fileItem.isFormField()) {
                            // 由于是文件上传制定了enctype="multipart/form-data",
                            // 用下面这个方法获取不到参数。
                            // BeanUtils.populate(product,
                            // request.getParameterMap());
    
                            // 需要用FileItem的getString()才能获得键对应的值
                            String key = fileItem.getFieldName();
                            String value = fileItem.getString("UTF-8");
                            // 同一个name属性的值可能相同,Map不允许重复键,所以放入数组
                            map.put(key, new String[] { value });
                            // 是文件,将文件保存到项目根目录下的upload文件夹
                        } else {
    
                            // 获得upload文件夹路径
                            String uploadPath = getServletContext().getRealPath("/upload");
                            // 生成日期文件夹
                            String datePath = PathUtils.getPath(uploadPath);
                            // 生成文件名
                            String fileName = UUID.randomUUID().toString();
                            // 保存图片
                            InputStream is = fileItem.getInputStream();
                            FileOutputStream fos = new FileOutputStream(uploadPath + datePath + fileName);
                            IOUtils.copy(is, fos);
    
                            // 保存访问路径
                            product.setImgurl("/upload" + datePath + fileName);
    
                            // 关流
                            fos.close();
    
                        }
                    }
                }
    
            } catch (FileUploadException e) {
                e.printStackTrace();
                throw new RuntimeException("你的操作有误!");
            }
    
            try {
                BeanUtils.populate(product, map);
            } catch (IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
            // 保存商品到数据库
            productService.save(product);
    
            // 重定向到列表显示,先到servlet在到jsp,因为需要从servlet中从数据库取得数据
            response.sendRedirect(request.getContextPath() + "/ListServlet");
        }
    }
    

    上面写了一个PathUtils来获取日期文件夹的路径

    package utils;
    
    import java.io.File;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    
    public class PathUtils {
        
        public static String getPath(String prefix) {
            SimpleDateFormat dateFormat = new SimpleDateFormat("/yyyy/MM/dd/");
            // 解析好后是  /2017/04/17/
            String datePath = dateFormat.format(new Date());
            // 日期文件夹的完整路径
            String wholePath = prefix + datePath;
            File file = new File(wholePath);
            // 不存在就创建,保证AddProduct里面访问时候就已经存在
            if (!file.exists()) {
                file.mkdirs();
            }
            return datePath;
            
        }
        
    }
    

    商品显示

    这里只是为了学习才引入JSON,一般不这样用。

    package web;
    
    import java.io.IOException;
    import java.util.List;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import bean.Product;
    import net.sf.json.JSONArray;
    import service.ProductService;
    
    @WebServlet("/ListServlet")
    public class ListServlet extends HttpServlet {
        
        private ProductService ps = new ProductService();
        
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
           List<Product> products =  ps.getAllProducts();
            //2 将商品列表放入request域, 将bean直接放入,解析成json
           String json = JSONArray.fromObject(products).toString();
           request.setAttribute("json", json);
               //3 转发到list.jsp
           request.getRequestDispatcher("/WEB-INF/page/list.jsp").forward(request, response);
        
        }
    
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            doGet(request, response);
        }
    
    }
    
    

    使用js动态生成表格

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <base href="<%=basePath%>">
        
        <title>My JSP 'index.jsp' starting page</title>
        <meta http-equiv="pragma" content="no-cache">
        <meta http-equiv="cache-control" content="no-cache">
        <meta http-equiv="expires" content="0">    
        <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
        <meta http-equiv="description" content="This is my page">
        <!--
        <link rel="stylesheet" type="text/css" href="styles.css">
        -->
        
        
      </head>
      
      <body onload="fun1()" >
            <h1>商品列表</h1>
                <table border="1" id="one" >
                </table>
        <script type="text/javascript">
            function fun1(){
                var table = document.getElementById("one");
                // 获得ListServlet所有商品的数组,eval可以把字符串当成语句来执行
                var jsonArray =  eval(${requestScope.json});
                //遍历数组,将商品添加到页面中的列表中。for语句里面没有写自增i++是因为这里我们想要一行显示两个商品
                for(var i = 0 ; i<jsonArray.length;){
                    //创建tr对象
                    var tr = document.createElement("tr");
                    //取出一个商品
                    var product1 =  jsonArray[i++];
                    //创建td对象
                    var td = document.createElement("td");
                    // 点击超链接跳转到编辑商品属性的Servlet,同时传过去了参数name
                    td.innerHTML="![](/product"+product1["imgurl"]+")<br><a href='/product/ToEditServlet?id="+product1["id"]+"' >"+product1["name"]+"</a><br>"+product1["price"]+"元";
                    //将td添加到tr中
                    tr.appendChild(td);
                    //判断,是否还有下一个商品,商品个数为奇数时候不会执行if
                    if(i < jsonArray.length){
                                //取出一个商品
                                var product2 =  jsonArray[i++];
                                //创建td对象
                                var td2 = document.createElement("td");
                                td2.innerHTML="![](/product"+product2["imgurl"]+")<br><a href='/product/ToEditServlet?id="+product2["id"]+"' >"+product2["name"]+"</a><br>"+product2["price"]+"元";
                                //将td添加到tr中
                                tr.appendChild(td2);
                    }
                    //tr添加到表格中
                    table.appendChild(tr);
                }
                
            }   
        
        </script>
      </body>
    </html>
    
    

    看一下,文字和图片都会瞎写的

    点击添加,跳转到商品列表

    商品修改

    点击商品标题的超链接,跳转道ToEditServlet,并且携带了参数id

    package web;
    
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import bean.Product;
    import service.ProductService;
    
    /**
     * Servlet implementation class ToEditServlet
     */
    @WebServlet("/ToEditServlet")
    public class ToEditServlet extends HttpServlet {
        
        private ProductService pService = new ProductService();
        
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // list.jsp里面<a href='/product/ToEditServlet?id="+product1["id"]传来的id参数
            String tagId = request.getParameter("id");
            // 根据id获得具体的商品
            Product product = pService.getById(Integer.parseInt(tagId));
            // 设置属性转发到显示页面
            request.setAttribute("product", product);
            request.getRequestDispatcher("/WEB-INF/page/edit.jsp").forward(request, response);
        }
    
        
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            doGet(request, response);
        }
    
    }
    
    

    跳转到修改商品的jsp页面,这个表格和谈价商品的表格非常类似。

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <base href="<%=basePath%>">
        
        <title>My JSP 'edit.jsp' starting page</title>
        
        <meta http-equiv="pragma" content="no-cache">
        <meta http-equiv="cache-control" content="no-cache">
        <meta http-equiv="expires" content="0">    
        <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
        <meta http-equiv="description" content="This is my page">
        <!--
        <link rel="stylesheet" type="text/css" href="styles.css">
        -->
    
      </head>
      
      <body>
      
        <form action="/product/EditServlet" method="post" enctype="multipart/form-data" >
            <table border="1" >
                <tr>
                    <th colspan="2" align="center" >
                                                                 修改商品
                    </th>
                    
               </tr>   
                    <tr>
                        <td>商品名称:</td>
                        <td><input type="text" name="name" value="${requestScope.product.name}"  /></td>
                    </tr>
                    
                    <tr>
                        <td>商品价格:</td>
                        <td><input type="text" name="price" value="${requestScope.product.price}"  /></td>
                    </tr>
                    
                    <tr>
                        <td>库存:</td>
                        <td><input type="text" name="pnum" value="${requestScope.product.pnum}" /></td>
                    </tr> 
                 
                    <tr>
                        <td>类别:</td>
                        <td>
                        
                        <%--原来数据库里类别是什么,就让哪个默认选中 --%>
                            <select name="type" >
                                <option value="日用百货" ${requestScope.product.type == "日用百货" ? "selected":"" } >日用百货</option>
                                <option value="电子产品" ${requestScope.product.type == "电子产品" ? "selected":"" } >电子产品</option>
                                <option value="零食" ${requestScope.product.type == "零食" ? "selected":"" } >零食</option>
                     
                            </select>
                        </td>
                    </tr>    
                    
                    <tr>
                        <td>商品图片:</td>
                        <td>
                        ![](/product${requestScope.product.imgurl})
                        <input type="file" name="img" />
                        </td>
                    </tr>
                     
                    <tr>
                        <td>商品描述:</td>
                        <td><textarea name="description" cols="50" rows="10"  >
                            ${requestScope.product.descreption}
                        </textarea></td>
                    </tr> 
                    
                    <tr>
                        <td colspan="2" align="center" >
                            <input type="submit" value="修改" />
                        </td>
                    </tr>
                                   
                </table>
                <%-- 不修改id故隐藏,但是要提交 --%>
                <input type="hidden" name="id" value="${requestScope.product.id}" />
            </form>
      </body>
    </html>
    
    

    由EditServlet更新数据库,并重定向到ListServlet重新从数据库取得数据并显示。注意:edit.jsp只是显示了未修改的图片而已,如果不修改,即没有选择文件上传。文件段的fileitem内容就是空的,保存imgurl时就为空,一更新数据导致数据库中原来的图片也丢失。所以需要判断fileItem.getSize() > 0保证确实上传了文件才更新图片imgurl,否则不更新imgurl

    package web;
    
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.lang.reflect.InvocationTargetException;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.UUID;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    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.FileUploadException;
    import org.apache.commons.fileupload.disk.DiskFileItemFactory;
    import org.apache.commons.fileupload.servlet.ServletFileUpload;
    import org.apache.commons.io.IOUtils;
    
    import bean.Product;
    import service.ProductService;
    import utils.PathUtils;
    
    @WebServlet("/EditServlet")
    public class EditServlet extends HttpServlet {
        // 由于修改商品使用的表格和添加商品的表格差不多,这里基本可以用AddProductServlet的代码。只是最后是update
        private ProductService productService = new ProductService();
        Product product = new Product();
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            // 1. 创建配置工厂
            DiskFileItemFactory factory = new DiskFileItemFactory();
            // 2. 创建解析器
            ServletFileUpload upload = new ServletFileUpload(factory);
            // 用来存放表单中的键值对
            Map<String, String[]> map = new HashMap<>();
    
            // 3. 解析request
            List<FileItem> fileItems = null;
    
            try {
                fileItems = upload.parseRequest(request);
                // 4. 遍历FileItem
                if (fileItems != null) {
                    for (FileItem fileItem : fileItems) {
                        // 是普通段
                        if (fileItem.isFormField()) {
                            // 由于是文件上传制定了enctype="multipart/form-data",
                            // 用下面这个方法获取不到参数。
                            // BeanUtils.populate(product,
                            // request.getParameterMap());
    
                            // 需要用FileItem的getString()才能获得键对应的值
                            String key = fileItem.getFieldName();
                            String value = fileItem.getString("UTF-8");
                            // 同一个name属性的值可能相同,Map不允许重复键,所以放入数组
                            map.put(key, new String[] { value });
                            // 是文件,将文件保存到项目根目录下的upload文件夹
                        } else {
                            // 上传的文件不为空才保存imgurl,否则为空保存为null,更新数据库图片丢失
                            if (fileItem.getSize() > 0) {
                                // 获得upload文件夹路径
                                String uploadPath = getServletContext().getRealPath("/upload");
                                // 生成日期文件夹
                                String datePath = PathUtils.getPath(uploadPath);
                                // 生成文件名
                                String fileName = UUID.randomUUID().toString();
                                // 保存图片
                                InputStream is = fileItem.getInputStream();
                                FileOutputStream fos = new FileOutputStream(uploadPath + datePath + fileName);
                                IOUtils.copy(is, fos);
    
                                // 保存访问路径
                                product.setImgurl("/upload" + datePath + fileName);
    
                                // 关流
                                fos.close();
                            }
                        }
                    }
                }
    
            } catch (FileUploadException e) {
                e.printStackTrace();
                throw new RuntimeException("你的操作有误!");
            }
            try {
                BeanUtils.populate(product, map);
            } catch (IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
            // 保存商品到数据库
            productService.update(product);
    
            // 重定向到列表显示,先到servlet在到jsp,因为需要从servlet中从数据库取得数据
            response.sendRedirect(request.getContextPath() + "/ListServlet");
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            // TODO Auto-generated method stub
            doGet(request, response);
        }
    }
    
    

    看下修改页面,修改后将回到商品展示页面,此时数据已经修改。


    by @sunhaiyu

    2017.4.18

    相关文章

      网友评论

          本文标题:16、商品案例

          本文链接:https://www.haomeiwen.com/subject/rsrfzttx.html