Servlet從入門到精通(超級(jí)詳細(xì)!)
概述
Servlet(Server Applet)是Java Servlet的簡(jiǎn)稱,稱為小服務(wù)程序或服務(wù)連接器,用Java編寫的服務(wù)器端程序,具有獨(dú)立于平臺(tái)和協(xié)議的特性,主要功能在于交互式地瀏覽和生成數(shù)據(jù),生成 動(dòng)態(tài)Web內(nèi)容。這個(gè)過(guò)程為:
1,客戶端發(fā)送請(qǐng)求至服務(wù)器端
2,服務(wù)器將請(qǐng)求信息發(fā)送至 Servlet
3,Servlet 生成響應(yīng)內(nèi)容并將其傳給服務(wù)器。響應(yīng)內(nèi)容動(dòng)態(tài)生成,通常取決于客戶端的請(qǐng)求
4,服務(wù)器將響應(yīng)返回給客戶端
Servlet 看起來(lái)像是通常的 Java 程序。Servlet 需要導(dǎo)入特定的屬于 Java Servlet API 的包。
Servlet有三種實(shí)現(xiàn)方式:實(shí)現(xiàn)Servlet接口, 繼承抽象類GenericServlet, 繼承HttpServlet
入門案例
創(chuàng)建Servlet程序
選中src-右鍵-New-Create New Servlet-輸入Servlet類的名字和包名-ok
package cn.tedu.test;
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(name = "MyServlet")
public class MyServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//向?yàn)g覽器響應(yīng)指定內(nèi)容
response.getWriter().write("hello servlet");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);//調(diào)用doPost()
}
}注解方式配置Servlet程序
1,直接在Servlet類上加一個(gè)注解就可以了
//Servlet程序想要?jiǎng)e瀏覽器訪問,使用@WebServlet規(guī)定了瀏覽器的訪問方式
@WebServlet("/hello/Servlet1")
2,打開瀏覽器直接訪問這個(gè)Servlet就可以了
http://localhost:8080/hello/Servlet1
配置文件方式配置Servlet程序(提供web.xml)
在Servlet3.0版本中,被@WebServlet注解代替,如:@WebServlet("/myservlet")括號(hào)中,就可以規(guī)定訪問方式
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
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_4_0.xsd"
version="4.0">
<!--這是Servlet程序的核心配置文件,IDEA不會(huì)自動(dòng)幫我們配置,只能自己來(lái)配置的,主要是規(guī)定瀏覽器的訪問方式-->
<servlet>
<servlet-name>myservlet</servlet-name>
<!--Servlet類的全路徑-->
<servlet-class>cn.tedu.test.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>myservlet</servlet-name>
<!--規(guī)定了瀏覽器的訪問方式-->
<url-pattern>/myservlet</url-pattern>
</servlet-mapping>
</web-app>
測(cè)試

你寫個(gè)HTML網(wǎng)頁(yè)測(cè)試也可以的
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <form action="http://localhost:8080/cgbservletjava01_war_exploded/a/b/x" method="post"> <input type="text" name="username"> <br> <input type="submit" value="提交"> </form> </body> </html>
Servlet的繼承結(jié)構(gòu)

Servlet的生命周期
Servlet 生命周期可被定義為從創(chuàng)建直到毀滅的整個(gè)過(guò)程。以下是 Servlet 重要階段遵循的過(guò)程:
1,初始化階段 調(diào)用init()方法
2,響應(yīng)客戶請(qǐng)求階段 調(diào)用service()方法
3,終止階段 調(diào)用destroy()方法
最后,Servlet 是由 JVM 的垃圾回收器進(jìn)行垃圾回收的。

init() 方法
init 方法被設(shè)計(jì)成只調(diào)用一次。它在第一次創(chuàng)建 Servlet 時(shí)被調(diào)用,在后續(xù)每次用戶請(qǐng)求時(shí)不再調(diào)用。因此,它是用于一次性初始化,Servlet 創(chuàng)建于用戶第一次調(diào)用對(duì)應(yīng)于該 Servlet 的 URL 時(shí),但是您也可以指定 Servlet 在服務(wù)器第一次啟動(dòng)時(shí)被加載。
當(dāng)用戶調(diào)用一個(gè) Servlet 時(shí),就會(huì)創(chuàng)建一個(gè) Servlet 實(shí)例,每一個(gè)用戶請(qǐng)求都會(huì)產(chǎn)生一個(gè)新的線程,適當(dāng)?shù)臅r(shí)候移交給 doGet 或 doPost 方法。init() 方法簡(jiǎn)單地創(chuàng)建或加載一些數(shù)據(jù),這些數(shù)據(jù)將被用于 Servlet 的整個(gè)生命周期。
service() 方法
它是Servlet的核心,每當(dāng)一個(gè)客戶請(qǐng)求一個(gè)HttpServlet對(duì)象,該對(duì)象的Service()方法就要調(diào)用,而且傳遞給這個(gè)方法一個(gè)“請(qǐng)求”(ServletRequest)對(duì)象和一個(gè)“響應(yīng)”(ServletResponse)對(duì)象作為參數(shù)。在HttpServlet中已存在Service()方法。
service() 方法會(huì)檢查 HTTP 請(qǐng)求類型(GET、POST、PUT、DELETE 等),并在適當(dāng)?shù)臅r(shí)候調(diào)用 doGet、doPost、doPut,doDelete 等方法,service() 方法由容器調(diào)用,您只需要根據(jù)來(lái)自客戶端的請(qǐng)求類型來(lái)重寫 doGet() 或 doPost() 即可。
doGet() 和 doPost() 方法是每次服務(wù)請(qǐng)求中最常用的方法。
doGet() 方法
GET 請(qǐng)求來(lái)自于一個(gè) URL 的正常請(qǐng)求,或者來(lái)自于一個(gè)未指定 METHOD 的 HTML 表單,它由 doGet() 方法處理。
doPost() 方法
POST 請(qǐng)求來(lái)自于一個(gè)特別指定了 METHOD 為 POST 的 HTML 表單,它由 doPost() 方法處理。
destroy() 方法
destroy() 方法只會(huì)被調(diào)用一次,在 Servlet 生命周期結(jié)束時(shí)被調(diào)用。destroy() 方法可以讓您的 Servlet 關(guān)閉數(shù)據(jù)庫(kù)連接、停止后臺(tái)線程、把 Cookie 列表或點(diǎn)擊計(jì)數(shù)器寫入到磁盤,并執(zhí)行其他類似的清理活動(dòng)。在調(diào)用 destroy() 方法之后,servlet 對(duì)象被標(biāo)記為垃圾回收。
Request
概述
Request對(duì)象用來(lái)解析請(qǐng)求參數(shù),當(dāng)瀏覽器訪問服務(wù)器時(shí),攜帶著一些請(qǐng)求參數(shù),可以通過(guò)Servlet提供的Request對(duì)象提供的API來(lái)解析請(qǐng)求參數(shù)
請(qǐng)求對(duì)象有兩個(gè):
ServletRequest httpServletRequest
常用的方法:
getParameter("參數(shù)名")--根據(jù)參數(shù)名獲取參數(shù)的值
getParameterValues()--獲取到所有參數(shù)的值并存入數(shù)組
setCharacterEncoding()--設(shè)置請(qǐng)求的字符編碼方式
getCharacterEncoding()--返回字符編碼方式
setAttribute(String,Object) 存儲(chǔ)此請(qǐng)求中的屬性
getAttribute(String name) 返回指定屬性的屬性值
測(cè)試
前端HTML程序
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <a href="http://localhost:8080/cgbservletjava01_war_exploded/FormServlet?name=張三&addr=北京">點(diǎn)我提交get數(shù)據(jù)</a> <form action="http://localhost:8080/cgbservletjava01_war_exploded/FormServlet" method="post"> 用戶名: <input type="text" name="username"> <br /> 愛好: <input type="checkbox" name="hobby" value="籃球"/>籃球 <input type="checkbox" name="hobby" value="足球"/>足球 <input type="checkbox" name="hobby" value="乒乓球"/>乒乓球 <br /> <input type="submit" value="提交"> </form> </body> </html>
后端java程序
package cn.tedu.req;
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.util.Arrays;
@WebServlet(name = "FormServlet")
public class FormServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//請(qǐng)求參數(shù)中,包含中文時(shí),post必須配置
// request.setCharacterEncoding("utf-8");
//獲取請(qǐng)求參數(shù)
//方式1:根據(jù)參數(shù)名獲取一個(gè)值
String name = request.getParameter("username");
System.out.println("name = " + name);
//方式2:根據(jù)參數(shù)名獲取所有值,并返回?cái)?shù)組
String[] likes = request.getParameterValues("hobby");
System.out.println("hobby = " + Arrays.toString(likes));
//給瀏覽器做出響應(yīng)
response.getWriter().print("dopost..success!");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = request.getParameter("name");
String addr = request.getParameter("addr");
System.out.println("doget..."+name+addr);
}
}請(qǐng)求轉(zhuǎn)發(fā)
概述
請(qǐng)求轉(zhuǎn)發(fā)是服務(wù)器內(nèi)部資源的一種跳轉(zhuǎn)方式,即當(dāng)瀏覽器發(fā)送請(qǐng)求訪問服務(wù)器中的某一個(gè)資源時(shí),該資源將請(qǐng)求轉(zhuǎn)交給另外一個(gè)資源進(jìn)行處理的過(guò)程,就叫做請(qǐng)求轉(zhuǎn)發(fā),具有以下特點(diǎn):
1,請(qǐng)求轉(zhuǎn)發(fā)整個(gè)過(guò)程是一次請(qǐng)求、一次響應(yīng)
2,請(qǐng)求轉(zhuǎn)發(fā)前后,瀏覽器地址欄地址不會(huì)發(fā)生變化(瀏覽器–訪問–>A–轉(zhuǎn)發(fā)–>B,地址欄地址始終指向A的地址)
3,請(qǐng)求轉(zhuǎn)發(fā)前后的request對(duì)象是同一個(gè)
4,轉(zhuǎn)發(fā)前后的兩個(gè)資源必須屬于同一個(gè)Web應(yīng)用,否則將無(wú)法進(jìn)行轉(zhuǎn)發(fā)
5,使用代碼: request.getRequestDispatcher(訪問目的資源的路徑).forward(request,response);
6,也可以使用 setAttribute()/getAttribute()來(lái)驗(yàn)證

測(cè)試過(guò)程

Response
概述
Response是代表Http響應(yīng)信息的對(duì)象,其中將會(huì)封裝服務(wù)器要發(fā)送給瀏覽器的響應(yīng)信息,將response對(duì)象作為參數(shù)傳遞給service方法,在service方法處理請(qǐng)求的過(guò)程中,可以將要發(fā)送給瀏覽器的數(shù)據(jù),先寫入response對(duì)象中,在service方法執(zhí)行完后,服務(wù)器負(fù)責(zé)從response對(duì)象中獲取到響應(yīng)信息,再按照http響應(yīng)信息的格式組織成響應(yīng)消息,發(fā)送給瀏覽器。
常用的方法:
setContentType("參數(shù)名")--設(shè)置響應(yīng)的字符編碼方式
sendRedirect()--完成重定向
getOutputStream()--獲取字節(jié)輸出流
getWriter()--獲取字符輸出流
setHeader("Access-Control-Allow-Origin", "*"); --專門用來(lái)解決跨域問題
測(cè)試
package cn.tedu.resp;
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(name = "RespServlet")
public class RespServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//響應(yīng)數(shù)據(jù)中包含中文,會(huì)亂碼,用以下代碼指定編碼,緩沖字符輸出流內(nèi)部有一個(gè)緩沖區(qū),這個(gè)緩沖區(qū)的默認(rèn)字符集是ISO-8859-1
response.setContentType("text/html;charset=utf-8");
//給瀏覽器響應(yīng)數(shù)據(jù)
response.getWriter().write("你好123");
}
}
重定向
概述
當(dāng)瀏覽器向服務(wù)器發(fā)送請(qǐng)求訪問某一個(gè)資源A時(shí),資源A在響應(yīng)時(shí)通知瀏覽器需要再進(jìn)一步請(qǐng)求才能獲取到對(duì)應(yīng)的資源,瀏覽器再次向服務(wù)器發(fā)送請(qǐng)求訪問資源B,最終是由資源B響應(yīng)瀏覽器要獲取的數(shù)據(jù),這個(gè)過(guò)程叫做重定向,具有以下特點(diǎn):
1,重定向前后是兩次請(qǐng)求、兩次響應(yīng)
2,重定向前后,瀏覽器地址欄地址會(huì)發(fā)生變化(因?yàn)閮纱握?qǐng)求都是通過(guò)瀏覽器發(fā)起,瀏覽器知道這個(gè)跳轉(zhuǎn)過(guò)程,因此地址欄地址會(huì)發(fā)生變化)。
3,重定向前后的request對(duì)象不是同一個(gè) (因此重定向前后是兩次請(qǐng)求,服務(wù)器根據(jù)兩次請(qǐng)求會(huì)創(chuàng)建兩個(gè)request對(duì)象,因此request對(duì)象不是同一個(gè))
4,重定向前后的兩個(gè)資源可以來(lái)自不同的Web應(yīng)用,甚至可以是來(lái)自不同的虛擬主機(jī)或者服務(wù)器。
5,使用代碼: response.sendRedirect(“重定向到資源的路徑”);

測(cè)試
觀察,一開始是訪問A資源,服務(wù)器內(nèi)部重定向后,地址欄已經(jīng)變成了B資源的訪問方式了.是兩次請(qǐng)求兩次響應(yīng)
package cn.tedu.resp;
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(name = "RedirectServlet")
public class RedirectServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//重定向的地址,可以隨意設(shè)置,不是必須在同一工程中
//response.sendRedirect("http://localhost:8080/cgbservletjava01_war_exploded/RespServlet");
response.sendRedirect("https://www.baidu.com/");
}
}擴(kuò)展:在web工程里使用Servlet程序 在IDEA里創(chuàng)建一個(gè)web工程
File-New-Project-選Java Enterprise并勾選右側(cè)的Web Application-next-輸入工程名稱-Finish
整理web工程目錄結(jié)構(gòu)

修改資源輸出位置

修改jar包存放位置


配置Tomcat服務(wù)器
略,詳情見Tomcat服務(wù)器的內(nèi)容
擴(kuò)展案例
創(chuàng)建前端網(wǎng)頁(yè)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<link rel="stylesheet" >
</head>
<body>
<div id="app">
<el-button type="danger" @click="get()">點(diǎn)我</el-button>
<el-input v-model="name"></el-input>
<el-input v-model="id"></el-input>
</div>
<script>
new Vue({
el:"#app",
data(){
return{
name:'',
id:''
}
},
methods:{
get(){
// axios.get("http://localhost:8080/axios/t3?id=10&name=jack").then(
axios.get("http://localhost:8080/axios/t3",{
params:{
id:10,
name:'jack'
}
}).then(
a=>{
console.log(a);
console.log(a.data);
this.id=a.data.id;
this.name=a.data.name;
}
)
}
}
})
</script>
</body>
</html>創(chuàng)建Servlet程序
package cn.tedu.cgb2110boot03.test;
import com.alibaba.fastjson.JSON;
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("/axios/t3")
public class ServletT3 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println(111);
response.setHeader("Access-Control-Allow-Origin", "*");
String id = request.getParameter("id");
String name = request.getParameter("name");
// {"id":"10","name":"jack"}
// "{\"id\":\"10\",\"name\":\"jack\"}"
String json="{\"id\":\""+id+"\",\"name\":\""+name+"\"}";
response.getWriter().write(json);
}
}總結(jié)
到此這篇關(guān)于Servlet從入門到精通的文章就介紹到這了,更多相關(guān)Servlet入門內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
xxl-job對(duì)比ElasticJob使用示例詳解
這篇文章主要為大家介紹了xxl-job對(duì)比ElasticJob使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06
基于java socket實(shí)現(xiàn) 聊天小程序
這篇文章主要介紹了基于java socket實(shí)現(xiàn) 聊天小程序,代碼分為服務(wù)器和客戶端,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12
java并發(fā)包中CountDownLatch和線程池的使用詳解
這篇文章主要介紹了java并發(fā)包中CountDownLatch和線程池的使用詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-02-02
struts2的國(guó)際化實(shí)現(xiàn)網(wǎng)站整體中英文切換實(shí)例代碼
本篇文章主要介紹了struts2的國(guó)際化實(shí)現(xiàn)網(wǎng)站整體中英文切換實(shí)例代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10
Java中創(chuàng)建對(duì)象的5種方式總結(jié)
本篇文章主要介紹了Java中創(chuàng)建對(duì)象的5種方式總結(jié),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-02-02
MyBatis映射文件中parameterType與resultType的用法詳解
MyBatis中的ParameterType指的是SQL語(yǔ)句中的參數(shù)類型,即傳入SQL語(yǔ)句中的參數(shù)的類型,下面這篇文章主要給大家介紹了關(guān)于MyBatis映射文件中parameterType與resultType用法的相關(guān)資料,需要的朋友可以參考下2023-04-04
Java8新特性之再見Permgen_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了Java8新特性之再見Permgen的相關(guān)知識(shí),非常不錯(cuò),具有參考借鑒價(jià)值,需要的的朋友參考下吧2017-06-06
詳解Java編程中包package的內(nèi)容與包對(duì)象的規(guī)范
這篇文章主要介紹了Java編程中包package的內(nèi)容與包對(duì)象的規(guī)范,是Java入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-12-12

