本资料是“企业发展概论”系列的一部分。往期文章:
您是否已经知道如何编写在控制台上显示文本的 Java 应用程序,但您仍然不知道如何创建您的第一个 Web 应用程序?太好了,让自己舒服。在本文中,我们将熟悉 servlet 并编写一个您可以向朋友吹嘘的应用程序,而无需向他们发送 JAR 文件,也无需强迫他们下载 Java。让我们编写一个简单的Web 应用程序。如果您还不熟悉 Web 开发中使用的方法,我建议您先阅读“企业开发简介”系列中的第一篇文章。
您是否已经知道如何编写在控制台上显示文本的 Java 应用程序,但您仍然不知道如何创建您的第一个 Web 应用程序?太好了,让自己舒服。在本文中,我们将熟悉 servlet 并编写一个您可以向朋友吹嘘的应用程序,而无需向他们发送 JAR 文件,也无需强迫他们下载 Java。让我们编写一个简单的Web 应用程序。如果您还不熟悉 Web 开发中使用的方法,我建议您先阅读“企业开发简介”系列中的第一篇文章。
什么是小服务程序?
首先,让我们弄清楚什么是 servlet 以及为什么您会如此频繁地听到它们。Java Servlet API是一种旨在在服务器上实现的标准化 API。它根据请求-响应方案与客户端进行交互。servlet是一个可以接收来自客户端的请求并将响应返回给客户端的类。事实上,servlet 正是我们用来在 Java 中创建客户端-服务器体系结构的构建块。您可能还记得我们已经在本系列的另一篇文章中讨论过该架构。我们不会拐弯抹角:让我们立即编写一些代码。创建 Web 应用程序所需的条件
为了在使用 Java servlet 时获得最大便利,您需要 IntelliJ IDEA Ultimate Edition。它是付费产品,但您可以激活 30 天试用版或使用始终免费的抢先体验版。此外,安装 Apache Tomcat — 我们应用程序的服务器。Tomcat 是一个 servlet 容器:它处理传入的请求并将它们传递给我们的应用程序。在此处下载 Tomcat 。让我们创建我们的第一个 Web 应用程序
如果一切就绪,创建一个 Maven 项目。如果您不熟悉 Maven,请查看上一篇文章。让我们开始!-
在pom.xml中添加javax.servlet-api依赖,指定WAR打包:
<?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>org.example</groupId> <artifactId>servlets</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> </dependency> </dependencies> </project>简单的 servlet 类:
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 java.io.IOException; import java.io.PrintWriter; @WebServlet("/hello") public class MainServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html"); PrintWriter printWriter = resp.getWriter(); printWriter.write("Hello!"); printWriter.close(); } } -
要运行该应用程序,您需要创建一个 Tomcat 配置:
![第 5 部分。Servlet 和 Java Servlet API。 编写一个简单的 Web 应用程序 - 2]()
-
接下来,我们指出我们将使用哪个版本的 Tomcat,以及与服务器通信的 URL 和端口。你应该有这样的东西:
![第 5 部分。Servlet 和 Java Servlet API。 编写一个简单的 Web 应用程序 - 4]()
-
现在我们只需要指定将部署在容器中的工件(JAR 存档中的组装项目)。您可以单击Fix按钮并选择war exploded:这意味着在重建项目后,工件将自动放置在 servlet 容器中。
![第 5 部分。Servlet 和 Java Servlet API。 编写一个简单的 Web 应用程序 - 5]()
-
应用上下文的默认值是servlets_war_exploded。这意味着我们在以下位置访问应用程序:http://localhost:8080/servlets_war_exploded。
为什么我们需要任何额外的文本?让我们删除不需要的东西。现在我们的 Web 应用程序的地址是:http://localhost:8080。
![第 5 部分。Servlet 和 Java Servlet API。 编写一个简单的 Web 应用程序 - 6]()
-
单击确定。我们看到我们现在可以启动应用程序了:
现在,当您在浏览器中打开该应用程序时,您应该会收到 404 错误。这是有道理的,因为地址http://localhost:8080/需要一个映射到“/”的 servlet,但我们唯一的 servlet 映射到“/hello”。
-
我们可以在http://localhost:8080/hello访问它。一旦我们这样做了,我们就会得到预期的答案——字符串“Hello”!
@WebServlet()注释。这是我们将 servlet 绑定(或映射)到特定路径(“/hello”)的地方。这个注解只出现在Java Servlet API 3.0,所以网上有很多通过XML文件进行servlet映射的例子。这不再是必要的。为了处理 GET 请求,我们覆盖了该doGet()方法。注意方法的参数:HttpServletRequest和HttpServletResponse。该HttpServletRequest对象为我们提供了有关请求的所有必要信息。在 中HttpServletResponse,我们编写响应并设置必要的标头。
使用参数和会话
让我们改进我们的 servlet,以便它可以处理请求参数并使用会话:
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 javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/hello")
public class MainServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
Integer visitCounter = (Integer) session.getAttribute("visitCounter");
if (visitCounter == null) {
visitCounter = 1;
} else {
visitCounter++;
}
session.setAttribute("visitCounter", visitCounter);
String username = req.getParameter("username");
resp.setContentType("text/html");
PrintWriter printWriter = resp.getWriter();
if (username == null) {
printWriter.write("Hello, Anonymous" + "<br>");
} else {
printWriter.write("Hello, " + username + "<br>");
}
printWriter.write("Page was visited " + visitCounter + " times.");
printWriter.close();
}
}
visitCounter现在 servlet 与会话一起工作,每次访问页面时 都会增加值。如果visitCounter尚未创建属性(在第一次访问页面时),该getAttribute()方法返回 null,因此我们需要检查是否为 null。请求参数也是如此。如果用户没有传递用户名参数,那么它的值将为空。在这种情况下,我们将用户视为匿名访客。要在 GET 请求中传递参数,使用查询字符串,例如,我们可以使用以下 URL:http://localhost:8080/hello? 用户名=保罗。您可以在上一篇文章中阅读有关 HTTP 请求的更多信息在系列中。我们的应用程序目前没有太多逻辑,但我们在根路径处遇到 404 错误有点烦人。为了解决这个问题,我们将创建另一个 servlet 并将其映射到起始页:@WebServlet("/")。这个 servlet 的目的是将请求重定向到“/hello”路径。有两种方法可以做到这一点:使用“转发”或“重定向”。也许值得了解它们之间的区别。转发将请求的处理委托给服务器上的另一个 servlet。客户不参与。为此,将以下代码添加到新的 servlet 的 doGet() 方法中:
getServletContext().getRequestDispatcher("/hello").forward(req, resp);
在这段代码中,我们访问 servlet 上下文,获取相关 servlet 的请求分派器,并要求它处理带有指定参数 (req, resp) 的特定请求。重定向向客户端返回客户端必须用于处理其请求的地址。大多数浏览器会自动导航到返回的 URL。要实现重定向,您需要添加以下代码:
resp.sendRedirect(req.getContextPath() + "/hello");
我们redirect()在HttpServletResponse参数上调用该方法,并将客户端需要使用的地址传递给它。这里有一个重要的细节:还必须在完整重定向路径的末尾添加 HTTP 参数,这不是很方便。在我们的情况下,最好使用forward,但有时使用redirect更好。如果您了解它们工作方式的不同,就不会做出错误的选择。新 servlet 的代码如下所示:
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 java.io.IOException;
@WebServlet("/")
public class IndexServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// getServletContext().getRequestDispatcher("/hello").forward(req, resp);
resp.sendRedirect(req.getContextPath() + "/hello");
}
}




GO TO FULL VERSION