基于JSP、java、Tomcat三者的项目实战--校园交易网(3)主页--实现修改商品的名字与价格功能(万字爆更)增查改删,三端交互样样齐全

技术支持:JAVA、JSP

服务器:TOMCAT 7.0.86

编程软件:IntelliJ IDEA 2021.1.3 x64

前文几个功能的实现的博客

基于JSP、java、Tomcat、mysql三层交互的项目实战--校园交易网(1)-项目搭建(前期准备工作)-CSDN博客

基于JSP、java、Tomcat、mysql三层交互的项目实战--校园交易网(2)登录功能实现_tomcat jsp mysql-CSDN博客

基于JSP、java、Tomcat三者的项目实战--校园交易网(2)注册功能实现-CSDN博客

基于JSP、java、Tomcat三者的项目实战--校园交易网(3)主页-显示清单(list)-CSDN博客

基于JSP、java、Tomcat三者的项目实战--校园交易网(3)主页--数据库也显示清单遗漏问题-CSDN博客

基于JSP、java、Tomcat三者的项目实战--校园交易网(3)主页--添加商品功能-CSDN博客

基于JSP、java、Tomcat三者的项目实战--校园交易网(3)主页--显示当前用户的信息和系统时间和实现一个简单的购物车功能,包括添加商品、增加数量、减少数量、删除商品以及计算总金额-CSDN博客


在上一篇博客中,我们讲完了添加商品功能和显示时间是怎么写的和一个简单的购物车功能

我们可将添加进来的商品,点击加入购物车按钮,他就会在下面显示我们的购物车一栏,自动计算单价乘以数量,并且我们做了部分优化,左边数量可以减到0,这一栏商品就会自动消失,右边的删除按钮也能删除掉这个商品。

但是,当我要上传的商品数量万一价格要是有所浮动,我们要改变价格这种时候我们要怎么办呢?

基于这个考虑,我们在上方这一栏,我们加入了修改功能。

具体代码在主页中体现

html 复制代码
<a href="load?id=<%=e.getId()%>">修改</a>

作用是创建一个超链接,其中 e.getId() 用于动态地生成商品的ID作为参数。具体来说:

  • <a> 标签定义了一个超链接,用户点击该链接时会跳转到指定的页面。
  • href="load?id=<%=e.getId()%>" 设置了链接的目标地址为 load 的服务,并通过参数 id 将商品的ID传递给目标页面。
  • <%=e.getId()%> 是一个 Java 代码块,用于输出当前商品的ID。这里假设 e.getId() 是一个方法或者属性,返回该商品的唯一标识符。

因此,这个超链接的作用是允许用户点击以跳转到一个特定商品的修改页面,该页面根据传递的商品ID加载对应的商品信息以供修改操作。


当然,我们得充分意识到,当我们要进行一项修改工作时,我们首先要做的是先查找到数据,再去做修改数据的工作。

于是我们要再回到我们的这个load--->

load 是一个相对路径,指向你的项目中的某个 Servlet 或者 JSP 页面,在这段代码中我们指向的是一个服务来完成要做的事情,这个链接通常会被浏览器请求并发送到服务器端,服务器端根据路径和参数来处理请求。

因此使用 Servlet 来处理 load 请求,那么通常会在 web.xml 中配置 Servlet 的映射,指定请求的路径和对应的 Servlet 类。

web.xml

html 复制代码
    <servlet>
        <servlet-name>load</servlet-name>
        <servlet-class>Servlet.SelectShoppingServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>load</servlet-name>
        <url-pattern>/load</url-pattern>
    </servlet-mapping>

load-->SelectShoppingServlet,我们就去服务层中找我们的这个查找商品功能。


服务端(查找功能)

SelectShoppingServlet(查找服务)

java 复制代码
package Servlet;

import dao.StudentDAO;
import entiy.Product;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class SelectShoppingServlet extends HttpServlet {
    public void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        StudentDAO studentDAO = new StudentDAO();
        String id = request.getParameter("id");
        System.out.println(id);
        PrintWriter writer = response.getWriter();
        try {
            Product product = studentDAO.findById(Integer.parseInt(id));
            request.setAttribute("goods",product );
            RequestDispatcher rd = request.getRequestDispatcher("Update.jsp");
            rd.forward(request,response);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

我们可以看到,这段代码中主要来起作用的还是dao层的findById方法来锁定id进行查找,主要用于处理客户端的 HTTP 请求,并根据请求中的商品ID查询对应的商品信息,然后将该信息传递给一个名为 Update.jsp 的 JSP 页面进行展示或处理。

  1. 字符编码和响应类型设置

    • request.setCharacterEncoding("utf-8")response.setContentType("text/html;charset=utf-8") 确保请求和响应都使用 UTF-8 编码,以支持处理中文和其他特殊字符。
  2. DAO 对象的创建和使用

    • StudentDAO studentDAO = new StudentDAO(); 创建了一个用于访问数据库的 StudentDAO 实例,用于执行对商品数据的操作。
  3. 获取和解析请求参数

    • String id = request.getParameter("id"); 获取名为 "id" 的请求参数,通常是客户端传递的商品ID。
  4. 查询数据库并获取商品信息

    • Product product = studentDAO.findById(Integer.parseInt(id)); 调用 studentDAOfindById 方法,根据解析后的商品ID查询数据库中对应的商品信息,并将结果存储在 product 对象中。
  5. 设置请求属性和请求转发

    • request.setAttribute("goods", product); 将查询得到的 product 对象作为名为 "goods" 的请求属性存储起来,以便后续在目标页面 Update.jsp 中使用。
    • RequestDispatcher rd = request.getRequestDispatcher("Update.jsp"); 创建一个请求分派器对象,用于将请求转发到名为 Update.jsp 的 JSP 页面。
    • rd.forward(request, response); 执行请求转发操作,将当前请求和响应对象传递给 Update.jsp 页面,使其能够处理商品信息的展示或进一步的操作。

处理客户端请求、查询数据库、设置请求属性并将请求转发到另一个页面

dao层

java 复制代码
 public Product findById(int id) throws Exception{
        Connection conn = null;
        PreparedStatement prep = null;
        ResultSet rst = null;
        Product e =new Product();
        try {
            conn =DBUtil.getConnection();
            System.out.println(conn);
            prep = conn.prepareStatement(
                    "select * from goods where id="+id+"");
            System.out.println(id);
            rst = prep.executeQuery();
            if(rst.next()){
                int id1 = rst.getInt("id");
                String name = rst.getString("name");
                Double price = rst.getDouble("price");
                e.setId(id1);
                e.setName(name);
                e.setPrice(price);
            }
        }catch (Exception e1){
            e1.printStackTrace();
            throw e1;
        }finally {
            DBUtil.close(conn);
        }
        return e;
    }

findById方法用于根据给定的商品ID从数据库中查询对应的商品信息,并返回一个 Product 对象

  1. 数据库连接和准备语句

    • Connection conn = DBUtil.getConnection(); 获取数据库连接,DBUtil.getConnection() 是一个自定义的方法,用于获取数据库连接对象。
    • prep = conn.prepareStatement("select * from goods where id="+id+""); 创建 PreparedStatement 对象,预编译 SQL 查询语句,通过商品ID从数据库中查询商品信息。
  2. 执行查询并处理结果集

    • rst = prep.executeQuery(); 执行查询操作,将查询结果存储在 ResultSet 对象 rst 中。
    • if(rst.next()) { ... } 判断查询结果集中是否有数据,如果有,进入条件语句块处理查询到的商品信息。
  3. 将查询结果映射到实体对象

    • int id1 = rst.getInt("id"); 从结果集中获取商品ID。
    • String name = rst.getString("name"); 获取商品名称。
    • Double price = rst.getDouble("price"); 获取商品价格。
    • e.setId(id1);, e.setName(name);, e.setPrice(price); 将查询到的商品ID、名称和价格设置到 Product 对象 e 的对应属性中。
  4. 异常处理和资源关闭

    • catch (Exception e1) { ... } 捕获可能抛出的异常,打印异常堆栈信息,并重新抛出异常。
    • finally { DBUtil.close(conn); } 在 finally 块中关闭数据库连接,确保资源得到正确释放,避免资源泄漏。
  5. 返回查询结果

    • return e; 返回封装了查询到的商品信息的 Product 对象 e

实体层

Product

java 复制代码
package entiy;

public class Product {
    private int id;
    private String name;
    private double price;
    // 其他商品属性,如颜色、库存等

    // 构造方法、getter和setter方法


    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Product(/*, 其他属性 */) {
        this.name = name;
        this.price = price;
        // 初始化其他属性
    }

    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;
    }

    @Override
    public String toString() {
        return "Product{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}

Student

java 复制代码
package entiy;

public class Student {

    private String name;
    private int idname;
    private String pd;

    public String getName(){
        return name;
    }
    public void setName(String name){
        this.name=name;
    }

    public int getIdname(){
        return idname;
    }
    public void setIdname(int idname){
        this.idname = idname;
    }

    public String getPd(){
        return pd;
    }
    public void setPd(String pd){
        this.pd = pd;
    }

    @Override
    public String toString(){
        return "Student{"+
                "name="+name+
                "idname="+idname+
                ",pd="+pd+
                '}';
    }

}

网页端

Update.jsp

java 复制代码
<%@ page import="entiy.Product" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
    <title>修改商品信息</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <link rel="stylesheet" type="text/css"
          href="css/style.css" />
</head>

<body>
<div id="wrap">
    <div id="top_content">
        <div id="header">
            <div id="rightheader">
            </div>
            <div id="topheader">
                <h1 id="title">
                   商品修改
                </h1>
            </div>
            <div id="navigation">
            </div>
        </div>
        <div id="content">
            <p id="whereami">
            </p>
            <h1>
                修改商品信息:
            </h1>
            <form action="update" method="post">
                <%
                    Product product = (Product) request.getAttribute("goods");

                    System.out.println(product.getId());
                %>
                <table cellpadding="0" cellspacing="0" border="0"
                       class="form_table">

                    <tr>
                        <td valign="middle" align="right">
                            商品:
                        </td>
                        <td valign="middle" align="left">
                            <input type="text" class="inputgri" name="name" value="<%=product.getName()%>" />
                        </td>
                    </tr>
                    <tr>
                        <td valign="middle" align="right">
                            价格:
                        </td>
                        <td valign="middle" align="left">
                            <input type="text" class="inputgri" name="price" value="<%=product.getPrice()%>" />
                            <input type="hidden" name="id" value="<%=product.getId()%>">
                        </td>
                    </tr>

                </table>
                <p>
                    <input type="submit" class="button" value="提交" />
                </p>
            </form>
        </div>
    </div>
    <div id="footer">
        <div id="footer_bg">
            ABC@126.com
        </div>
    </div>
</div>
</body>
</html>

主要就是用于展示和修改商品信息的表单页面。

  • <%@ page import="entity.Product" %>:导入 Product 实体类,用于在页面中访问商品对象的属性和方法。

  • <form action="update" method="post">:表单的提交地址为 update,使用 POST 方法提交表单数据。

  • <% Product product = (Product) request.getAttribute("goods"); %>:从请求中获取名为 goods 的属性,并将其转换为 Product 对象 product。这通常是通过在 Servlet 中设置请求属性来实现的,用于向页面传递数据。

  • 表单元素

    • <input type="text" class="inputgri" name="name" value="<%=product.getName()%>" />:文本输入框用于显示和修改商品名称,其值从 product 对象的 getName() 方法获取。
    • <input type="text" class="inputgri" name="price" value="<%=product.getPrice()%>" />:文本输入框用于显示和修改商品价格,值从 product 对象的 getPrice() 方法获取。
    • <input type="hidden" name="id" value="<%=product.getId()%>">:隐藏输入框用于传递商品ID,值从 product 对象的 getId() 方法获取。
  • <% System.out.println(product.getId()); %>:在页面中打印商品的ID,通常用于调试目的。

因为其<form action="update" method="post">

表单的提交地址为 update,使用 POST 方法提交表单数据。所有我们在web.xml中又要再写一个

java 复制代码
    <servlet>
        <servlet-name>update</servlet-name>
        <servlet-class>Servlet.UpdateShoppingServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>update</servlet-name>
        <url-pattern>/update</url-pattern>
    </servlet-mapping>

所以在服务端,我们还要继续写一个update功能,能够实现从id查找到我我们选中的商品然后去进行修改

服务端(更新或者说是修改功能)

UpdateShoppinngServlet

java 复制代码
package Servlet;

import dao.StudentDAO;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class UpdateShoppingServlet extends HttpServlet {
    public void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        StudentDAO productDAO = new StudentDAO();
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");

        // Get parameters from request
        String idStr = request.getParameter("id");
        String name = request.getParameter("name");
        String priceStr = request.getParameter("price");

        // Validate parameters
        if (idStr == null || name == null || priceStr == null || idStr.isEmpty() || name.isEmpty() || priceStr.isEmpty()) {
            response.getWriter().println("Invalid parameters. Please provide all fields.");
            return;
        }

        try {
            // Parse parameters
            int id = Integer.parseInt(idStr);
            double price = Double.parseDouble(priceStr);

            // Update product in DAO
            productDAO.Update(id, name, price);

            // Redirect to list page after successful update
            response.sendRedirect("list");

        } catch (NumberFormatException e) {
            // Handle if id or price is not a valid number
            response.getWriter().println("Invalid id or price format. Please enter valid numbers.");
        } catch (Exception e) {
            // Handle other exceptions
            throw new ServletException("Error updating product", e);
        }
    }
}
  1. 导入依赖和设置编码

    • 导入了StudentDAO类,该类用于处理与数据库的交互。
    • 设置请求和响应的字符编码为UTF-8,以确保能够正确处理中文字符。
  2. 重写service方法

    • Servlet类重写了service方法,该方法接收HttpServletRequestHttpServletResponse作为参数,用于处理客户端的请求和生成响应。
  3. 创建DAO对象

    • 实例化了StudentDAO对象productDAO,用于后续的数据库操作。
  4. 获取和验证参数

    • 从请求中获取商品的ID(idStr)、名称(name)和价格(priceStr)。
    • 对获取的参数进行非空和有效性验证:
      • 如果有任何一个参数为空或空字符串,向响应输出错误信息并提前结束处理。
  5. 参数解析和更新操作

    • 尝试将获取到的ID和价格转换为整型和双精度浮点数,如果转换失败则捕获NumberFormatException
    • 调用productDAOUpdate方法,将解析后的ID、名称和价格传递给DAO层进行商品信息的更新操作。
  6. 处理更新结果

    • 如果更新成功,使用response.sendRedirect("list")将用户重定向到商品列表页面。
    • 如果更新过程中出现非数字格式的ID或价格,捕获并处理NumberFormatException,向响应输出相应的错误信息。
    • 如果更新过程中出现其他异常,捕获并抛出ServletException,并将异常信息传递给上层处理。

dao层(update方法)

java 复制代码
public void Update(int id,String name,double price) throws Exception {
        Connection connection = DBUtil.getConnection();
        PreparedStatement preparedStatement = connection.prepareStatement("update goods set name=?,price=? where id =?;");
        preparedStatement.setString(1,name);
        preparedStatement.setDouble(2,price);
        preparedStatement.setInt(3,id);

        int i = preparedStatement.executeUpdate();
        connection.close();
    }

突然发现,可能前面都没说明这个DBUtil包的好像

DBUtil

java 复制代码
package util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DBUtil {
    public static Connection getConnection() throws Exception {
        Connection conn = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/sdjyy?" +
                            "useUnicode=true&characterEncoding=utf8","root","asd123"
            );
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
        return conn;
    }
    public static void close(Connection conn){
        if(conn!=null){
            try {
                conn.close();
            }catch (SQLException e){
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args)throws Exception{
        Connection conn = getConnection();
        System.out.println(conn);
    }
}
  • getConnection 方法用于获取数据库连接对象 Connection

  • 首先,通过 Class.forName 加载 MySQL 数据库驱动程序 com.mysql.jdbc.Driver

  • 然后,使用 DriverManager.getConnection 方法建立与 MySQL 数据库的连接,连接的 URL 指定了本地主机和端口(localhost:3306),以及数据库名(sdjyy)和连接参数(使用Unicode编码和UTF-8字符集)。

  • 如果连接过程中出现异常,会将异常打印出来并重新抛出,向上层调用方法传递异常信息。

  • close 方法用于关闭 Connection 对象。

  • 首先检查传入的 conn 是否为 null,如果不为 null,则调用 conn.close() 方法关闭数据库连接。

  • 如果在关闭连接时发生 SQLException 异常,会将异常打印出来,但不会重新抛出异常,而是简单地记录异常信息。


实现功能截图

从网页上方我们可以明确得知我们拿到了id,也是,我们在写改操作时,常常会因为没有拿到id而数值传为空报错。

笔者在写改操作时,也是在dao层中没有写下我的setid方法,一直传为空,没有拿到id

修改完之后,我们可以看到成功修改了,同时也重定向回到了我们的list页面。

相关推荐
励志成为嵌入式工程师22 分钟前
c语言简单编程练习9
c语言·开发语言·算法·vim
捕鲸叉1 小时前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer1 小时前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
Peter_chq1 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
Yaml41 小时前
Spring Boot 与 Vue 共筑二手书籍交易卓越平台
java·spring boot·后端·mysql·spring·vue·二手书籍
小小小妮子~1 小时前
Spring Boot详解:从入门到精通
java·spring boot·后端
hong1616881 小时前
Spring Boot中实现多数据源连接和切换的方案
java·spring boot·后端
aloha_7892 小时前
从零记录搭建一个干净的mybatis环境
java·笔记·spring·spring cloud·maven·mybatis·springboot
记录成长java2 小时前
ServletContext,Cookie,HttpSession的使用
java·开发语言·servlet
前端青山2 小时前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js