?作者簡介:一位材料轉(zhuǎn)碼農(nóng)的選手,希望一起努力,一起進步!?
??個人主頁:@每天都要敲代碼的個人主頁
??系列專欄:Web后端 | Servlet
目錄
一:模擬實現(xiàn)Servlet
二:開發(fā)第一個帶有Java小程序Servlet【重點】
一:模擬實現(xiàn)Servlet
有了上一章節(jié)的分析,我們來模擬實現(xiàn)以下Servlet;下面先分析一下我們需要做什么:
充當SUN公司的角色,制定Servlet規(guī)范
javax.servlet.Servlet接口
充當Tomcat服務(wù)器的開發(fā)者
充當Webapp的開發(fā)者
UserLoginServlet implements Servlet
充當SUN公司的角色,制定Servlet規(guī)范
Tomcat與Webapp之間之所以能夠解耦合,是因為有Servlet規(guī)范
現(xiàn)在充當?shù)慕巧荢UN公司,SUN公司把Servlet接口/規(guī)范制定出來了
package javax.servlet
public interface Servlet{
// 一個專門提供服務(wù)的方法
void service();
}
充當Webapp的開發(fā)者
充當?shù)慕巧l(fā)生了改變:webapp開發(fā)者
只要是我們webapp開發(fā)者寫的XXXServlet都要實現(xiàn)Servlet接口
package com.bjpowernode.servlet;
import javax.servlet.Servlet;
public class UserLoginServlet implements Servlet{
public void service(){
System.out.println("UserLoginServlet's service...");
}
}
充當Tomcat服務(wù)器的開發(fā)者
我們輸入的請求路徑與XXXServlet類有一定的對應(yīng)關(guān)系;對應(yīng)關(guān)系由Webapp的開發(fā)者來提供,定義一個屬性配置文件:web.properties
/login=com.bjpowernode.servlet.UserLoginServlet
package org.apache;
import java.util.Scanner;
import java.util.Properties;
import java.io.FileReader;
import javax.servlet.Servlet;
// 充當Tomcat服務(wù)器的開發(fā)者
public class Tomcat{
public static void main(String[] args) throws Exception{
System.out.println("Tomcat服務(wù)器啟動成功,開始接收用戶的訪問。");
// 簡單的使用Scanner來模擬一下用戶的請求
// 用戶訪問服務(wù)器是通過瀏覽器上的“請求路徑”
// 也就是說用戶請求路徑不同,后臺執(zhí)行的Servlet不同。
System.out.print("請輸入您的訪問路徑:");
Scanner s = new Scanner(System.in);
// 用戶的請求路徑 /login
String key = s.nextLine(); // Tomcat服務(wù)器已經(jīng)獲取到了用戶的請求路徑了。
// Tomcat服務(wù)器應(yīng)該通過用戶的請求路徑找對應(yīng)的XXXServlet
// 請求路徑和XXXServlet之間的關(guān)系應(yīng)該由誰指定呢?
// 對于Tomcat服務(wù)器來說需要解析配置文件
FileReader reader = new FileReader("web.properties");
Properties pro = new Properties();
pro.load(reader);
reader.close();
// 通過key獲取value
String className = pro.getProperty(key);
// 通過反射機制創(chuàng)建對象
Class c = Class.forName(className);
Object obj = c.newInstance(); // obj的類型對于Tomcat服務(wù)器開發(fā)人員來說不知道。
// 但是Tomcat服務(wù)器的開發(fā)者知道,你寫的XXXXServlet一定實現(xiàn)了Servlet接口
Servlet servlet = (Servlet)obj;
servlet.service();
}
}
通過我們的分析:
對于我們javaweb程序員來說,我們只需要做兩件事:
編寫一個類實現(xiàn)Servlet接口。
將編寫的類配置到配置文件中,在配置文件中:指定請求路徑和類名的關(guān)系。
注意:
這個配置文件的文件名不能亂來。固定的。
這個配置文件的存放路徑不能亂來。固定的。
文件名、文件路徑都是SUN公司制定的Servlet規(guī)范中的明細。
嚴格意義上來說Servlet其實并不是簡單的一個接口:
Servlet規(guī)范中規(guī)定了:
一個合格的webapp應(yīng)該是一個怎樣的目錄結(jié)構(gòu)。
一個合格的webapp應(yīng)該有一個怎樣的配置文件。
一個合格的webapp配置文件路徑放在哪里。
一個合格的webapp中java程序放在哪里。
這些都是Servlet規(guī)范中規(guī)定的。
Tomcat服務(wù)器要遵循Servlet規(guī)范。JavaWEB程序員也要遵循這個Servlet規(guī)范。這樣Tomcat服務(wù)器和webapp才能解耦合。
Servlet規(guī)范是一個什么規(guī)范?
遵循Servlet規(guī)范的webapp,這個webapp就可以放在不同的WEB服務(wù)器中運行。(因為這個webapp是遵循Servlet規(guī)范的)
Servlet規(guī)范包括什么呢?
規(guī)范了哪些接口
規(guī)范了哪些類
規(guī)范了一個web應(yīng)用中應(yīng)該有哪些配置文件
規(guī)范了一個web應(yīng)用中配置文件的名字
規(guī)范了一個web應(yīng)用中配置文件存放的路徑
規(guī)范了一個web應(yīng)用中配置文件的內(nèi)容
規(guī)范了一個合法有效的web應(yīng)用它的目錄結(jié)構(gòu)應(yīng)該是怎樣的。
.....
二:開發(fā)第一個帶有Java小程序Servlet【重點】
補充:關(guān)于JavaEE的版本
JavaEE目前最高版本是 JavaEE8
JavaEE被Oracle捐獻了,Oracle將JavaEE規(guī)范捐獻給Apache了。
Apache把JavaEE換名了,以后不叫JavaEE了,以后叫做 jakarta EE。
JavaEE8版本升級之后的"JavaEE 9",不再是"JavaEE9"這個名字了,叫做JakartaEE9
JavaEE8的時候?qū)?yīng)的Servlet類名是:javax.servlet.Servlet
JakartaEE9的時候?qū)?yīng)的Servlet類名是:jakarta.servlet.Servlet (包名都換了)
如果你之前的項目還是在使用javax.servlet.Servlet,那么你的項目無法直接部署到Tomcat9+版本上。你只能部署到Tomcat9-版本上。在Tomcat9以及Tomcat9之前的版本中還是能夠識別javax.servlet這個包。
開發(fā)步驟是怎樣的?
第一步:在webapps目錄下新建一個目錄,起名crm(這個crm就是webapp的名字)。當然,也可以是其它項目,比如銀行項目,可以創(chuàng)建一個目錄bank,辦公系統(tǒng)可以創(chuàng)建一個oa。
注意:crm就是這個webapp的根
第二步:在webapp的根下新建一個目錄:WEB-INF
注意:這個目錄的名字是Servlet規(guī)范中規(guī)定的,必須全部大寫,必須一模一樣。必須的必須。
第三步:在WEB-INF目錄下新建一個目錄:classes
注意:這個目錄的名字必須是全部小寫的classes。這也是Servlet規(guī)范中規(guī)定的。另外這個目錄下一定存放的是Java程序編譯之后的class文件(這里存放的是字節(jié)碼文件)。
第四步:在WEB-INF目錄下新建一個目錄:lib
注意:這個目錄不是必須的。但如果一個webapp需要第三方的jar包的話,這個jar包要放到這個lib目錄下,這個目錄的名字也不能隨意編寫,必須是全部小寫的lib。例如java語言連接數(shù)據(jù)庫需要數(shù)據(jù)庫的驅(qū)動jar包。那么這個jar包就一定要放到lib目錄下。這Servlet規(guī)范中規(guī)定的。
第五步:在WEB-INF目錄下新建一個文件:web.xml
注意:這個文件是必須的,這個文件名必須叫做web.xml。這個文件必須放在這里。一個合法的webapp,web.xml文件是必須的,這個web.xml文件就是一個配置文件,在這個配置文件中描述了請求路徑和Servlet類之間的對照關(guān)系。
這個文件最好從其他的webapp中拷貝模板,最好別手寫。復制粘貼
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee
https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
version="5.0"
metadata-complete="true">
</web-app>
第六步:編寫一個Java程序,這個小Java程序也不能隨意開發(fā),這個小java程序必須實現(xiàn)Servlet接口。
這個Servlet接口不在JDK當中。(因為Servlet不是JavaSE了。Servlet屬于JavaEE,是另外的一套類庫。)
Servlet接口(Servlet.class文件)是Oracle提供的。(最原始的是sun公司提供的)
Servlet接口是JavaEE的規(guī)范中的一員。
Tomcat服務(wù)器實現(xiàn)了Servlet規(guī)范,所以Tomcat服務(wù)器也需要使用Servlet接口。Tomcat服務(wù)器中應(yīng)該有這個接口,Tomcat服務(wù)器的CATALINA_HOME\lib目錄下有一個servlet-api.jar,解壓這個servlet-api.jar之后,你會看到里面有一個Servlet.class文件。
重點:從JakartaEE9開始,Servlet接口的全名變了:jakarta.servlet.Servlet
注意:編寫這個Java小程序的時候,java源代碼你愿意在哪里就在哪里,位置無所謂,你只需要將java源代碼編譯之后的class文件放到classes目錄下即可。
package com.bjpowernode.servlet
import jakarta.servlet.Servlet
import jakarta.servlet.Servlet;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.ServletConfig;
import java.io.IOException;
import java.io.PrintWriter;
public class HelloServlet implements Servlet{
// 通過查看幫助文檔發(fā)現(xiàn)這個接口中有5個方法
// destroy()、 getServletConfig()、getServletInfo()、
// init?(ServletConfig config)、 service?(ServletRequest req, ServletResponse res)
public void init?(ServletConfig config) throws ServletException{
}
public void service?(ServletRequest req, ServletResponse res) throws ServletException,IOException{
// 把內(nèi)容輸出到控制臺的
System.out.println("Hello Servlet!");
}
public void destory(){
}
public String getServletInfo(){
return "";
}
public ServetConfig getServletConfig(){
}
}
第七步:編譯我們編寫的HelloServlet
重點:你怎么能讓你的HelloServlet編譯通過呢?編譯時jakarta.servlet找不到,因為這是JavaEEjar包下的,所以我們需要配置環(huán)境變量。
配置環(huán)境變量CLASSPATH:classpath就表示類的路徑(JDK中沒有Servlet接口,這屬于JavaEE)
CLASSPATH=.;C:\Java學習\5.Web后端\工具\apache-tomcat-10.0.12\lib\servlet-api.jar
思考問題:以上配置的CLASSPATH和Tomcat服務(wù)器運行有沒有關(guān)系?
沒有任何關(guān)系,以上配置這個環(huán)境變量只是為了讓你的HelloServlet能夠正常編譯生成class文件。運行時Tomcat是能自己找到servlet-api.jar
第八步:將以上編譯之后的HelloServlet.class文件拷貝到WEB-INF\classes目錄下。
第九步:在web.xml文件中編寫配置信息,讓“請求路徑”和“Servlet類名”關(guān)聯(lián)在一起。
這一步用專業(yè)術(shù)語描述:在web.xml文件中注冊Servlet類。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee
https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
version="5.0"
metadata-complete="true">
<!--servlet描述信息-->
<!--任何一個servlet都對應(yīng)一個servlet-mapping -->
<servlet>
<servlet-name>zl-gh</servlet-name>
<!--這個位置必須是帶有包名的全限定類名-->
<servlet-class>com.bjpowernode.servlet.HelloServlet</servlet-class>
</servlet>
<!--servlet映射信息-->
<servlet-mapping>
<!--這個也是隨便的,不過這里寫的內(nèi)容要和上面的一樣。-->
<servlet-name>zl-gh</servlet-name>
<!--這里需要一個路徑-->
<!--這個路徑唯一的要求是必須以 / 開始-->
<!--當前這個路徑可以隨便寫-->
<url-pattern>/Hello</url-pattern>
</servlet-mapping>
</web-app>
第十步:啟動Tomcat服務(wù)器,startup.bat
第十一步:打開瀏覽器,在瀏覽器地址欄上輸入一個url,這個URL必須是:
http://127.0.0.1:8080/crm/Hello
重點:瀏覽器上的請求路徑不能隨便寫,這個請求路徑必須和web.xml文件中的url-pattern一致。
注意:瀏覽器上的請求路徑和web.xml文件中的url-pattern的唯一區(qū)別就是:瀏覽器上的請求路徑帶項目名:/crm
瀏覽器上編寫的路徑太復雜,可以使用超鏈接。(非常重要:html頁面只能放到WEB-INF目錄外面。是相當于同級目錄關(guān)系)
<!doctype html>
<html>
<head>
<title>index page</title>
</head>
<body>
<a >Hello Servlet</a>
</body>
</html>
以后不需要我們編寫main方法了。tomcat服務(wù)器負責調(diào)用main方法,Tomcat服務(wù)器啟動的時候執(zhí)行的就是main方法。我們javaweb程序員只需要編寫Servlet接口的實現(xiàn)類,然后將其注冊到web.xml文件中,即可。
總結(jié):一個合法的webapp目錄結(jié)構(gòu)應(yīng)該是怎樣的?
webapproot(webapp根目錄下)
|------WEB-INF
|------classes(存放字節(jié)碼)
|------lib(第三方j(luò)ar包)
|------web.xml(注冊Servlet)
|------html
|------css
|------javascript
|------image
....
瀏覽器發(fā)送請求,到最終服務(wù)器調(diào)用Servlet中的方法,是怎樣的一個過程?
用戶輸入URL,或者直接點擊超鏈接:http://127.0.0.1:8080/crm/Hello
然后Tomcat服務(wù)器接收到請求,截取路徑:/crm/Hello
Tomcat服務(wù)器找到crm項目
Tomcat服務(wù)器在web.xml文件中查找Hello對應(yīng)的Servlet是:com.bjpowernode.servlet.HelloServlet
Tomcat服務(wù)器通過反射機制,創(chuàng)建com.bjpowernode.servlet.HelloServlet的對象。
Tomcat服務(wù)器調(diào)用com.bjpowernode.servlet.HelloServlet對象的service方法。
上面我們編寫實現(xiàn)接口時,重寫service?(ServletRequest req, ServletResponse res)方法,是直接把結(jié)果輸出到控制臺的!
那么怎么輸出到瀏覽器上呢?這就需要ServletResponse response接口;response調(diào)用getWriter()返回的是一個PrintWriter流,利用這個流在調(diào)用print()方法,打印到服務(wù)器上,例如:? ??? ??
?????PrintWriter out = response.getWriter();
?? ??out.print("在瀏覽器上輸出打印:Hello Servlet");???
package com.bjpowernode.servlet;
import jakarta.servlet.Servlet;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.ServletConfig;
import java.io.IOException;
import java.io.PrintWriter;
public class HelloServlet implements Servlet{
// 5個方法
public void init(ServletConfig config) throws ServletException{
}
public void service(ServletRequest request,ServletResponse response)
throws ServletException , IOException{
// 1.直接向控制臺打印輸出
System.out.println("My First Servlet, Hello Servlet");
// 2.向瀏覽器打印輸出
// 需要使用ServletResponse接口:response
// 調(diào)用getWriter()方法,這個方法返回的是一個java.io.PrintWriter流
PrintWriter out = response.getWriter();
out.print("在瀏覽器上輸出打?。篐ello Servlet");
// 上面是一個輸出流,負責輸出字符串到瀏覽器
// 這個輸出流不需要我們刷新,也不需要關(guān)閉;這些都是由Tomcat來維護
// out.flush();
// out.close();
}
public void destroy(){
}
public String getServletInfo(){
return "";
}
public ServletConfig getServletConfig(){
return null;
}
}
重新編譯運行,在瀏覽器上輸入URL進行訪問;這樣就會在當前瀏覽器頁面上輸出了!
總結(jié):向瀏覽器響應(yīng)一段HTML代碼,怎么進行設(shè)置?
需要調(diào)用response的setContentType("text/html")方法,這樣就能識別HTML代碼
public void service(ServletRequest request, ServletResponse response){
// 設(shè)置識別代碼的類型
response.setContentType("text/html");
// 設(shè)置輸出結(jié)果打印到瀏覽器上
PrintWriter out = response.getWriter();
out.print("<h1>hello servlet!</h1>");
}
補充:解決Tomcat服務(wù)器在DOS命令窗口中的亂碼問題(控制臺亂碼)
將CATALINA_HOME/conf/logging.properties文件中的utf-8都GBK!文章來源:http://www.zghlxwxcb.cn/news/detail-782434.html
如下:java.util.logging.ConsoleHandler.encoding = GBK文章來源地址http://www.zghlxwxcb.cn/news/detail-782434.html
到了這里,關(guān)于Servlet | Servlet原理、開發(fā)第一個帶有Java小程序Servlet的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!