寫在前面
上一篇文章 在 Tomcat 上部署你的第一個 Servlet 應用 使用最原始的指令行方式編譯 Servlet 類,并且部署到 tomcat 安裝目錄下的 webapps 檔案夾下。但是實際情況下,我們現在的工作已經十分依賴內建開發工具 IDEA 了,本文就借助 IDEA 建立一個 Servlet ,并且在 IDEA 工具内通過 tomcat 來啟動服務和本地調試。
項目位址
git clone https://gitee.com/kendoziyu/code-servlet-parent.git
其中,develop-servlet 就是本文的項目。
1.建立項目
首先 File -> New -> Project... 打開建立項目視窗
接着就是給你的項目找一個合适的名字和合适的路徑,我的項目命名為 develop-servlet
點選 Finish 完成建立,并且在新的視窗中打開項目。
自動建立的模闆,為我們建立了以下檔案:
/web/WEB-INF/web.xml
/web/index.jsp
*自定義修改
首先,這個 web 檔案夾的取名,不太符合我的習慣,我更喜歡命名為 webapp。
右擊 web 檔案夾 --> Refactor --> Rename...
另外,目前 3.1 是穩定版本,4.0 是 alpha 版本,是以我們稍稍改動一下 web.xml,把 servlet 版本改為 3.1
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">
2.添加 Servlet 依賴
在 tomcat 安裝目錄下的 lib 下有 servlet-api.jar,而我的 tomcat 安裝目錄是 D:\server\apache-tomcat-9.0.39
接着我們在 idea 中添加依賴庫,我們先通過 File --> Project Structure... 打開視窗:
D:\server\apache-tomcat-9.0.39\lib\servlet-api.jar
3.建立 LoginServlet
package coderead.servlet;
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 LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().write("
Hello World
");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
4. 配置 web.xml
我們聲明一個名為 loginServlet 的 servlet 對應類 coderead.servlet.LoginServlet,并且配置它的攔截 url 位址為 /Login
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">
loginServlet
coderead.servlet.LoginServlet
loginServlet
/Login
5. 添加運作項
我們打算用 tomcat 的方式來運作我們的項目,首先我們要 Add Configuration...
然後在 Run/Debug Configuration 視窗,選擇 Tomcat Server -> Local
接着我們就需要設定應用伺服器 Applicaiton Server:
點選 Configure... 打開了 Tomcat Server 視窗,我選擇了一下本地 Tomcat 安裝目錄 D:\server\apache-tomcat-9.0.39,并選擇 Ok
此時,在 Run/Debug Configuration 視窗出現一個 Warning: No artifacts configured
點選 Fix ,如果你的 IDEA 版本沒有出現這個警告和 Fix 按鈕,那也請不要慌張,選擇 File -> Project Structure 即可。
6. 配置 Web Module
如果你不是用 idea 直接建立的 Web Application(比如是用 git clone 下來的代碼,或者你自己手動建立的 webapp 檔案夾),那你可以看一下,你的 webapp 檔案夾上并沒有一些“特殊的記号”。此時我們可以先添加 Web 子產品,後建立 Artifact,這樣會快很多。
如果你的 webapp 檔案夾上已經有一個“小藍點”,那你可能可以直接跳至第 7 步,前提是你确定你的配置是正确的。在 Project Structure 視窗下,選擇 Modules
添加後效果如下圖所示,接着我們要修改 Web Module Deployment Descriptor 和 Web Resource Directory。
滑鼠懸浮至 + 和 - 下方的 >>,會出現編輯按鈕:
編輯 Web Module Deployment Descriptor 選擇 項目根目錄路徑\webapp\WEB-INF\web.xml,版本選擇 3.1 ,和 web.xml 中的版本一緻。
編輯 Web Resource Directory,選擇項目根目錄下的 webapp 目錄
7. 建立 Artifact
如果你做了 6 步,那麼你可以直接選擇 Create Artifact。
如果你不是用 Create Artifact 方式,那就需要你自己選擇 Artifact 的類型:
如果選 Web Application: Exploded,這個是以檔案夾形式(War Exploded)釋出項目,選擇這個,釋出項目時就會自動生成檔案夾在指定的 output directory;
如果選 Web Application: Archive,就是 war 包形式,每次都會重新打包全部的,将項目打成一個 war 包,放到指定位置;
8. 部署
再次選擇 Add Configuration... ,打開 Run/Debug Configurations, + -> Tomcat Server -> Local ,切換到 Deployment,發現已經把 Artifact 自動添加進去了。
這裡的 develop-servlet 是由第 7 步上面的圖檔 Artifact - Name 所決定的,同時也會影響 Web 項目的 ContextPath。第 7 步 Artifact 的 Output Directory 最終目錄是 develop_servlet,是以 ContextPath 也是 develop_servlet。
也就是說我們應該在浏覽器中通過 http://localhost:8080/ 的通路結果為
* 選擇輸出目錄
還是因為我是 git clone 得到的項目,沒有配置輸出目錄,彈出這個報錯:
我們可以在 Project Structure 視窗,配置 Project compiler output 為 項目根目錄\out
9. jsp 調用 Servlet
首次打開時,會進入 index.jsp,如果沒登入,我希望通過 jsp 調用 Servlet。
User: kendoziyu
Date: 2020/10/21
--%>
首頁
String loginName = (String) request.getSession().getAttribute("loginName");
%>
if (loginName == null || loginName.isEmpty()) {
%>
去登入
Hello,
不過,此時點選“去登入”,直接跳轉 http://localhost:8080/Login,結果 404 找不到頁面,稍微改造一下:
方法一:可以修改連結位址為相對位址
去登入
适用場景:目前頁面是在 WebRoot 路徑下。
方法二:目标 URL 前面加上請求 ContextPath 字首
首頁
String loginName = (String) request.getSession().getAttribute("loginName");
String prefix = request.getContextPath();
%>
if (loginName == null || loginName.isEmpty()) {
%>
去登入
Hello,
10. Servlet 跳轉 jsp
方法一: sendRedirect 方式
sendRedirect("/a.jsp");
可以将頁面跳轉到任何路徑,不局限于web應用中,跳轉的過程中url位址變化,無法使用request.setAttribute來傳遞。
方法二:forward 方式
request.getRequestDispatcher("/a.jsp").forward(request.response);
url位址不變,隻能跳轉到本web應用中的頁面上。可以用 request.setAttibute 方法
我們改寫一下 LoginServlet
package coderead.servlet;
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 LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// response.getWriter().write("
Hello World
");
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getSession().setAttribute("loginName", request.getParameter("username"));
response.sendRedirect("index.jsp");
}
}
login.jsp
登入
username:
password:
參考文章