Java Web 實戰 21 - 用 Servlet 實現一個Hello World

用 Servlet 來寫一個 Hello World~

  • 一 . 基本部署方式
    • 1.1 創建 Servlet 項目
    • 1.2 引入依賴
    • 1.3 創建目錄
    • 1.4 編寫代碼
      • 繼承 HttpServlet
      • 重寫 doGet 方法
      • 刪除 super 方法
      • 加上 @WebServlet 注解
      • 寫業務邏輯
    • 1.5 打包
    • 1.6 部署
    • 1.7 驗證
    • 1.8 小結
  • 二 . 更方便的部署方式
    • 2.1 Smart Tomcat 的安裝
    • 2.2 Smart Tomcat 的配置
    • 2.3 Smart Tomcat 的使用
    • 2.4 Smart Tomcat 的原理
  • 三 . 常見錯誤
    • 3.1 404
    • 3.2 405
    • 3.3 500
    • 3.4 返回空白頁面
    • 3.5 無法訪問此網站
    • 3.6 返回中文亂碼
  • 四 . 擴展 : 什么是 JSP ?

Hello , 大家好 , 今天給大家帶來的是我們 Java 當中最基礎的框架 : Servlet , 那 Servlet 最核心的作用就是用來制作網頁端的程序 , 我們通過學習 Servlet 的語法以及相關 API , 就可以寫出一些網頁程序 .

那這個階段的程序與之前學習的單機程序不同 , 難度上也加大了 , 代碼的題量也更大了 , 這就要求大家跟進腳步 , 不要掉隊 , 以練帶學 !

博主這篇文章主要給大家講解一下 怎樣創建一個 Servlet 程序并且寫出第一個 Servlet 版本的 Hello World

那希望大家跟緊步伐 , 站穩腳跟 !
在這里插入圖片描述
大家也可以訂閱 JavaWeb 專欄 , 點擊即可跳轉

準備好 , 我們要開始發車了 !

一 . 基本部署方式

1.1 創建 Servlet 項目

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

這樣就成功創建一個 Servlet 程序了

那么 , 我們首先需要了解我們創建的 Maven 是用來干什么的?

Maven 是一個構建工具 , 我們主要用它來進行依賴管理以及打包 .
我們首次使用 Maven , 可能會出現問題 .
由于 Maven 有很多依賴 , 需要通過網絡來加載 , 而 Maven 的服務器是在國外 , 所以咱們下載速度會有點慢 , 30min~1h 都是正常現象
像這種情況 , 就是在下載依賴
在這里插入圖片描述

另外 , 其實如果真的下載特別慢 , 可以去嘗試修改一下鏡像源為國內的鏡像源 . 但是輕易不要更改 , 很有可能就改壞了 , 那就不好整了

那么我們來看一下 Servlet 程序的基本構成吧
在這里插入圖片描述

1.2 引入依賴

我們剛才不是提到了依賴了嗎 , Maven 里面自己就有依賴啊 ? 咋還導入呢?
我們這里引入的依賴 , 是寫 Servlet 程序 , 需要的依賴 , 也就是 Servlet 的 jar 包
我們需要把 jar 包下載導入到項目中
我們之前學習 JDBC 的時候 , 就手動導入過依賴 , 假如依賴比較少 , 我們可以手動導入 , 那依賴要是很多呢?
我們的 Maven 就可以幫我們自動下載 , 然后導入依賴
那么怎么弄呢 ?
我們先要去 Maven中央倉庫 下載
https://mvnrepository.com/
剛開始進去會有驗證 , 驗證一下就可以了
進來之后就是這樣 , 然后搜索 Servlet 即可
在這里插入圖片描述
在這里插入圖片描述

往下翻 , 找到 3.1.0 (劃重點)
在這里插入圖片描述

我們使用的是 JDK 8 , Tomcat 8.5 , Servlet 3.1 ,這個搭配就是 Tomcat 官方推薦的 , 放心使用

點擊之后 , 下面就有個 Maven , 復制下來
在這里插入圖片描述

<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope>
</dependency>

接下來回到我們的 IDEA , 點擊 pom.xml , 在 里面寫 標簽 , 然后把剛才復制過來的粘貼進去
在這里插入圖片描述

如果以后還有依賴 , 放在 標簽里面就行了
由于我們是第一次使用 , 他爆紅了 , 沒關系. 他會在中央倉庫下載依賴 , 需要一定時間.
如果沒有自動下載的話 , 我們還可以手動刷新一下
點擊右側的Maven
在這里插入圖片描述

點擊圓圈按鈕
在這里插入圖片描述

這樣的話 , Maven 就會重新刷新 , 就會繼續下載需要的依賴

1.3 創建目錄

右鍵 main -> New -> Directory
在這里插入圖片描述

輸入 webapp
在這里插入圖片描述

右鍵 webapp -> New -> Directory
在這里插入圖片描述

輸入 WEB-INF
然后右鍵 WEB-INF -> New -> File
在這里插入圖片描述

名字叫做 web.xml
在這里插入圖片描述

完事之后就是這個效果
webapp -> WEN-INF -> web.xml
在這里插入圖片描述

那么這個 web.xml 也不能空著啊 , 現在空著就報錯了
那么我們復制進去這段代碼

<!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app><display-name>Archetype Created Web Application</display-name>
</web-app>

有的人這里是標紅的 , 那也沒事.
其實是 IDEA 慣的咱們 , 標紅就會認為出錯了 . 其實不然 , IDEA 只對 .java 程序特別敏感
在 xml 文件中 , 就很容易出現誤報的現象

那么這段代碼是什么意思呢 , 我們不需要知道 , 我們只需要知道 tomcat 加載你自己寫的程序 , 就會先來讀取 web.xml 里面的內容 , 具體讀取什么咱們不用管

1.4 編寫代碼

先創建 Java 文件
在這里插入圖片描述

我們的 HelloWorld 程序已經創建好了 , 就長這個樣子
在這里插入圖片描述

接下來 , 我們需要修改以及增加一些東西

繼承 HttpServlet

import javax.servlet.http.HttpServlet;public class HelloWorld extends HttpServlet {
}

我們需要讓程序繼承 HttpServlet
在這里插入圖片描述

如果發現 HttpServlet 類提示不出來 , 或者手動輸入后標紅了 , 那就去檢查一下剛才的 pom.xml 里面引入的依賴是否成功
未成功的話點擊旁邊的Maven , 然后上面有個刷新按鈕

那么這個 HttpServlet 就來自于我們剛才通過 pom.xml , 基于 Maven 從中央倉庫導入的 jar 包

重寫 doGet 方法

接下來 , 我們在 HelloWorld 類中重寫 doGet 方法
具體如下圖
在這里插入圖片描述

然后代碼就變成了這個樣子
在這里插入圖片描述

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 HelloWorld extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {super.doGet(req, resp);}
}

我們來仔細琢磨琢磨這個 doGet 方法
在這里插入圖片描述

刪除 super 方法

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 HelloWorld extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//把自動生成的super()方法一定要刪除掉或者注釋掉,不然會有問題//super.doGet(req, resp);}
}

加上 @WebServlet 注解

在完成 doGet 方法之后 , 千萬不要忘記在類的上面加上 @WebServlet 注解

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("/hello")
public class HelloWorld extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//把自動生成的super()方法一定要刪除掉或者注釋掉,不然會有問題//super.doGet(req, resp);}
}

這個注解其實就是約定了 HTTP 請求 里面的 URL 里面的 Content-Path 是什么樣的 , 才能調用當前這個 Servlet 類

比如 : Tomcat 收到的請求有很多種

  • GET /aaa 不會觸發上面的 doGet 方法 , 因為Path不同
  • GET /bbb 不會觸發上面的 doGet 方法 , 因為Path不同
  • GET /hello 觸發 doGet 方法
  • POST /hello 不會觸發上面的 doGet 方法 , 因為這個是 POST 請求
    所以不是所有的 GET 請求都會觸發上面的 doGet 方法 , 只有特定的路徑的請求 , 才會觸發

根據請求的路徑 , 找到對應的類 , 在調用其對應的 doXXX 方法 , 這個過程就是"路由"

路由 : 根據不同的路徑 , 找到不同的要執行的代碼

那么上面的代碼我們發現 , 并沒有主方法 (main 方法)
我們之前說 : Java 程序的入口是 main 方法 , 那上面的代碼他也沒 main 方法 , 那不是執行不了嗎 ? 那我們寫他干嘛?
實際上 , 我們的 Servlet 程序是通過 Tomcat 運行的 , 我們可以看作 main 方法是在 Tomcat 里面的 . 所以我們需要部署到 Tomcat 里面才能去運行.

寫業務邏輯

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("/hello")
public class HelloWorld extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//把自動生成的super()方法一定要刪除掉或者注釋掉,不然會有問題//super.doGet(req, resp);//這條語句是打印到服務器的控制臺上//也就是打印到 IDEA 的控制臺上 System.out.println("hello");//這條語句才是添加到響應報文中,顯示在頁面上//就是把"hello world"作為響應報文的body部分了,瀏覽器就把這個body顯示到頁面上了resp.getWriter().write("hello world");}
}

1.5 打包

打包操作十分簡單 , 可以通過 Maven 一鍵式完成
右邊的 Maven -> ServletDemo1 -> Lifecycle -> package
在這里插入圖片描述

右鍵 Run 或者 雙擊即可進行打包操作
看到BUILD SUCCESS字樣就打包成功了 , 打包失敗的話會有報錯信息
在這里插入圖片描述

我們來分析一下右邊結構
在這里插入圖片描述

我們再看 , 這里生成的是 jar 包 , 雖然 jar 包是 Java 語言里面最通用的壓縮包 , 但是 Tomcat 就隔路 , 它能識別的是一個 war 包 , 并不支持 jar 包
在這里插入圖片描述

所以我們還需要去設置一下
打開 pom.xml
在這個位置輸入以下代碼
在這里插入圖片描述

<packaging>war</packaging>
<build><finalName>Hello_servlet</finalName>
</build>

這個 finalName 同時也是我們在瀏覽器中輸入 URL 的一部分
在這里插入圖片描述

注意這兩個標簽的位置不要寫錯 , 在的上邊
接下來我們重新打包 , 我們就可以看到 war 包生成成功了
在這里插入圖片描述

我們還可以在文件資源管理器里面查看
在這里插入圖片描述
在這里插入圖片描述

1.6 部署

我們把剛才生成的 war 包 , 拷貝到 Tomcat 里面的 webapps 目錄中
實際上 , 部署就是復制粘貼 , 說得好聽其實啥也不是

在這里插入圖片描述

接下來 , 啟動 Tomcat
在這里插入圖片描述

還是正常的一堆亂碼 , 但是我們往上翻翻 , 就會發現一些蛛絲馬跡
在這里插入圖片描述

意思就是 Tomcat 發現了這個 war 包 , 對他進行解壓以及加載了
我們再回到 webapps 目錄里面 , 發現 Hello_Servlet 已經被解壓了
在這里插入圖片描述

1.7 驗證

我們已經把程序部署在 Tomcat 上了 , 我們接下來可以檢驗一下了
在瀏覽器輸入
127.0.0.1:8080/Hello_servlet/hello
我們可以看到 , 已經完美運行了
在這里插入圖片描述

然后我們來分析一下我們剛剛輸入的東西吧
在這里插入圖片描述

一般情況下 , 訪問 Servlet 程序對應的路徑 , 一般是兩級路徑 , 但是也不絕對
第一級路徑 Context-Path 代表當前的 webapp(網站)

一個 Tomcat 上面是可以同時部署多個 webapp (網站)的 , Tomcat 路徑底下的 webapps 目錄下的每個目錄實際上都是一個 webapp (網站)

有的資料也把 Tomcat 叫做 “容器” , 意思就是能容納多個 webapp

那么一般情況下 ,我們的 Context-Path 怎么確定 ?

  1. 如果是通過 startup.bat 啟動的 , 那么他的 Context-Path 就是 webapps 目錄底下的 war 包 (目錄名)
  2. 如果是通過 Smart Tomcat 啟動的 (稍后介紹) , 那么他的 Context-Path 就是配置啟動項的時候那個 Context-Path
    在這里插入圖片描述

第二級路徑就是 ServletPath , 是根據代碼中的 @WebServlet(“/”) 來確定的 , 或者是 webapp下面的靜態文件/目錄

比如 : 我們在 webapp 路徑下面創建個 css 文件夾 , 里面創建個文件 style.css
在這里插入圖片描述
運行 Smart Tomcat , 我們輸入 URL
127.0.0.1:8080/MessageWall/css/style.css

什么都沒有 , 是因為我們的 CSS 文件沒寫任何代碼在這里插入圖片描述那么我們剛開始學習 , 可能會出現以下幾種情況情況

情況 1 :

在這里插入圖片描述
404 代表資源 not found 了 , 意思是對應資源要么沒找到 , 要么丟了
遇見 404 , 我們首先要做的就是排查路徑是否正確
上面的就是因為 Hello_Servlet 寫成 hello_Servlet 了

情況 2 :

在這里插入圖片描述

這種情況就是 Tomcat 沒啟動 , 啟動之后再次試一下就好了


目前為止 , 我們已經把 Tomcat 的創建講解完了 , 我們還需要注意以下幾個問題

問題 1 : Tomcat 已經啟動的狀態下 , 啟動一個新的 , 就會被重新分配一個端口號 , 新啟動的 Tomcat 端口號就不一定是 8080 了

一個端口號 , 只能被一個進程綁定

問題 2 : 我已經部署完了 , 之后我又更新了代碼 , 那回到瀏覽器刷新怎么還是不變的 ?

這個時候我們就需要重新打包部署 , 不然怎么刷新頁面都沒用

1.8 小結

  1. 創建項目 : Maven 項目
  2. 引入依賴 : Servlet 對應的依賴
  3. 創建目錄 : webapp -> WEB-INF -> web.xml
  4. 編寫代碼 :
    a. 繼承 HttpServlet 類
    b. 重寫 doGet 方法
    c. 加上 @WebServlet 注解
  5. 打包程序 : 使用 Maven 提供的 package , 然后還需要修改 pom.xml , 通過 packing 標簽設置打包類型為 war , 通過 finalName 屬性設置包名
  6. 部署程序 : 把 war 包拷貝到 Tomcat 里面的 webapps 目錄里面 , 然后重啟 Tomcat 服務器
  7. 驗證程序 : 通過瀏覽器構造 HTTP 請求 , 訪問 Tomcat 服務器
    URL 路徑 = Context Path(war 包的名字) + Servlet Path(注解里面的路徑)

如果后續代碼發生改變 , 那么必須要重新進行5 ~ 7 操作

開發環境 VS 運行環境
開發環境 : 寫代碼的環境 , 對應的是項目目錄
運行環境 : 運行程序的環境 , 對應的是 Tomcat 目錄
直接修改代碼 , 只是針對開發環境進行了修改 , 我們只有重新進行打包 -> 部署 , 才能在運行環境生效

二 . 更方便的部署方式

在這里插入圖片描述

那么我們可以借助 IDEA 里面的一個插件 : Smart Tomcat , 它可以幫助我們進行打包和部署
那么我教大家怎么進行安裝

2.1 Smart Tomcat 的安裝

  1. File -> Settings
    在這里插入圖片描述

  2. 在 Plugins 里面搜索 Smart Tomcat , 點擊 Install
    在這里插入圖片描述

這樣 , 我們的 Smart Tomcat 就安裝好了
我們還可以通過網頁進行下載 , 然后拖入到 IDEA 里面
https://plugins.jetbrains.com/plugin/9492-smart-tomcat
那么安裝完了 Smart Tomcat , 我們怎么來使用呢?

2.2 Smart Tomcat 的配置

第一步 : 點擊 Add Configuration
在這里插入圖片描述

第二步 : 點擊加號 , 然后選擇 Smart Tomcat
在這里插入圖片描述

第三步 :
在這里插入圖片描述

配置 tomcat 的路徑不用進入到 bin 目錄

點擊 Tomcat server 右邊的 Configure
在這里插入圖片描述

選擇 Tomcat 的路徑 , 然后OK
在這里插入圖片描述

這就 OK 了

2.3 Smart Tomcat 的使用

點擊這里的綠色三角號 , 編譯打包部署程序 , 并且運行 Tomcat
在這里插入圖片描述

我們看到底下紅彤彤的 , 就是成功了
在這里插入圖片描述

要看到底下的 startup in xxx ms 這種字樣 , 才算成功
但是我們之前的 Tomcat 不是彈出來一個黑框框嗎 , 所以這就是這個插件的厲害之處 , 把黑框框集成在 IDEA 里面了 , 而且沒有亂碼了!
我們再去驗證一下
在這里插入圖片描述

成功了
要注意的是 , Content Path 要保持一致 , 我們之前說過 finalName 就是 Content Path , 我們之前設過的 Content Path 是 Hello_servlet ,而 Smart Tomcat 里面是 /ServletDemo1 , 所以要修改一下才能成功

在這里插入圖片描述

但是我們不寫 finalName 就不會有這種問題

2.4 Smart Tomcat 的原理

Smart Tomcat 是運行 Tomcat 的時候 , 通過其他手段 , 讓 Tomcat 直接加載了咱們的代碼當中的 webapp 目錄 , 這個時候跳過了打包+拷貝的過程 , 也起到了部署的效果 .
我們之前通過 startup.bat 運行 Tomcat , 運行的是 他目錄底下的 webapps , webapps 里面有很多目錄 , 他的每一個子目錄都是一個 webapp , 也就是一個個小的網站 . 我們通過 startup.bat 啟動 , 其實是加載了所有的 webapp , 那么 Smart Tomcat 只是運行了咱們 IDEA 項目對應的 webapp (也就是咱們自己的 webapp 目錄) .

三 . 常見錯誤

3.1 404

大概率是 URL 寫錯了 , 也有可能是 webapp 沒有正確加載(比如 : web.xml 寫錯了 , Smart Tomcat 里面的 Content Path 與 URL 不匹配、finalName 與 URL 中的 Content-Path 不匹配等)

3.2 405

method not allowed
比如 : 請求是 Get , 但是我們沒實現 doGet , 就會405
在這里插入圖片描述
在這里插入圖片描述

或者寫了 doGet , 但是沒把 super.doGet(); 刪掉 , 也會405
在這里插入圖片描述

就會產生未知情況的 405
在這里插入圖片描述

3.3 500

服務器內部錯誤 , 也就是服務器掛了
可能是代碼拋異常了
在這里插入圖片描述
在這里插入圖片描述

3.4 返回空白頁面

應該是忘記寫 write 方法了
在這里插入圖片描述
在這里插入圖片描述

3.5 無法訪問此網站

沒啟動 Tomcat

在這里插入圖片描述

3.6 返回中文亂碼

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("/hello")
public class HelloWorld extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.getWriter().write("你好世界");}
}

當服務器返回的數據是中文的時候 , 此時我們的頁面上就會出現亂碼
在這里插入圖片描述

這是因為我們的 IDEA 指定的默認字符是 utf8 , 而瀏覽器解析字符的時候 , 默認跟操作系統一致 , 我們大多數人都是 windows 簡體中文版 , 默認編碼是 GBK , 那么瀏覽器按 GBK 解析 , 必然會出錯 , 所以我們要讓瀏覽器按照 utf8 的解析方式來進行解碼

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("/hello")
public class HelloWorld extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//加上這句代碼resp.setContentType("text/html;charset=utf8");resp.getWriter().write("你好世界");}
}

我們再次運行 , 這次就成功了
在這里插入圖片描述

那么這條語句加的位置也是大有講究 , 那我加在輸出語句后面可不可以 ?

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("/hello")
public class HelloWorld extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.getWriter().write("你好世界");//把這句代碼加到了輸入語句后面resp.setContentType("text/html;charset=utf8");}
}

在這里插入圖片描述

又亂碼了 , 所以大家記得必須要保證構造響應的 header 要在構造 body 之前 , 否則 header 不生效


讓瀏覽器按照 utf8 的解析方式來進行解碼 這條語句其實就是在更改header .
resp.getWriter().write(“你好世界”); 這條語句其實就是通過構造body , 讓瀏覽器返回 body 的內容
我們來看一下
這是在沒有指定字符集之前 , 抓包的結果
在這里插入圖片描述

那么我們指定字符集之后 , 我們發現 字符集被設置成功了 , 而且我們的"你好世界"也完美被打印了
在這里插入圖片描述

四 . 擴展 : 什么是 JSP ?

我們有的同學會在學校學到 JSP 這種東西 , 那 JSP 到底是什么 , 他跟 Servlet 又有什么關系

JSP 可以認為是 Servlet 的一部分 , 在 200x 年很常用 , 但是現在已經退出歷史舞臺了

我們之前講過靜態頁面和動態頁面

靜態頁面就是內容始終固定的頁面 , 即使用戶不同/時間不同/輸入的參數不同 , 頁面內容也不會發生變化
比如我們的 Tomcat 歡迎頁就是一個靜態頁面
在這里插入圖片描述

動態頁面就是隨著用戶輸入的不同 , 頁面呈現出來的效果也不同
比如我們搜索 鮮花 和 蛋糕 這兩個關鍵字
在這里插入圖片描述
在這里插入圖片描述

我們輸入不同的關鍵字 , 顯示出來的是不同的頁面 , 那么我們的 JSP 就是專門用來做動態頁面的
制作動態頁面的方式基本有兩種 :

  1. 客戶端渲染 : 服務器返回數據 , 由頁面通過 js 來生成對應的界面
  2. 服務器渲染 : 服務器直接組裝好完整的 html , 直接返回給瀏覽器

由于我們現在普遍的工作方式都是前后端交互 , 大家各干各的事 , 我們不需要考慮具體的頁面 , 所以 jsp 慢慢的就退出歷史舞臺了 , 而且即使我們使用服務器渲染的方式 , 那么我們也有更好的模板引擎 , jsp 就更沒優勢了

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/165749.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/165749.shtml
英文地址,請注明出處:http://en.pswp.cn/news/165749.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【docker】安裝redis和mysql生產實戰

docker安裝諸如redis,mysql等程序非常方便,但是如果不是為了學習,生產環境的部署還是要注意很多問題的 mysql docker pull mysql:5.7mkdir -p /usr/docker/mysql/{conf,logs,data}docker run -d -p 3306:3306 --privilege

ORA-28003: password verification for the specified password failed,取消oracl密碼復雜度

自己在測試環境想要使自己的Oracle數據庫用戶使用簡單的密碼方便測試&#xff0c;結果指定密碼的密碼驗證失敗 SQL> alter user zzw identified by zzw; alter user zzw identified by zzw * ERROR at line 1: ORA-28003: password verification for the specified password…

本地部署 ComfyUI

本地部署 ComfyUI ComfyUI 介紹ComfyUI Github 地址部署 ComfyUI配置模型地址 or 下載模型啟動 ComfyUI訪問 ComfyUI ComfyUI 介紹 最強大、模塊化的穩定擴散 GUI 和后端。 該用戶界面將允許您使用基于圖形/節點/流程圖的界面設計和執行高級穩定擴散管道。 ComfyUI Github 地…

用戶運營常用的ChatGPT通用提示詞模板

如何建立和完善用戶運營體系&#xff0c;提高用戶滿意度和忠誠度&#xff1f; 如何制定有效的用戶獲取和留存策略&#xff0c;提高用戶生命周期價值&#xff1f; 如何運用多種渠道和平臺進行用戶運營&#xff0c;提高用戶參與度和互動性&#xff1f; 如何建立和維護用戶社群…

第五天 用Python批量處理Excel文件,實現自動化辦公

用Python批量處理Excel文件&#xff0c;實現自動化辦公 一、具體需求 有以下N個表&#xff0c;每個表的結構一樣&#xff0c;如下&#xff1a; 需要把所有表數據匯總&#xff0c;把每個人的得分、積分分別加起來&#xff0c;然后按總積分排名&#xff0c;總積分一致時&#xff…

小程序可拖拽按鈕

你有沒有遇到過在頁面中有一個固定在某個位置的按鈕&#xff0c;永遠的擋住了你想要看的區域&#xff1f; 在小程序的列表頁面中&#xff0c;常常會有一個提報的入口固定在右下角&#xff0c;如果這個按鈕不可拖動的話&#xff0c;可能會擋住下面的事件&#xff0c;讓用戶操作起…

云端導覽,數字互動 | 拓世法寶AI數字人一體機助力全新旅游時代

《中國旅行消費趨勢洞察白皮書&#xff08;2023版&#xff09;》顯示&#xff0c;消費者旅行習慣已從“到此一游”變為“深度在地”&#xff0c;更強調在旅游中充實自我、學習新知識。 &#xff08;《中國旅行消費趨勢洞察白皮書&#xff08;2023版》截圖&#xff09; 從這些資…

C++標準模板(STL)- 類型支持 (類型修改,從給定類型移除引用,std::remove_reference)

類型特性 類型特性定義一個編譯時基于模板的結構&#xff0c;以查詢或修改類型的屬性。 試圖特化定義于 <type_traits> 頭文件的模板導致未定義行為&#xff0c;除了 std::common_type 可依照其所描述特化。 定義于<type_traits>頭文件的模板可以用不完整類型實例…

Springboot整合MybatisPlus及分頁功能

1 引入pom <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot</artifactId><version>2.7.14</version> </dependency> <dependency><groupId>com.baomidou</groupId><a…

【Vue】Vue3 配置全局 scss 變量

variables.scss $color: #0c8ce9;vite.config.ts // 全局css變量css: {preprocessorOptions: {scss: {additionalData: import "/styles/variables.scss";,},},},.vue 文件使用

讀書筆記:彼得·德魯克《認識管理》第33章 管理者與管理科學

一、章節內容概述 把管理科學的潛力轉變為績效&#xff0c;主要取決于管理者。要做到這一點&#xff0c;管理者必須理解管理科學是什么以及能夠做什么。管理者必須明白&#xff0c;管理科學固有的特殊局限性在很大程度上源于自身的起源和歷史。但最重要的是&#xff0c;管理者…

Java大型電商項目——品優購(一)

視頻教程&#xff1a;【黑馬程序員】Java大型電商項目—品優購【配套源碼筆記】_嗶哩嗶哩_bilibili源碼下載&#xff1a; 鏈接&#xff1a;https://pan.baidu.com/s/1fECz5In_XCB-aW6ed6ZTbA 提取碼&#xff1a;27xa 技術選型&#xff1a; 后端框架&#xff1a;SpringSprin…

多功能回饋式交流電子負載的應用

多功能回饋式交流電子負載是用于模擬和測試電源、電池等電子設備的負載工具。它具有多種應用&#xff0c;可以用于測試和評估各種類型的電源&#xff0c;包括直流電源和交流電源。它可以模擬各種負載條件&#xff0c;如恒定電流、恒定電壓和恒定功率&#xff0c;以驗證電源的性…

小葉子鋼琴智能陪練 助力打牢鋼琴基礎

孩子在練琴過程中&#xff0c;經常會出現錯音錯節奏&#xff0c;為了能夠幫助她更高效的練琴&#xff0c;最近開始使用智能鋼琴陪練工具——小葉子鋼琴智能陪練。 身邊也有很多朋友在用這款應用&#xff0c;它比較知名的功能就是三大練琴模式&#xff0c;也就是識譜模式、提升…

linux centos系統命令安裝

Zip unzip 命令安裝下載 centos 命令常用常用下載 https://rpmfind.net/linux/rpm2html/search.php?queryzip%28x86-64%29&submitSearch…&system&arch 在線安裝zip命令 Centos用yum安裝的話用下面的命令安裝 yum install -y unzip zipUbuntu的的系統可以用下…

java SpringCloud版本b2b2c鴻鵠云商平臺全套解決方案 小程序商城免費搭建

使用技術&#xff1a; Spring CloudSpring BootMybatis微服務服務監控可視化運營 B2B2C平臺&#xff1a; 平臺管理端(包含自營) 商家平臺端(多商戶入駐) PC買家端、手機wap/公眾號買家端 微服務&#xff08;30個通用微服務如&#xff1a;商品、訂單、購物車、個人中心、支…

Ubuntu20.04清理垃圾vscode緩存

使用VM虛擬機安裝了Ubuntu系統&#xff0c;主目錄空間越來越小&#xff0c;硬盤擴容之后很快又空間不足&#xff0c;甚至出現了開機卡黑屏的情況&#xff0c;這里記錄一下解決過程。 1 重新開機進入系統 狀態&#xff1a;卡到了開機黑屏狀態&#xff0c;左上角有一條小橫杠 原…

國外網站文章或網頁采集翻譯為中文

采集國外網站的文章或網頁數據&#xff08;例如英文&#xff0c;西班牙語&#xff0c;法語等&#xff09;&#xff0c;怎么快速批量翻譯為中文&#xff1f; 可以使用簡數采集器來實現&#xff0c;支持自動翻譯&#xff0c;同時翻譯為多種語言&#xff08;不僅中文&#xff09;…

Angular11 MSAL B2C登錄實例 (二)

前言 上文介紹了在app.module.ts里的配置&#xff0c;本文著重講解下在app-routing.module.ts和index.html里的設置。 步驟 在文件中主要需要添加以下代碼 app-routing.module.ts const initialNavigation (!BrowserUtils.isInIframe() && !BrowserUtils.isInPopup…

Linux實驗三:shell程序設計: shell基礎

實驗目的: 進一步鞏固shell程序設計語言基本語法&#xff0c;加深對所學知識理解。 實驗要求 1. 四種變量的使用 2. 配置環境變量 3. 元字符和正則表達式 4. 引號 1. 本地變量 $ var1"hello Linux" //定義本地變量var1 $ read var2 //定義本地變量vae…