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

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

已在 随机的 群组中发布
理解本文所需的知识:您已经或多或少地了解了Java Core,并希望了解JavaEE 技术Web 编程对您来说,目前正在研究Java Collections quest最有意义,它处理的主题与本文很接近。
使用 servlet 和 JSP 创建简单的 Web 应用程序(第 1 部分)- 1
本材料是我的文章在 IntelliJ Idea Enterprise 中创建最简单的 Web 项目的逻辑延续。在那篇文章中,我演示了如何创建一个可用的 Web 项目模板。这次我将向您展示如何使用Java Servlet APIJavaServer Pages API创建一个简单但非常有吸引力的 Web 应用程序。 我们的应用程序将有一个带有两个链接的主页:
  • 添加用户页面的链接;
  • 指向用户列表的链接。
和以前一样,我将使用IntelliJ Idea Enterprise EditionApache Maven(我们将只连接一些依赖项)和Apache Tomcat。最后,我们将使用W3.CSS框架“美化”我们的应用程序。我们假设您已经有一个我们现在要添加的空项目。如果没有,请浏览第一篇文章并制作一篇。只需几分钟 :)

关于我们未来应用程序结构的一些信息

我们的主页 (/) 将是一个最普通的静态HTML页面,带有一个标题和两个链接/按钮:
  • 添加一个新用户(导航到/添加);
  • 查看用户列表(导航至 / list)。
Tomcat将捕获对这些地址的请求并将它们发送到我们将要创建的两个 servlet 之一(我们将在web.xml中指定映射)。然后 servlet 将处理请求、准备数据(或保存数据,如果我们要添加用户),并将控制转移到适当的JSP 文件,然后“呈现”结果。我们将数据存储在普通列表(List)中。

创建一个静态主页

如果您的 web 文件夹中有index.jsp ,请将其删除。相反,在此文件夹中创建一个名为index.html的简单HTML 文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>My super project!</title>
</head>
<body>
    <!-- header -->
    <div>
        <h1>Super app!<//h1>
    </div>

    <div>       <!-- content -->
        <div>    <!-- button holder -->
            <button onclick="location.href='/list'">List users<//button>
            <button onclick="location.href='/add'">Add user<//button>
        </div>
    </div>
</body>
</html>
这里没有什么复杂的。在title标签中,我们指明了页面的标题。在页面主体中,我们有两个主要的 div:headercontent。内容div包括我们按钮的支架。我们有两个按钮,单击一下即可将您带到相应的地址。您可以运行该项目并查看它现在的样子。如果你点击按钮,你会得到404 错误页面, 因为我们对应的页面还不存在。但我们可以看出按钮有效。请注意,这不是最通用的方法:如果浏览器中的 JavaScript 被关闭,那么这些按钮将不起作用。但我们假设没有人禁用 JavaScript。:) 显然,您可以使用简单的链接,但我更喜欢按钮。你可以随心所欲地做。不要担心我的例子会有很多div。我们稍后会用样式填充它们,一切都会看起来更漂亮。:)

创建 JSP 文件以呈现结果

在同一个Web目录中,创建一个文件夹,我们将在其中添加我们的JSP 文件。我将其称为“观点”,但您还是可以即兴创作。在此文件夹中,我们将创建两个 JSP 文件:
  • add.jsp — 添加用户的页面;
  • list.jsp — 显示用户列表的页面。
为它们分配适当的页眉。像“添加新用户”和“用户列表”之类的东西,我们就这样吧。

创建两个 servlet

Servlet 将接收并处理Tomcat发送给它们的请求。在src/main/java文件夹中,创建应用程序包,我们将在其中放置源代码。其他包裹也将去那里。因此,为了防止这些包在彼此内部创建,我们将在应用程序包中创建一些类(稍后我们将删除它)。现在在应用程序包中创建三个不同的包:
  • 实体——我们的实体(描述用户对象的类)放在这里;
  • model——这是我们的模型所在的地方(我们稍后会讨论这个);
  • servlet——这就是我们的 servlet 所在的位置。
完成此操作后,您可以冷静地从应用程序包中删除该类(当然,如果您创建了它)。在servlets包中,创建两个类:
  • AddServlet — 处理发送到 / add 的请求;
  • ListServlet — 处理发送到 / list 的请求。

在 Maven 中连接依赖项

Tomcat 9. * 实现了Servlet 4.0JavaServer Pages 2.3的规范。Tomcat 9官方文档第一段第二行就是这么说的。这意味着如果您像我一样使用这个版本的Tomcat,那么您将编写和运行的代码将使用这些版本。但是我们希望在我们的项目中有这些规范,这样我们使用它们的代码至少可以成功编译。为此,我们需要将它们加载到我们的项目中。这就是Maven来拯救的地方。

一般规则是这样的:如果您需要使用 Maven 将某些东西连接到您的项目:

  • 从 Maven 转到存储库网站;
  • 查找所需库的所需版本;
  • 获取需要粘贴到 pom.xml 中的依赖代码;
  • 粘贴!:)
让我们开始。首先,准备POM 文件在/version条目之后但在/project之前的某处,插入以下内容:

<dependencies>

</dependencies>
我们这样做是为了表明我们将在这些标签中列出所需的依赖项。现在转到mvnrepository.com。顶部有一个搜索字段。首先,搜索“ servlet ”。第一个结果,已经被使用了七千多次,很适合我们。请记住,我们需要4.0版(对于Tomcat 9). 其他版本可能适用于旧的实现。这是一个相当新的版本,所以没有那么多用途。但我们需要它。将打开一个页面,您可以在其中获取各种包管理器的此依赖项的代码,或者您可以直接下载它。但由于我们想使用 Maven 连接它,我们将在 Maven 选项卡上选择代码。我们复制并粘贴到 POM 文件的依赖项部分。如果您在IDEA的右下角收到询问是否要启用自动导入的通知,请继续并同意它。如果您不小心拒绝了,请转到“设置”并手动打开自动导入:设置 (Ctrl + Alt + S) -> Build, Execution, Deployment -> Maven -> Importing和该项目的 IDEA 配置文件同步。按照相同的原则,我们将找到并连接JavaServer Pages 2.3(搜索“JSP”)。由于我们已经启动了 Maven,所以我们只需告诉它我们的源文件遵循 Java 8 语法,并且我们需要将它们编译成该版本的字节码。完成所有这些步骤后,我们的pom.xml将如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>cc.codegym.info.fatfaggy</groupId>
    <artifactId>my-super-project</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compile.source>1.8</maven.compile.source>
        <maven.compile.target>1.8</maven.compile.target>
    </properties>

    <dependencies>
        <!-- Servlet API 4.0 for tomcat 9 -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.0</version>
            <scope>provided</scope>
        </dependency>

        <!-- JavaServer Pages API 2.3 for tomcat 9 -->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.1</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

</project>

将我们的servlets变成真正的servlets

目前,我们创建的这对 servlet 实际上是普通的类。它们没有任何功能。但现在我们已经将Servlet API连接到我们的项目,因此我们可以使用它的类。要使我们的servlets“真实”,我们需要做的就是让它们继承HttpServlet类。

映射或标记

现在最好以某种方式告诉Tomcat对 / add地址的请求由我们的AddServlet处理,而对 / list地址的请求由ListServlet处理。这个过程称为映射(标记)。 这是在web.xml中使用相同的原则完成的:
  • 首先,描述 servlet(提供一些名称并指定类本身的路​​径);
  • 然后将这个 servlet 绑定到一个特定的地址(指定我们刚刚给它的 servlet 的名称,并指定其请求应该发送到这个 servlet 的地址)。
描述小服务程序:

<servlet>
    <servlet-name>add</servlet-name>
    <servlet-class>app.servlets.AddServlet</servlet-class>
</servlet>
现在将其绑定到地址:

<servlet-mapping>
    <servlet-name>add</servlet-name>
    <url-pattern>/add</url-pattern>
</servlet-mapping>
如您所见,servlet-name 在这两种情况下都是相同的。结果,Tomcat知道如果接收到 /add 请求,则必须将其发送到 app.servlets.AddServlet。我们对第二个 servlet 做同样的事情。最后我们的web.xml大概有以下内容:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <!-- add servlet -->
    <servlet>
        <servlet-name>add</servlet-name>
        <servlet-class>app.servlets.AddServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>add</servlet-name>
        <url-pattern>/add</url-pattern>
    </servlet-mapping>

    <!-- list servlet -->
    <servlet>
        <servlet-name>list</servlet-name>
        <servlet-class>app.servlets.ListServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>list</servlet-name>
        <url-pattern>/list</url-pattern>
    </servlet-mapping>
</web-app>
顺便说一下,我们没有为主页 (/) 创建标记。事实上,在这种情况下我们不需要它。我们的主页是一个简单的 HTML 文件,只显示两个按钮。它没有动态内容,所以我们不需要为来自/ 的请求创建一个单独的 servlet ,它只会将执行转发给一些JSP(也必须创建)来为我们绘制两个按钮。我们不需要这个。静态页面适合我们。当 Tomcat 收到一个请求时,它会检查是否有一个 servlet 可以处理该地址的请求,然后会看到这个地址实际上已经包含了准备好的 HTML文件,它将提供。我们可以再次运行我们的应用程序(重新启动服务器或重新部署它 - 无论您喜欢什么)并确保主页已呈现,没有任何问题,并且在我们单击按钮时发生转换(尽管我们再次收到错误)。顺便说一句,之前我们得到 404 错误,现在我们得到 405。这意味着映射有效并且找到了 servlet,但是它们没有合适的方法来处理请求。

简短的题外话:“幕后”发生了什么?

您可能已经考虑过我们的应用程序如何在 Tomcat 中运行。那里发生了什么?main() 方法在哪里?只要您在浏览器中访问 localhost:8080,浏览器就会使用 HTTP 协议向该地址发送请求。我希望您已经意识到有许多不同类型的请求,最流行的是 GET 和 POST。每个请求都应该得到答复。GET 请求预计会收到返回给浏览器的现成 HTML 代码的响应。然后浏览器将替换所有漂亮的字母、按钮和表单的代码。POST 请求更有趣一些,因为它还携带了一些信息。例如,假设您在网站的注册或登录表单中输入凭据,然后单击“发送”。这会导致将包含您的个人信息的 POST 请求发送到服务器。服务器接收此信息,对其进行处理并返回一些响应(例如,包含您的个人资料的 HTML 页面)。它们之间的主要区别在于 GET 请求仅用于从服务器检索数据,而 POST 请求携带一些信息(并且服务器上的数据可以更改)。例如,当您将图片上传到服务器时,它会在 POST 请求中携带到服务器,然后服务器将其添加到数据库中,即发生更改。现在回到 Tomcat。当它收到来自客户端的请求时,它会查看地址。它检查是否有合适的 servlet 来处理对该地址的请求(或可以立即返回的可用资源)。如果找不到要返回的东西,然后它以 404 错误而不是 HTML 页面作为响应。但是,如果它在那个地址找到一个合适的 servlet,它就会查看请求类型(GET、POST 或其他)并询问 servlet 是否有可以处理此类查询的方法。如果 servlet 说它不知道如何处理这种类型,那么Tomcat返回 405 代码。这正是我们项目中发生的事情。但是如果找到合适的 servlet,并且它有合适的方法,Tomcat就会创建一个 servlet 对象,在新线程上启动它(让它自己运行),Tomcat 继续自己的工作,接受和发送请求。此外,Tomcat 还创建了两个对象:一个 HttpServletRequest(我将简称为“请求”)和一个 HttpServletResponse(我将其称为“响应”)。它将从客户端请求中接收到的所有数据放入第一个对象中,因此可以从中提取所有数据。然后在所有这一切之后,它将这两个对象传递给在单独线程上启动的 servlet 的适当方法。一旦 servlet 完成其工作并准备好发送给客户端的响应,它就会向 Tomcat 挥动旗帜,说“我完成了。一切都准备好了”。Tomcat 收到响应并将其发送给客户端。这让 Tomcat 接收请求并发送响应,不会分心,所有工作都由运行在不同线程上的 servlet 完成。这意味着当我们编写 servlet 代码时,我们确定将执行什么工作。你可以认为 main() 方法位于 Tomcat 本身内部(是的,它是用 Java 编写的),当我们“启动”Tomcat 时,main() 方法就会启动。 使用 servlet 和 JSP 创建简单的 Web 应用程序(第 1 部分)- 2

使用 servlet 捕获 GET 方法并发送超级简单的响应

目前,我们的 servlet 没有合适的方法 (GET),因此 Tomcat 返回 405 错误。让我们创造它们!我们的 servlet 继承的 HttpServlet 类声明了各种方法。要将特定代码分配给方法,我们只需覆盖它们即可。在这种情况下,我们需要覆盖doGet()两个 servlet 中的方法。

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

}
如您所见,此方法有两个参数:req(请求)和 resp(响应)。这些正是 Tomcat 在调用 servlet 中的适当方法时为我们创建和填充的对象。首先,我们将创建最简单的响应。为此,我们将获取 resp 对象并从中获取 PrintWriter 对象。这种类型的对象用于编写响应。我们将使用它来输出一个简单的字符串。

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    PrintWriter writer = resp.getWriter();
    writer.println("GET method from AddServlet");
}
我们将在 ListServlet 中做类似的事情,然后我们将重新启动我们的服务器。如您所见,一切正常!当您单击按钮时,您将获得包含我们使用 PrintWriter“编写”的文本的页面。但是我们准备生成带有响应的页面的 JSP 文件没有被使用。那只是因为他们从未被执行过。我们的 servlet 自己创建响应并完成运行,向 Tomcat 发出信号,表明它已准备好响应客户端。Tomcat 只是获取响应并将其发送回客户端。 让我们将控制权从 servlet 传递给 JSP 文件。我们将更改方法的代码如下:
  • 我们从请求对象中获取一个请求调度器对象,并将它传递给我们要将控制转移到的 JSP 页面的地址;
  • 我们使用此对象将控制转移到指定的 JSP 页面,不要忘记传递我们从 Tomcat 接收到的请求和响应对象。

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    RequestDispatcher requestDispatcher = req.getRequestDispatcher("views/add.jsp");
    requestDispatcher.forward(req, resp);
}
在JSP页面的body标签中,可以添加一些东西,这样我们就可以清楚的看到显示的是哪个页面。完成后,重新启动服务器并检查。我们单击主页上的按钮,页面打开,这意味着请求被发送到 servlet。然后将控制权传递给现在正在呈现的 JSP 页面。目前为止就这样了。在本文的下一部分中,我们将研究应用程序的功能。
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION