本資料是“企業發展概論”系列的一部分。往期文章:
您是否已經知道如何編寫在控制台上顯示文本的 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 配置:
-
接下來,我們指出我們將使用哪個版本的 Tomcat,以及與服務器通信的 URL 和端口。你應該有這樣的東西:
-
現在我們只需要指定將部署在容器中的工件(JAR 存檔中的組裝項目)。您可以單擊Fix按鈕並選擇war exploded:這意味著在重建項目後,工件將自動放置在 servlet 容器中。
-
應用上下文的默認值是servlets_war_exploded。這意味著我們在以下位置訪問應用程序:http://localhost:8080/servlets_war_exploded。
為什麼我們需要任何額外的文本?讓我們刪除不需要的東西。現在我們的 Web 應用程序的地址是:http://localhost:8080。
-
單擊確定。我們看到我們現在可以啟動應用程序了:
現在,當您在瀏覽器中打開該應用程序時,您應該會收到 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