CodeGym/Java 博客/随机的/使用 servlet 和 JSP 创建简单的 Web 应用程序(第 2 部分)
John Squirrels
第 41 级
San Francisco

使用 servlet 和 JSP 创建简单的 Web 应用程序(第 2 部分)

已在 随机的 群组中发布
个会员
使用 servlet 和 JSP 创建一个简单的 Web 应用程序(第 1 部分) 理解本文所需的知识:您已经或多或少地了解了 Java Core,并希望了解 JavaEE 技术和 Web 编程。对您来说,目前正在研究 Java Collections 任务是最有意义的,它处理的主题与本文很接近。
使用 servlet 和 JSP 创建简单的 Web 应用程序(第 2 部分)- 1

创建实体

entities包中,我们将创建一个User具有两个私有字符串变量的类:namepassword。创建构造函数(默认构造函数和一个同时接受两个值的构造函数)和 getter/setter,并重写该toString()方法以防万一,以及equals()hashCode()方法。换句话说,我们将做一个受人尊敬的 Java 开发人员在创建类时所做的一切。
public class User {
    private String name;
    private String password;

    public User() {
    }

    public User(String name, String password) {
        this.name = name;
        this.password = password;
    }

    public String getName() {
        return name;
    }

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

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", password='" + password + '\'' +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        User user = (User) o;

        if (name != null ? !name.equals(user.name) : user.name != null) return false;
        return password != null ? password.equals(user.password) : user.password == null;

    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + (password != null ? password.hashCode() : 0);
        return result;
    }
}
现在我们可以开始创建用户列表了。我们将向其中添加用户,并从中获取用户以显示它们。但是,我们确实有一个问题。我们不创建我们的 servlet 对象。Tomcat为我们做了这件事。我们在其中重写的方法已经为我们定义好了,我们不能传参。那么我们如何创建一个在我们的两个 servlet 中都可见的共享列表呢?如果我们只是在每个 servlet 中创建一个列表对象,那么我们会将用户添加到一个列表中,但会在 ListServlet 中显示另一个列表中的用户. 所以我们需要一个由两个 servlet 共享的对象。一般来说,我们需要一个由我们程序中的所有类共享的对象:一个对象用于整个程序。我希望你听说过一些关于设计模式的事情。对于某些人来说,这可能是他们程序中第一次真正需要单例模式。您可以疯狂地制作一些带有双重检查和同步的甜蜜单例(是的,我们的应用程序是多线程的,因为 Tomcat servlet 在单独的线程上运行)。但我将使用早期初始化技术,因为它完全可以满足我们的目的。

创建模型

在模型包中创建一个类(并实现单例模式)并将其命名为不寻常的东西。例如,模型。我们将在我们的类中创建一个私有用户列表,并实现两个方法:一个添加用户,另一个返回字符串列表(用户名)。由于我们的用户对象包含用户名和密码,并且我们不想泄露用户密码,因此我们只有一个名称列表。
public class Model {
    private static Model instance = new Model();

    private List<User> model;

    public static Model getInstance() {
        return instance;
    }

    private Model() {
        model = new ArrayList<>();
    }

    public void add(User user) {
        model.add(user);
    }

    public List<String> list() {
        return model.stream()
                .map(User::getName)
                .collect(Collectors.toList());
    }
}

关于MVC的一点

由于您已经听说过singleton,因此您可能听说过另一种设计模式模型-视图-控制器(MVC)。其目的是将业务逻辑与视图分开。也就是说,将决定做什么的代码与决定如何显示东西的代码分开。视图负责数据的呈现方式在我们的例子中,视图是我们的JSP 页面。这正是我将它们放在名为views的文件夹中的原因。 模型是程序实际使用的数据。在我们的例子中,这是用户(用户列表)。而控制器是它们之间的纽带。他们从模型中获取数据并将其传递给视图(或者从Tomcat中获取一些数据,对其进行处理,并将其传递给模型)。您在其中定义您的业务逻辑(程序应该做什么),而不是在模型或视图中。因此,每个部分处理自己的业务:
  • 模型存储数据;
  • 视图呈现数据的漂亮表示;
  • 控制器处理数据处理。
这允许程序非常简单和可维护,而不是一个类中所有代码的巨大堆。 MVC不仅适用于 Web 编程,而且在该领域中使用得特别频繁(几乎总是如此)。在我们的例子中,servlet 将充当控制器。这是对模式的非常肤浅和简短的描述,但MVC不是本文的主题。如果有人想了解更多,谷歌是你的朋友! 创建用于添加用户的表单。 将表单添加到add.jsp。它应该由两个文本输入字段(一个普通字段,另一个 - 密码字段)和一个用于将数据发送到服务器的按钮组成。
<form method="post">
    <label>Name:
        <input type="text" name="name"><br />
    </label>

    <label>Password:
        <input type="password" name="pass"><br />
    </label>
    <button type="submit">Submit</button>
</form>
这里的表单有一个method属性,其值为post。这表示此表单中的数据将作为POST 请求发送到服务器。未指定action属性,这意味着请求将发送到我们访问此页面的相同地址 ( / add )。因此,在收到GET 请求后,绑定到该地址的 servlet 会返回带有添加用户表单的JSP 。如果它收到一个POST 请求,那么我们就知道表单在这里发送了它的数据(我们从doPost()方法、过程,并传递给模型进行保存)。值得注意的是,输入字段有一个名为name的参数(用于用户名,或pass用于密码)。这是非常重要的一点。因此,要从请求(在 servlet 内)接收此数据(将输入的用户名和密码),我们将使用这些名称传递字段。但稍后会详细介绍。我用于发送数据的按钮再次被制作为按钮而不是通常的输出字段。我不知道这种方法的采用有多广泛,但它适用于我(Chrome 浏览器)。

POST 请求的 Servlet 处理

让我们回到AddServlet。我提醒您,为了让我们的 servlet 能够“捕获” GET 请求,我们覆盖了HttpServletdoGet()类中的方法。为了让我们的 servlet 也能捕获POST 请求,我们还必须覆盖该方法。Tomcat向它传递我们将使用的类似请求和响应对象。首先,提取请求的名称并传递表单发送的参数(如果您在表单中指定了不同的名称,则使用这些名称)。之后,使用接收到的数据创建一个用户对象。然后我们获取模型对象并将创建的用户添加到模型中。 doPost()
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String name = req.getParameter("name");
    String password = req.getParameter("pass");
    User user = new User(name, password);
    Model model = Model.getInstance();
    model.add(user);
}

将数据传递给视图

让我们继续讨论ListServlet。该doGet()方法已经实施。它只是将控制转移到视图 ( list.jsp )。如果您还没有这个,则类比 AddServlet 中的方法创建。现在最好从模型中获取用户名列表并将它们传递给视图,视图将接收它们并漂亮地显示它们。为此,我们将再次使用从Tomcat收到的请求对象。我们可以给这个对象添加一个属性,给它起一个名字。其实我们可以把我们要传递的对象添加到视图. 由于在将控制从 servlet 转移到视图时,我们向视图传递了与 servlet 接收到的相同的请求和响应对象,因此我们可以将名称列表添加到请求对象,然后从请求中获取用户名列表视图中的对象。我们已经完成了ListServlet类,所以我将在这里展示整个类的代码:
package app.servlets;

import app.model.Model;

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.util.List;

public class ListServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Model model = Model.getInstance();
        List<String> names = model.list();
        req.setAttribute("userNames", names);

        RequestDispatcher requestDispatcher = req.getRequestDispatcher("views/list.jsp");
        requestDispatcher.forward(req, resp);
    }
}

在 JSP 文件中运行 Java 代码

是时候查看list.jsp了。它只会在ListServlet将控制权转移给它时执行。此外,我们已经从 servlet 中的模型准备了用户名列表,并将其传递到请求对象中。由于我们有姓名列表,我们可以使用循环对其进行迭代for并显示每个姓名。正如我之前所说,JSP 文件可以执行Java 代码(这就是它们与静态 HTML 页面的不同之处)。要执行一些代码,我们需要做的就是将以下结构放在适当的位置:
<!-- html code -->
<%
    // Java code
%>
<!-- html code -->
在这个结构中,我们可以访问几个变量:
  • request — 我们的请求对象,我们从 servlet 传递过来的,它被简称为req
  • response — 响应对象(在 servlet 中称为resp );
  • out — 一个JspWriter对象(它继承了一个普通的Writer),我们可以使用它来将某些内容直接“写入”到HTML 页面本身。语句out.println("Hello, World!")与System.out.println("Hello, World!")非常相似,但不要混淆它们!
  • out.println() “写入”到HTML 页面,而System.out.println写入系统输出流。如果您使用Java 代码JSP部分中调用System.out.println() ,您将在Tomcat控制台中看到结果,而不是在页面上。
您可以在此处查找 JSP 中可用的其他对象。我们可以使用request对象获取从 servlet 传递的名称列表(我们将相应的属性附加到该对象),然后使用 out对象显示这些名称。让我们显示它们(暂时,作为一个简单的 HTML 列表):
<ul>
    <%
        List<String> names = (List<String>) request.getAttribute("userNames");

        if (names != null && !names.isEmpty()) {
            for (String s : names) {
                out.println("<li>" + s + "</li>");
            }
        }
    %>
</ul>
如果我们只需要在有用户时显示列表,否则显示没有用户的警告,那么我们可以稍微改写这部分:
<%
    List<String> names = (List<String>) request.getAttribute("userNames");

    if (names != null && !names.isEmpty()) {
        out.println("<ui>");
        for (String s : names) {
            out.println("<li>" + s + "</li>");
        }
        out.println("</ui>");
    } else out.println("<p>There are no users yet!</p>");
%>
现在我们知道如何将数据从 servlet 传递到视图,我们可以改进我们的AddServlet以便它显示有关成功添加用户的通知。为此,在doPost()方法中,在将新用户添加到模型后,我们可以将此用户名添加到req对象的属性并将控制权传回视图( add.jsp )。现在我们将向其中添加一个带有 Java 代码的部分,我们将在其中检查请求是否具有这样的属性,如果有,那么我们将显示一条消息,表明用户已成功添加。完成这些更改后,AddServlet的完整代码将如下所示:
package app.servlets;

import app.entities.User;
import app.model.Model;

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;

public class AddServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        RequestDispatcher requestDispatcher = req.getRequestDispatcher("views/add.jsp");
        requestDispatcher.forward(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String name = req.getParameter("name");
        String password = req.getParameter("pass");
        User user = new User(name, password);
        Model model = Model.getInstance();
        model.add(user);

        req.setAttribute("userName", name);
        doGet(req, resp);
    }
}
在这里,在方法的末尾,doPost()我们创建了一个属性,其中包含添加到模型中的用户的名称,然后调用该doGet()方法,我们将当前请求和响应传递给该方法。该doGet()方法现在将控制权转移到视图,该视图还接收请求对象,并将添加的用户的名称附加为属性。我们剩下要做的是修复add.jsp,以便在没有此类属性时显示通知。这是add.jsp的最终版本:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>Add new user</title>
    </head>

    <body>
        <div>
            <h1>Super app!</h1>
        </div>

        <div>
            <%
                if (request.getAttribute("userName") != null) {
                    out.println("<p>User '" + request.getAttribute("userName") + "' added!</p>");
                }
            %>
            <div>
                <div>
                    <h2>Add user</h2>
                </div>

                <form method="post">
                    <label>Name:
                        <input type="text" name="name"><br />
                    </label>
                    <label>Password:
                        <input type="password" name="pass"><br />
                    </label>
                    <button type="submit">Submit</button>
                </form>
            </div>
        </div>

        <div>
            <button onclick="location.href='/'">Back to main</button>
        </div>
    </body>
</html>
页面主体由以下部分组成:
  • 带有标题的 div;
  • 内容的 div 容器,其中包括检查是否存在具有用户名的属性;
  • 带有添加用户表单的 div;
  • 在底部,一个带有返回主页按钮的页脚。
这可能看起来像太多的 div,但我们稍后会在添加样式时使用它们。这是list.jsp的最终版本:
<%@ page import="java.util.List" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>Users</title>
    </head>

    <body>
        <div>
            <h1>Super app!</h1>
        </div>

        <div>
            <div>
                <div>
                    <h2>Users</h2>
                </div>
                <%
                    List<String> names = (List<String>) request.getAttribute("userNames");

                    if (names != null && !names.isEmpty()) {
                        out.println("<ui>");
                        for (String s : names) {
                            out.println("<li>" + s + "</li>");
                        }
                        out.println("</ui>");
                    } else out.println("<p>There are no users yet!</p>");
                %>
            </div>
        </div>

        <div>
            <button onclick="location.href='/'">Back to main</button>
        </div>
    </body>
</html>
因此,我们有一个可以保存和添加用户并显示他们姓名列表的完整工作的 Web 应用程序。现在我们只需要让它漂亮...... :) 使用 servlet 和 JSP 创建简单的 Web 应用程序(第 2 部分)- 2

添加样式。我们将使用 W3.CSS 框架

目前,我们的应用程序可以运行,但它看起来绝对离谱。因此,让我们添加背景、为文本和按钮着色、为列表添加样式、对齐元素、添加缩进等等。手动编写样式会花费大量时间并耗费我们的精力。所以我建议使用W3.CSS框架。它已经有带有样式的现成类。我们只需要将要使用的 CSS 类安排在正确的位置即可。要将它们添加到我们的页面,我们首先连接样式文件。有两种方法可以做到这一点:
  1. 浏览我们的页面并在标题部分插入以下样式文件的直接链接

    <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">

    如果您有永久的 Internet 连接,则此选项适用。当您在本地服务器上打开您的页面时,样式将从 Internet 中提取。

  2. 但是如果你想在本地拥有所有样式而不依赖于 Internet 连接,请下载样式文件并将其放在 web文件夹中的某个位置(例如web/styles/w3.css)。然后浏览我们所有的页面(index.html、add.jsp、list.jsp)并将以下链接添加到head部分内的样式文件:

    <link rel="stylesheet" href="styles/w3.css">

    之后,只需浏览标签并添加您喜欢的样式即可。这个我就不详细说了。相反,我将只提供我的三个带有光栅样式类的文件的即用型版本。

索引.html
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Super app!</title>
        <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
    </head>

    <body class="w3-light-grey">
        <div class="w3-container w3-blue-grey w3-opacity w3-right-align">
            <h1>Super app!</h1>
        </div>

        <div class="w3-container w3-center">
            <div class="w3-bar w3-padding-large w3-padding-24">
                <button class="w3-btn w3-hover-light-blue w3-round-large" onclick="location.href='/list'">List users</button>
                <button class="w3-btn w3-hover-green w3-round-large" onclick="location.href='/add'">Add user</button>
            </div>
        </div>
    </body>
</html>
添加.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>Add new user</title>
        <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
    </head>

    <body class="w3-light-grey">
        <div class="w3-container w3-blue-grey w3-opacity w3-right-align">
            <h1>Super app!</h1>
        </div>

        <div class="w3-container w3-padding">
            <%
                if (request.getAttribute("userName") != null) {
                    out.println("<div class=\"w3-panel w3-green w3-display-container w3-card-4 w3-round\">\n" +
                            "   <span onclick=\"this.parentElement.style.display='none'\"\n" +
                            "   class=\"w3-button w3-margin-right w3-display-right w3-round-large w3-hover-green w3-border w3-border-green w3-hover-border-grey\">×</span>\n" +
                            "   <h5>User '" + request.getAttribute("userName") + "' added!</h5>\n" +
                            "</div>");
                }
            %>
            <div class="w3-card-4">
                <div class="w3-container w3-center w3-green">
                    <h2>Add user</h2>
                </div>
                <form method="post" class="w3-selection w3-light-grey w3-padding">
                    <label>Name:
                        <input type="text" name="name" class="w3-input w3-animate-input w3-border w3-round-large" style="width: 30%"><br />
                    </label>
                    <label>Password:
                        <input type="password" name="pass" class="w3-input w3-animate-input w3-border w3-round-large" style="width: 30%"><br />
                    </label>
                    <button type="submit" class="w3-btn w3-green w3-round-large w3-margin-bottom">Submit</button>
                </form>
            </div>
        </div>

        <div class="w3-container w3-grey w3-opacity w3-right-align w3-padding">
            <button class="w3-btn w3-round-large" onclick="location.href='/'">Back to main</button>
        </div>
    </body>
</html>
列表.jsp
<%@ page import="java.util.List" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>Users list</title>
        <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
    </head>

    <body class="w3-light-grey">
        <div class="w3-container w3-blue-grey w3-opacity w3-right-align">
            <h1>Super app!</h1>
        </div>

        <div class="w3-container w3-center w3-margin-bottom w3-padding">
            <div class="w3-card-4">
                <div class="w3-container w3-light-blue">
                    <h2>Users</h2>
                </div>
                <%
                    List<String> names = (List<String>) request.getAttribute("userNames");

                    if (names != null && !names.isEmpty()) {
                        out.println("<ul class=\"w3-ul\">");
                        for (String s : names) {
                            out.println("<li class=\"w3-hover-sand\">" + s + "</li>");
                        }
                        out.println("</ul>");

                    } else out.println("<div class=\"w3-panel w3-red w3-display-container w3-card-4 w3-round\">\n"
+
                            "   <span onclick=\"this.parentElement.style.display='none'\"\n" +
                            "   class=\"w3-button w3-margin-right w3-display-right w3-round-large w3-hover-red w3-border w3-border-red w3-hover-border-grey\">×</span>\n" +
                            "   <h5>There are no users yet!</h5>\n" +
                            "</div>");
                %>
            </div>
        </div>

        <div class="w3-container w3-grey w3-opacity w3-right-align w3-padding">
            <button class="w3-btn w3-round-large" onclick="location.href='/'">Back to main</button>
        </div>
    </body>
</html>
就是这样。:) 如果您还有任何问题或意见,或者有什么不对,请发表评论。我将附上几张截图,说明结果如何。
使用 servlet 和 JSP 创建简单的 Web 应用程序(第 2 部分)- 3
使用 servlet 和 JSP 创建简单的 Web 应用程序(第 2 部分)- 4
使用 servlet 和 JSP 创建简单的 Web 应用程序(第 2 部分)- 5
最后,如果你想练习这个项目,你可以尝试以下方法:
  • 制作一个 servlet 和 JSP 来删除用户,并添加另一对来编辑现有用户。结果将是使用 servlet 构建的真正的 CRUD Web 应用程序。;)
  • 将List替换为数据库,这样添加的用户不会在服务器重启后消失。:)
祝你好运!
评论
  • 受欢迎
你必须先登录才能发表评论
此页面还没有任何评论