09 MVC设计模式案例(下)

本文详细介绍了MVC设计模式在Java Web开发中的具体应用案例,包括增删改查等核心功能实现过程,深入剖析了Servlet如何与JSP交互,以及在实际开发中遇到的一些常见问题及其解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MVC设计模式案例(下)

标签(空格分隔): JavaWeb


Servlet之删除操作

在查询到的表格中进行删除,涉及到删除指定id的数据。如何使servlet获取到jsp中的id?使用Parameter参数进行交互。

我们通过获取Parameter参数(也就是路径问号后面的参数)来获取要删除的id,通过<%=%>的方式获取id
超链接:

<a href="delete.do?id=<%=customer.getId()%>">DELETE</a>

Servlet的delete方法:
1. 获取id
2. 调用DAO执行删除
3. 重定向到query.do(若目标页面不需要读取当前请求的request属性,就可以重定向), 将显式删除后的Customer对象

private void delete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("delete");
        //获取jsp传递的参数(字符串类型)
        String idStr = request.getParameter("id");
        int id = 0;
        //trycatch的作用是为了防止idStr不能被转为Integer
        //若不能转则id=0,无法进行任何删除操作
        try {
            id = Integer.parseInt(idStr);
            customerDAO.delete(id);
        } catch (Exception e) {}
        response.sendRedirect("query.do");
    }

Servlet之添加

该操作为在index.jsp页面中的点击,跳转到添加页面,并填写信息向数据表中添加一条数据。若name已经被占用则显示提示信息,之前填写的信息回显。若可以添加,则添加成功后返回一个成功页面。

步骤

  1. 给index.jsp中的超链接添加一个地址:add.jsp
  2. 创建add.jsp页面,输入参数,提交按钮,表单的action转为add.do
  3. 在CustomerServlet中写add方法,作为add.do的响应
    1. 获取表单参数
    2. 判断name是否已经被占用
    3. 若验证不通过,则返回add.jsp页面,提示信息,回显参数
    4. 若验证通过,则把表单参数封装为一个Customer对象customer
  4. 调用customerDAO的save(customer)执行保存操作
  5. 重定向到addSuccess.jsp页面
  6. addSuccess.jsp页面提示信息,并提供返回

add.jsp

对于写add.jsp除了写一个显式的表单外,有两点需要注意:

一是如果name被占用,返回到该界面的时候会显示一个提示信息。我们将该提示信息,通过属性以setAttribute()的方式,封装成一个字符串。然后我们在jsp中写java代码进行判断:如果我们获取到的对象不是null,则显式这个字符串。

二是如果name被占用,那么需要回显之前写的内容。也就是在value属性上,我们要获取之前表单提交的Parameter参数,如果我们仅这么写,那么在还没填写的时候,显示null而不是空白,因此我们要进行一个判断。

要注意的一点是:包裹java代码的<%=%>写在value=""分号中。


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%
    Object msg = request.getAttribute("message");
    if(msg != null){
%>
<br>
<font color="red"><%= msg %></font>
<br><br>
<%
    }
%>
<form action="add.do" method="post">
    <table>
        <tr>
            <td>CustomerName:</td>
            <td><input type="text" name="name"
                 value="<%= request.getParameter("name") == null ? "" : request.getParameter("name")%>"
            /></td>
        </tr>
        <tr>
            <td>Address:</td>
            <td><input type="text" name="address"
                value="<%= request.getParameter("address")==null ? "" : request.getParameter("address") %>"/></td>
        </tr>
        <tr>
            <td>Phone:</td>
            <td><input type="text" name="phone"
                       value="<%= request.getParameter("phone")==null ? "" : request.getParameter("phone") %>"/></td>
        </tr>
        <tr>
            <td><input type="submit" value="Add"/></td>
        </tr>
    </table>
</form>
</body>
</html>

add方法

检查用户名是否被占用,是一个与之前操作不同的地方。

  1. 通过调用CustomerDAO的getCountWithName(String name)获取该name在数据库中存在的个数
  2. 如果返回值大于0,说明name不存在,则响应add.jsp页面
    1. 要求在add.jsp显示一个错误信息,在这种情况下我们应该使用Attribute属性(因此我们要设立,而Parameter没有set方法)即在request上放一个属性message来显示(在jsp中通过get方法进行获取)。
    2. 要求add.jsp的表单值可以回显(这一步是在jsp上进行操作)。
    3. 通过转发的方式响应add.jsp,因为我们还需要使用request,因此使用转发,保证这是一次请求。
    4. return结束该方法(不进行下面的操作)。
  3. 若验证通过把表单参数封装为一个Customer对象customer
  4. 调用customerDAO的save(customer)执行保存操作
  5. 重定向到addSuccess.jsp页面:使用重定向可以避免表单重复提交的问题(如果是转发,在添加成功之后再点刷新,表单会重复提交)
private void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1. 获取表单参数:name,address,phone
        String name = request.getParameter("name");
        String address = request.getParameter("address");
        String phone = request.getParameter("phone");

        //2. 检验name是否已经被占用
        //2.1 调用CustomerDAO的getCountWithName(String name)获取该name在数据库中存在的个数
        long count = customerDAO.getCountWithName(name);

        //2.2 如果返回值大于0,则说明该name不存在,响应add.jsp页面
        if (count > 0) {
            //2.2.1 要求在add.jsp显示一个错误信息,即在request上放一个属性message来显式
            request.setAttribute("message","用户" + name + "已存在!");

            //2.2.2 add.jsp的表单值可以回显(在jsp上进行操作)
            //通过 value="<%= request.getParameter("name") == null ? "" : request.getParameter("name") %>"进行回显

            //2.2.3 通过转发的方式响应add.jsp,然后结束该方法
            request.getRequestDispatcher("/add.jsp").forward(request,response);
            return;

        }
        // 若验证通过把表单参数封装为一个Customer对象customer
        Customer customer = new Customer(name,address,phone);

        //调用customerDAO的save(customer)执行保存操作
        customerDAO.save(customer);
        //重定向到addSuccess.jsp页面:使用重定向可以避免表单重复提交的问题
        response.sendRedirect("addSuccess.jsp");
    }

有一点需要注意:

当我们封装一个对象的时候,是通过构造函数拉起传递获取的参数的,因此在Customer类中应该创建一个带参数的构造函数。然后!记得再创建一个无参的构造函数,否则会出现错误。

Servlet之修改

修改一条数据对象,一共分为两步骤:
1. 点击要修改条目的修改按钮,通过edit方法将该对象的信息显示到update.jsp上
2. 在update上写好信息之后点击更改按钮,用过update方法进行更改

edit方法

UPDATE的超链接(需要获取id,通过id来确定修改哪个),跳转到servlet页面,执行edit方法

<a href="edit.do?id=<%=customer.getId()%>">UPDATE</a>

edit方法:
获取id,调用CustomerDAO的方法获取id对应的Customer对象,将Customer对象放入request中,然后响应updateCustomer.jsp页面(转发)

步骤如下:
1. 获取当前对象的id
2. 通过customerDAO的get(id)方法获取该id对应的Customer对象
3. 如果Customer对象不为null,说明传入的id是正确的
4. 将customer对象作为属性,传递给update.jsp
5. 请求转发到update.jsp

 private void edit(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
        String forwardPath = "/error.jsp";
        //获取当前对象的id
        String idStr = request.getParameter("id");
        try {
            //通过customerDAO的get(id)方法获取该id对应的Customer对象
            Customer customer = customerDAO.get(Integer.parseInt(idStr));
            //如果customer对象不为null,说明id传入是正确的
            if (customer != null) {
                //将路径更改为要传递的路径
                forwardPath = "/update.jsp";
                //将customer对象作为属性,要传递给update.jsp页面
                request.setAttribute("customer",customer);
            }
        } catch (NumberFormatException e) {
        }
        //请求转方法到update.jps页面
        request.getRequestDispatcher(forwardPath).forward(request,response);
    }

update.jsp

JSP页面:

获取请求域中Customer对象,调用对应的字段中的get()方法来显示值。
wo我们修改Customer对象,需要在数据库中找到这条数据,需要使用id。但是我们在界面上是不显示id的,这里我们就需要使用隐藏域来获取Customet对象的id。

关于隐藏域,与其他表单域一样可以被提交到服务器,但是在页面上不显示。

同样的,在回显的时候,我们需要知道原name不能丢失,因此我们也需要使用隐藏域来保存oldName。提交到update.do

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%
    Object msg = request.getAttribute("msg");
    if(msg != null){
%>
<br>
<font color="red"><%= msg %></font>
<br><br>
<% } %>
<%
    Customer customer = (Customer) request.getAttribute("customer");
%>

<form action="update.do" method="post">

    <input type="hidden" name="id" value="<%=customer.getId()%>"/>
    <input type="hidden" name="oldName" value="<%=customer.getName()%>"/>

    <table>
        <tr>
            <td>CustomerName:</td>
            <td><input type="text" name="name"
                       value="<%=customer.getName()%>"
            /></td>
        </tr>
        <tr>
            <td>Address:</td>
            <td><input type="text" name="address"
                       value="<%=customer.getAddress()%>"
            /></td>
        </tr>
        <tr>
            <td>Phone:</td>
            <td><input type="text" name="phone"
                       value="<%=customer.getPhone()%>"
            /></td>
        </tr>
        <tr>
            <td><input type="submit" value="Update"/></td>
        </tr>
    </table>
</form>

</body>
</html>

update方法

update方法是修改操作。在update.jsp页面上填完信息后提交表单,在servlet中,通过update方法对封装好的对象进行修改。

在update方法中,需要对name进行验证。与添加操作的验证不同的是:
此时有可能修改name,也有可能没修改name,如果没有修改,在数据库中有该name,不算重复。
因此需要进行一个判断:
获取隐藏域中的oldName作为待比较的对象,如果修改了name,则在数据库中进行比对;如果没修改name,则不用进行比对。

在回显的时候,address,phone显示表单提交的新值,name回显oldName
如果通过验证,则封装对象,执行update操作,返回重定向到query.do

其步骤如下:

  1. 获取表单参数
  2. 对name进行检验,是否被占用
    2.1 比较name和oldName是否相同,如果相同,则当前name可用
    2.2 如果不同则要在数据空中查找该name是否被占用
    2.3 如果name被占用,则说明封装提示纤细,然后请求转发到jsp页面,并结束方法
  3. 如果检验通过,则封装参数为customer对象
  4. 调用CustomerDAO的update方法
  5. 请求重定向
private void update(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
        //1. 获取表单参数
        String oldName = request.getParameter("oldName");
        String id = request.getParameter("id");
        String name = request.getParameter("name");
        String address = request.getParameter("address");
        String phone = request.getParameter("phone");

        //2. 对name进行检验,是否被占用

        //2.1 比较name和oldName是否相同,如果相同,则当前name可用
        //2.2 如果不同,则要在数据库中查找该name是否被占用
        if (!name.equalsIgnoreCase(oldName)) {

            //2.3 如果name被占用,则将进行一系列操作并最终转到update.jsp
            long count = customerDAO.getCountWithName(name);
            if (count > 0) {
                //2.3.1 封装一个用于提示的信息msg
                String msg = "用户名" + name + "被占用!";
                request.setAttribute("msg",msg);
                //2.3.2 表单值进行回显,name使用oldName(否则会丢失),address,phone写新的
                //这步在jsp中进行操作
                //2.3.3 通过请求转发的方式到update.jsp
                request.getRequestDispatcher("/update.jsp").forward(request,response);
                //2.3.4 return结束方法
                return;
            }
        }
        //3. 如果name通过验证,将获取到的表单参数封装成Customer对象
        Customer customer = new Customer(id,name,address,phone);
        //4. 调用CustomerDAO的update方法
        customerDAO.update(customer);
        //5.请求重定向,避免表单重复提交
        response.sendRedirect("query.do");
    }

问题

这是我们发现,我们在修改操作的时候,当我们修改name的时候,发现在name被占用的时候会出现异常。

这个异常出现在哪?通过调试。在name被占用的时候,请求转发有问题,更具体的说是此时update.jsp页面有问题。

为什么出现异常?

因为,当用户名被占用时,从表单获取到的参数对应的对象在数据库中是不存在的,因此在请求转发到update.jsp中,对于input中的value="<%=customer.getId()%>"实际上是获取不到的,因此我们要在update.jsp中进行一个判断:
当customer不为null时,获取该对象的customer;当customer为null时,获取之前表单提交的Parameter参数

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%
    Object msg = request.getAttribute("msg");
    if(msg != null){
%>
<br>
<font color="red"><%= msg %></font>
<br><br>
<%
    }
%>
<%
    String id = null;
    String name = null;
    String oldName = null;
    String address = null;
    String phone = null;

    Customer customer = (Customer) request.getAttribute("customer");

    if (customer != null) {
        id = String.valueOf(customer.getId());
        name = customer.getName();
        oldName = customer.getName();
        address = customer.getAddress();
        phone = customer.getPhone();
    } else {
        id = request.getParameter("id");
        oldName = request.getParameter("oldName");
        name = request.getParameter("name");
        address = request.getParameter("address");
        phone = request.getParameter("phone");
    }

%>

<form action="update.do" method="post">

    <input type="hidden" name="id" value="<%=id%>"/>
    <input type="hidden" name="oldName" value="<%=oldName%>"/>

    <table>
        <tr>
            <td>CustomerName:</td>
            <td><input type="text" name="name"
                       value="<%=name%>"
            /></td>
        </tr>
        <tr>
            <td>Address:</td>
            <td><input type="text" name="address"
                       value="<%=address%>"
            /></td>
        </tr>
        <tr>
            <td>Phone:</td>
            <td><input type="text" name="phone"
                       value="<%=phone%>"
            /></td>
        </tr>
        <tr>
            <td><input type="submit" value="Update"/></td>
        </tr>
    </table>
</form>

</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值