Servlet
一问畅、 第一個(gè) Servlet 實(shí)現(xiàn)
Servlet 是 Server 與 Applet 的縮寫(xiě)是晨,是服務(wù)端小程序的意思翰撑。使用 Java 語(yǔ)
言編寫(xiě)的服務(wù) 器端程序置吓,可以像生成動(dòng)態(tài)的 WEB 頁(yè)犁嗅, Servlet
主要運(yùn)行在服務(wù)器端边涕,并由服務(wù)器調(diào)用執(zhí)行, 是一種按照 Servlet
標(biāo)準(zhǔn)來(lái)開(kāi)發(fā)的類(lèi)褂微。 是 SUN 公司提供的一門(mén)用于開(kāi)發(fā)動(dòng)態(tài) Web 資源的技
術(shù)功蜓。(言外之意:要實(shí)現(xiàn) web 開(kāi)發(fā),需要實(shí)現(xiàn) Servlet 標(biāo)準(zhǔn))Servlet
本質(zhì)上也是 Java 類(lèi)宠蚂,但要遵循 Servlet 規(guī)范進(jìn)行編寫(xiě)式撼,沒(méi)有
main()方法,它的創(chuàng) 建求厕、使用著隆、銷(xiāo)毀都由 Servlet 容器進(jìn)行管理(如
Tomcat)。(言外之意:寫(xiě)自己的類(lèi)甘改,不用寫(xiě) main 方法旅东,別人自動(dòng)調(diào)用)
Servlet 是和 HTTP 協(xié)議是緊密聯(lián)系的,其可以處理 HTTP 協(xié)議相關(guān)的所有
內(nèi)容十艾。這也是 Servlet 應(yīng)用廣泛的原因之一抵代。
提供了 Servlet 功能的服務(wù)器,叫做 Servlet 容器忘嫉,其常見(jiàn)容器有很多荤牍,如
Tomcat, Jetty, WebLogic Server, WebSphere, JBoss 等等。
1. 實(shí)現(xiàn)
1.1新建Servlet繼承HttpServlet類(lèi)
1)庆冕、新建普通java類(lèi)
2)康吵、繼承HttpServlet類(lèi)
3)、重寫(xiě)service()方法
4)访递、配置web.xml文件晦嵌,設(shè)置servlet對(duì)外訪(fǎng)問(wèn) 路徑
注意事項(xiàng):
1)、web.xml改動(dòng)之后必須重啟服務(wù)器
2)、url-pattern的值必須唯一
java.lang.IllegalArgumentException: The servlets named [servelt01] and
[servlet02] are both mapped to the url-pattern [/ser01] which is not
permitted
3)惭载、servlet-mapping標(biāo)簽中的servlet-name的值必須是已存在的值(servalet標(biāo)簽中的servlet-name)
java.lang.IllegalArgumentException: Servlet mapping specifies an unknown
servlet name servelt02
4)旱函、servlet標(biāo)簽中servlet-name要與servlet-mapping標(biāo)簽中的servlet-name的值保持一致
(servlet標(biāo)簽中servlet-name存在)
如果不一致,代碼不會(huì)報(bào)錯(cuò)描滔,只是訪(fǎng)問(wèn)的不是你的指定資源
5)棒妨、servlet標(biāo)簽中的servlet-class的路徑不能寫(xiě)錯(cuò)
java.lang.ClassNotFoundException: com.shsxt.servlet.Servlet04
6)、servlet-mapping標(biāo)簽中的url-pattern的值前面必須加"/"
java.lang.IllegalArgumentException: Invalid <url-pattern> ser01 in
servlet mapping
7)含长、servlet標(biāo)簽中的servlet-name的值必須唯一
Duplicate unique value [servlet01] declared for identity constraint
"web-app-servlet-name-uniqueness" of element "web-app".
package com.shsxt.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 新建Servlet 繼承HttpServlet類(lèi)
* 1券腔、新建普通java類(lèi)
* 2、繼承HttpServlet類(lèi)
* 3拘泞、重寫(xiě)service()方法
* 4纷纫、配置web.xml文件,設(shè)置servlet對(duì)外訪(fǎng)問(wèn) 路徑
* @author Lisa Li
*
*/
@SuppressWarnings("serial")
public class Servlet01 extends HttpServlet {
@Override
protected void service(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException {
System.out.println("Servlet01的創(chuàng)建....");
}
}
配置 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>servletDemo</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>server01</servlet-name>
<servlet-class>com.shsxt.servlet.ServletDemo01</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>server01</servlet-name>
<url-pattern>/ser01</url-pattern>
</servlet-mapping>
<!-- Servlet的配置 -->
<servlet>
<servlet-name>servlet01</servlet-name> <!-- 給服務(wù)器看的名字,servlet標(biāo)簽中servlet-name要與servlet-mapping標(biāo)簽中的servlet-name的值保持一致 -->
<servlet-class>com.shsxt.servlet.servlet01</servlet-class> <!-- servlet類(lèi)的路徑 -->
</servlet>
<servlet-mapping>
<servlet-name>servlet01</servlet-name> <!-- 給服務(wù)器看的名字陪腌,servlet-mapping標(biāo)簽中的servlet-name的值要與servlet標(biāo)簽中servlet-name保持一致 -->
<url-pattern>/ser02</url-pattern> <!-- 對(duì)外訪(fǎng)問(wèn)路徑 -->
</servlet-mapping>
</web-app>
5)涛酗、 發(fā)布項(xiàng)目并啟動(dòng)服務(wù)
到此,需要編寫(xiě)和配置的地方已經(jīng)完成偷厦,項(xiàng)目已經(jīng)完整了,但是如果需要外
界能夠訪(fǎng)問(wèn)燕刻, 還需要將項(xiàng)目發(fā)布到服務(wù)器上并運(yùn)行服務(wù)器
注意 url 的格式正確只泼, tomcat 的端口為 8080。
6)卵洗、 訪(fǎng)問(wèn)并查看結(jié)果
在項(xiàng)目正確發(fā)布到服務(wù)器上之后请唱,用戶(hù)即可通過(guò)瀏覽器訪(fǎng)問(wèn)該項(xiàng)目中的資源。
到這里我們的第一個(gè) Servlet 就實(shí)現(xiàn)了过蹂!
1.2方式二:繼承GenericServlet類(lèi)
* 1十绑、新建普通java類(lèi)
* 2、繼承GenericServlet類(lèi)
* 3酷勺、重寫(xiě)service()方法
* 4本橙、配置web.xml文件,設(shè)置servlet對(duì)外訪(fǎng)問(wèn) 路徑
package com.shsxt.servlet;
import java.io.IOException;
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* 方式二:繼承GenericServlet類(lèi)
* 1脆诉、新建普通java類(lèi)
* 2甚亭、繼承GenericServlet類(lèi)
* 3、重寫(xiě)service()方法
* 4击胜、配置web.xml文件亏狰,設(shè)置servlet對(duì)外訪(fǎng)問(wèn) 路徑
* @author Lisa Li
*
*/
@SuppressWarnings("serial")
public class Servlet02 extends GenericServlet {
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("Servlet02.....");
}
}
1.3方式三:實(shí)現(xiàn)Servlet接口
* 1、新建普通java類(lèi)
* 2偶摔、實(shí)現(xiàn)Servlet接口
* 3暇唾、重寫(xiě)service()方法
* 4、配置web.xml文件,設(shè)置servlet對(duì)外訪(fǎng)問(wèn) 路徑
public class Servlet03 implements Servlet {
@Override
public void init(ServletConfig config) throws ServletException {
// TODO Auto-generated method stub
}
@Override
public ServletConfig getServletConfig() {
// TODO Auto-generated method stub
return null;
}
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("Servlet03....");
}
@Override
public String getServletInfo() {
// TODO Auto-generated method stub
return null;
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}
2. 工作原理
執(zhí)行過(guò)程
客戶(hù)端發(fā)出請(qǐng)求 根據(jù) web.xml 文件的配置策州,找到對(duì)應(yīng)的 讀取中的值 找到
對(duì)應(yīng)的 找到該 class 并加載執(zhí)行該 class瘸味,返回結(jié)果 由 Web 服務(wù)器將結(jié)果響
應(yīng)給客戶(hù)端
3. Servlet 的生命周期
Servlet 沒(méi)有 main()方法,不能獨(dú)立運(yùn)行抽活,它的運(yùn)行完全由 Servlet 引擎來(lái)控
制和調(diào)度硫戈。 所謂生命周期,指的是 servlet 容器何時(shí)創(chuàng)建 servlet
實(shí)例下硕、何時(shí)調(diào)
用其方法進(jìn)行請(qǐng)求的處理丁逝、
何時(shí)并銷(xiāo)毀其實(shí)例的整個(gè)過(guò)程。(此處討論默認(rèn)的生命周期)
實(shí)例和初始化時(shí)機(jī)
當(dāng)請(qǐng)求到達(dá)容器時(shí)梭姓,容器查找該 servlet 對(duì)象是否存在霜幼,如果不存在,則會(huì)
創(chuàng)建實(shí)例并 進(jìn)行初始化誉尖。
就緒/調(diào)用/服務(wù)階段
有請(qǐng)求到達(dá)容器罪既,容器調(diào)用 servlet 對(duì)象的 service()方法,處理請(qǐng)求的方法在
整個(gè)聲明周 期中可以被多次調(diào)用;
HttpServlet 的 service()方法铡恕,會(huì)依據(jù)請(qǐng)求方式來(lái)調(diào)用 doGet()或者 doPost()
方法琢感。但是, 這兩個(gè) do 方法默認(rèn)情況下探熔,會(huì)拋出異常驹针,需要子類(lèi)去
override。
銷(xiāo)毀時(shí)機(jī)
當(dāng)容器關(guān)閉時(shí)(應(yīng)用程序停止時(shí))诀艰,會(huì)將程序中的 Servlet 實(shí)例進(jìn)行銷(xiāo)毀柬甥。
上述的生命周期可以通過(guò) Servlet 中的生命周期方法來(lái)觀(guān)察。在 Servlet 中
有三個(gè)生命周 期方法其垄,不由用戶(hù)手動(dòng)調(diào)用苛蒲,而是在特定的時(shí)機(jī)有容器自動(dòng)調(diào)用,
觀(guān)察這三個(gè)生命周期方法 即可觀(guān)察到 Servlet 的生命周期绿满。
1)init 方法臂外,在 Servlet 實(shí)例創(chuàng)建之后執(zhí)行(證明該 Servlet
有實(shí)例創(chuàng)建了)
2)service 方法,每次有請(qǐng)求到達(dá)某個(gè) Servlet
方法時(shí)執(zhí)行喇颁,用來(lái)處理請(qǐng)求(證
明該 Servlet 進(jìn)行 服務(wù)了)
3)destroy 方法寄月, Servlet 實(shí)例銷(xiāo)毀時(shí)執(zhí)行(證明該 Servlet
的實(shí)例被銷(xiāo)毀了)
@SuppressWarnings("serial")
public class Servlet04 extends HttpServlet {
/**
* 初始化,服務(wù)器方式无牵,由服務(wù)器調(diào)用
* 只會(huì)調(diào)用一次漾肮,當(dāng)?shù)谝淮握?qǐng)求時(shí)
* 當(dāng)請(qǐng)求到達(dá)servlet時(shí),servlet容器會(huì)判斷該實(shí)例是否存在茎毁,如果不存在克懊,才會(huì)調(diào)用該方法
*/
@Override
public void init() throws ServletException {
System.out.println("Servlet04 init....");
}
/**
* 服務(wù)/調(diào)用方法忱辅,服務(wù)器方式,由服務(wù)器調(diào)用
* 可以調(diào)用多次谭溉,每次請(qǐng)求到達(dá)時(shí)都會(huì)調(diào)用
*/
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Servlet04...");
}
/**
* 銷(xiāo)毀方法墙懂,服務(wù)器方式,由服務(wù)器調(diào)用
* 只會(huì)調(diào)用一次扮念,容器關(guān)閉時(shí)(正常關(guān)閉時(shí)才會(huì)打铀鸢帷)
*/
@Override
public void destroy() {
System.out.println("Servlet04 destroy...");
}
}
3.1Servlet 的生命周期,
簡(jiǎn)單的概括這就分為四步:
servlet 類(lèi)加載-->實(shí)例化-->服務(wù)-->銷(xiāo)毀柜与。下面我們描述一下 Tomcat 與
Servlet 是如何工作的,看看下面的時(shí)序圖巧勤。
1)、 Web Client 向 Servlet 容器(Tomcat)發(fā)出 Http 請(qǐng)求
2)弄匕、 Servlet 容器接收 Web Client 的請(qǐng)求
3)颅悉、 Servlet 容器創(chuàng)建一個(gè) HttpRequest 對(duì)象,將 Web Client 請(qǐng)求的信息封
裝到這個(gè)對(duì)象 中
4)迁匠、 Servlet 容器創(chuàng)建一個(gè) HttpResponse 對(duì)象
5)剩瓶、 Servlet 容器調(diào)用 HttpServlet 對(duì)象的 service 方法,把 HttpRequest
對(duì)
象與 HttpResponse 對(duì)象作為參數(shù)城丧,傳給 HttpServlet 對(duì)象
6)延曙、 HttpServlet 調(diào)用 HttpRequest 對(duì)象的有關(guān)方法,獲取 Http 請(qǐng)求信息
7)亡哄、 HttpServlet 調(diào)用 HttpResponse 對(duì)象的有關(guān)方法搂鲫,生成響應(yīng)數(shù)據(jù)
8)、 Servlet 容器把 HttpServlet 的響應(yīng)結(jié)果傳給 Web Client
4. Servlet的配置
Servlet 除了配置基本的訪(fǎng)問(wèn)信息磺平,還可以配置初始化參數(shù),自啟動(dòng)等拐辽,并
且一個(gè) Servlet 可以配置多個(gè)訪(fǎng)問(wèn)路徑()拣挪,還可以使用通配符"*"。
4.1俱诸、初始化參數(shù)
* 設(shè)置在web.xml中的servlet標(biāo)簽中
* <init-param>
* <param-name><param-/name>
* <param-value></param-value>
* </init-param>
4.2菠劝、自啟動(dòng)(服務(wù)器啟動(dòng)時(shí)自動(dòng)實(shí)例化servlet)
*設(shè)置在web.xml中的servlet標(biāo)簽中,要寫(xiě)在init-param標(biāo)簽之后
*<load-on-startup>1</load-on-startup>
*值越小睁搭,優(yōu)先級(jí)越高
4.3赶诊、servlet配置多個(gè)訪(fǎng)問(wèn)路徑
*以Servlet05為例:
a. 只設(shè)置一個(gè)路徑
*<url-pattern>/ser05</url-pattern>
b.設(shè)置多個(gè)路徑
*<url-pattern>/ser05</url-pattern>
* <url-pattern>/ser005</url-pattern>
c.以指定路徑開(kāi)頭的所有資源路徑
*<url-pattern>/test/*</url-pattern>
d.以指定后綴結(jié)尾的所有資源路徑
<url-pattern>*.html</url-pattern>
e.所有路徑都可以訪(fǎng)問(wèn)
<url-pattern>*</url-pattern>
*通配符"*"
1、"*"只能放在最前面或者最后面园骆,不能放在中間舔痪,不能單獨(dú)使用,不能和字母拼接
2锌唾、值越精準(zhǔn)锄码,優(yōu)先級(jí)越高
普通Servlet05類(lèi)
*/
@SuppressWarnings("serial")
public class Servlet05 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Servlet05....");
}
@Override
public void init(ServletConfig config) throws ServletException {
// 得到指定名稱(chēng)的的初始化的值
String encode = config.getInitParameter("encode");
System.out.println(encode);
}
}
web.xml配置
<servlet>
<servlet-name>servlet05</servlet-name>
<servlet-class>com.shsxt.servlet.Servlet05</servlet-class>
<!-- 設(shè)置初始化參數(shù) -->
<init-param>
<param-name>encode</param-name>
<param-value>UTF-8</param-value>
</init-param>
<!-- 自啟動(dòng) -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>servlet05</servlet-name>
<!-- a. 只設(shè)置一個(gè)路徑 -->
<!-- <url-pattern>/ser05</url-pattern> -->
<!-- b.設(shè)置多個(gè)路徑 -->
<!-- <url-pattern>/ser05</url-pattern>
<url-pattern>/ser005</url-pattern> -->
<!--c.以指定路徑開(kāi)頭的所有資源路徑 -->
<!-- <url-pattern>/test/*</url-pattern> -->
<!-- d.以指定后綴結(jié)尾的所有資源路徑 -->
<!-- <url-pattern>*.html</url-pattern> -->
<!-- 所有路徑都可以訪(fǎng)問(wèn) -->
<url-pattern>/*</url-pattern>
</servlet-mapping>
二夺英、WEB請(qǐng)求和常用對(duì)象
1、 請(qǐng)求的方式
要訪(fǎng)問(wèn)服務(wù)器首先需要由客戶(hù)端主動(dòng)發(fā)出請(qǐng)求滋捶,在實(shí)際的操作中痛悯,我們可以
通過(guò)多種方式向服務(wù)器發(fā)起請(qǐng)求。
根據(jù)不同的場(chǎng)景需求重窟,使用不同的請(qǐng)求方式可以達(dá)到不同的效果载萌。
1.1. 地址欄輸入
在瀏覽器地址欄直接輸入要訪(fǎng)問(wèn)的地址即可,此種方式可以看做是訪(fǎng)問(wèn)服務(wù)
器的起始操作巡扇。
http://ip:port/path
1.2. 超鏈接
使用超鏈接也可以向服務(wù)器發(fā)出請(qǐng)求
<a >尚學(xué)堂</a>
1.3. Form 表單
當(dāng)需要向服務(wù)器發(fā)送請(qǐng)求扭仁,并且傳輸一些用戶(hù)輸入的數(shù)據(jù)時(shí),我們優(yōu)先選擇form
表單的方式發(fā)起請(qǐng)求
**1.4. ajax
**通過(guò) ajax 發(fā)起的請(qǐng)求霎迫,屬于異步請(qǐng)求斋枢,能實(shí)現(xiàn)局部刷新的效果,是一種比
較常用的請(qǐng)求方式知给。
通過(guò) jQuery 中的 ajax(),get(),post(),getJSON()等方法都能發(fā)送請(qǐng)求
1.5. 請(qǐng)求轉(zhuǎn)發(fā)
通過(guò)服務(wù)器內(nèi)部將請(qǐng)求進(jìn)行一次轉(zhuǎn)發(fā)瓤帚,可以請(qǐng)求到其他資源。
1.6. 重定向
服務(wù)器通過(guò)給定一個(gè)新資源的地址涩赢,響應(yīng)會(huì)客戶(hù)端后戈次,客戶(hù)端自動(dòng)再次發(fā)送
一個(gè)請(qǐng)求到新資源的地址處。
2筒扒、 HttpServletRequest 對(duì)象
2.1. 介紹
HttpServletRequest 對(duì)象:
主要作用是用來(lái)接收客戶(hù)端發(fā)送過(guò)來(lái)的請(qǐng)求信息怯邪,
例如:請(qǐng)求的參數(shù),發(fā)送的頭信息等都屬于客戶(hù)端發(fā)來(lái)的信息花墩,
service()方法中形參接收的是 HttpServletRequest
接口的實(shí)例化對(duì)象悬秉,表示該對(duì)象主要應(yīng)用在HTTP 協(xié)議上,該對(duì)象是由 Tomcat
封裝好傳遞過(guò)來(lái)冰蘑。
HttpServletRequest 是 ServletRequest 的子接口和泌, ServletRequest 只有一個(gè)
子接口,就是 HttpServletRequest祠肥。既然只有一個(gè)子接口為什么不將兩個(gè)接口合
并為一個(gè)武氓?
從長(zhǎng)遠(yuǎn)上講:現(xiàn)在主要用的協(xié)議是 HTTP 協(xié)議,但以后可能出現(xiàn)更多新的
協(xié)議仇箱。若以后想要支持這種新協(xié)議县恕,只需要直接繼承 ServletRequest 接口就行
了。
在 HttpServletRequest 接口中剂桥,定義的方法很多忠烛,但都是圍繞接收客戶(hù)端參
數(shù)的。但是怎么拿到該對(duì)象呢权逗?不需要况木,直接在 Service
方法中由容器傳入過(guò)來(lái)垒拢,而我們需要做的就是取出對(duì)象中的數(shù)據(jù),進(jìn)行分析火惊、處理求类。
2.2. 常用形式
package com.shsxt.servlet;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 常用方法
* @author Lisa Li
*
*/
@SuppressWarnings("serial")
public class Servlet01 extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("Servlet01.....");
System.out.println("==============常用方法============");
// 獲取請(qǐng)求的完整路徑 (從http到"?"前面)
String url = request.getRequestURL() + "";
System.out.println("獲取請(qǐng)求的完整路徑:" + url);
// 獲取請(qǐng)求的部分路徑 (從端口后"?"前面)
String uri = request.getRequestURI();
System.out.println("獲取請(qǐng)求的部分路徑:" + uri);
// 獲取請(qǐng)求的參數(shù)字符串 (從"?"開(kāi)始到最后)
String queryString = request.getQueryString();
System.out.println("獲取請(qǐng)求的參數(shù)字符串:" +queryString);
// 獲取請(qǐng)求類(lèi)型 (GET/POST)
String method = request.getMethod();
System.out.println("獲取請(qǐng)求類(lèi)型:" + method);
// 獲取請(qǐng)求協(xié)議版本
String p = request.getProtocol();
System.out.println("獲取請(qǐng)求協(xié)議版本:" + p);
// 獲取站點(diǎn)名
String contextPath = request.getContextPath();
System.out.println("獲取站點(diǎn)名:" + contextPath);
System.out.println("===========獲取請(qǐng)求頭==========");
// 獲取指定請(qǐng)求頭
String host = request.getHeader("host");
System.out.println("Host:" + host);
// 獲取所有請(qǐng)求頭的名稱(chēng)枚舉集合
Enumeration<String> enumeration = request.getHeaderNames();
while(enumeration.hasMoreElements()) {
System.out.println(enumeration.nextElement());
}
System.out.println("==========獲取請(qǐng)求的參數(shù)===========");
// 獲取指定名稱(chēng)的參數(shù)值
String uname = request.getParameter("uname");
String upwd = request.getParameter("upwd");
System.out.println("用戶(hù)名:" + uname + ",用戶(hù)密碼:" +upwd);
// 獲取指定名稱(chēng)的參數(shù)的所有值
String[] hobbys = request.getParameterValues("hobby");
// 判斷并遍歷
if (hobbys != null && hobbys.length > 0) {
for (String hobby : hobbys) {
System.out.println("愛(ài)好:" + hobby);
}
}
}
}
2.3 請(qǐng)求亂碼解決
由于現(xiàn)在的 request 屬于接收客戶(hù)端的參數(shù)屹耐,所以必然有其默認(rèn)的語(yǔ)言編碼尸疆,
主要是由于在解析過(guò)程中默認(rèn)使用的編碼方式為 ISO-8859-1(此編碼不支持中
文),所以解析時(shí)一定會(huì)出現(xiàn)亂碼惶岭。要想解決這種亂碼問(wèn)題寿弱,需要設(shè)置 request
中的編碼方式,告訴服務(wù)器以何種方式來(lái)解析數(shù)據(jù)按灶≈⒏铮或者在接收到亂碼數(shù)據(jù)以后,再通過(guò)相應(yīng)的編碼格式還原鸯旁。
1)POST請(qǐng)求
* Tomcat8亂碼
* Tomcat7亂碼
*
2)GET請(qǐng)求
* Tomcat7亂碼
* Tomcat8不會(huì)亂碼
*
3)解決POST請(qǐng)求亂碼:
* request.setCharacterEncoding("UTF-8"); //
設(shè)置服務(wù)器的編碼方式噪矛,該方式只對(duì)post請(qǐng)求生效,如果是get請(qǐng)求沒(méi)有任何效果
* new
String(request.getParameter(name).getBytes("ISO-8859-1"),"UTF-8");
4)解決GET請(qǐng)求亂碼:(如果原來(lái)不亂碼铺罢,通過(guò)new
String()去處理艇挨,會(huì)出現(xiàn)另外一種亂碼)
* new
String(request.getParameter(name).getBytes("ISO-8859-1"),"UTF-8");
*
5)總結(jié) :
* Post請(qǐng)求:無(wú)論什么版本的服務(wù)器,都亂碼
* Get請(qǐng)求:Tomcat8及以上版本韭赘,不亂碼缩滨;Tomcat7及以下版本亂碼。
測(cè)試頁(yè)面index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登錄</title>
</head>
<body>
<form action="ser02" method="get">
姓名:<input type="text" name="uname" /> <br/>
密碼:<input type="password" name="upwd" /> <br/>
<input type="submit" value="登錄" />
</form>
</body>
</html>
servlet 程序
@SuppressWarnings("serial")
public class Servlet02 extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("Servlet02.....");
/* POST 請(qǐng)求*/
// 解決POST請(qǐng)求亂碼問(wèn)題
// request.setCharacterEncoding("UTF-8"); // 設(shè)置服務(wù)器的編碼方式泉瞻,該方式只對(duì)post請(qǐng)求生效脉漏,如果是get請(qǐng)求沒(méi)有任何效果
// 接收參數(shù)
String uname = request.getParameter("uname");
//String upwd = request.getParameter("upwd");
System.out.println("姓名:" + uname);
// System.out.println("密碼:" + upwd);
/* GET請(qǐng)求 */
String userName = new String(uname.getBytes("ISO-8859-1"),"UTF-8");
System.out.println("userName:" + userName);
}
2.4. 請(qǐng)求轉(zhuǎn)發(fā)
請(qǐng)求轉(zhuǎn)發(fā),是一種服務(wù)器的行為袖牙,當(dāng)客戶(hù)端請(qǐng)求到達(dá)后侧巨,服務(wù)器進(jìn)行轉(zhuǎn)發(fā),
此時(shí)會(huì)將請(qǐng)求對(duì)象進(jìn)行保存贼陶,地址欄中的 URL 地址不會(huì)改變,得到響應(yīng)后巧娱,服
務(wù)器端再將響應(yīng)發(fā)送給客戶(hù)端碉怔, 從始至終只有一個(gè)請(qǐng)求發(fā)出。
實(shí)現(xiàn)方式如下禁添,達(dá)到多個(gè)資源協(xié)同響應(yīng)的效果撮胧。
request.getRequestDispatcher(url).forward(request, response);
* 1、服務(wù)器行為老翘,服務(wù)器行為
* 2芹啥、地址欄不會(huì)發(fā)生改變
* 3锻离、只有一次請(qǐng)求,request對(duì)象共享
package com.shsxt.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 請(qǐng)求轉(zhuǎn)發(fā)
* request.getRequestDispatcher(url).forward(request, response);
*
* 1墓怀、服務(wù)器行為汽纠,服務(wù)器行為
* 2、地址欄不會(huì)發(fā)生改變
* 3傀履、只有一次請(qǐng)求虱朵,request對(duì)象共享
* @author Lisa Li
*
*/
@SuppressWarnings("serial")
public class Servlet03 extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("Servlet03....");
// 獲取參數(shù)
String uname = request.getParameter("uname");
System.out.println("Servlet03:" + uname);
// 請(qǐng)求轉(zhuǎn)發(fā)跳轉(zhuǎn)到指定頁(yè)面
// request.getRequestDispatcher("index.html").forward(request, response);
// 請(qǐng)求轉(zhuǎn)發(fā)跳轉(zhuǎn)到指定servlet
request.getRequestDispatcher("ser04").forward(request, response);
}
}
2.5. request 作為域?qū)ο?/em>
通過(guò)該對(duì)象可以在一個(gè)請(qǐng)求中傳遞數(shù)據(jù),作用范圍: 在一次請(qǐng)求中有效钓账,即
服務(wù)器跳轉(zhuǎn)有效碴犬。
request.setAttribute():設(shè)置域?qū)ο髢?nèi)容;
request.getAttribute(String name):獲取域?qū)ο髢?nèi)容梆暮;
request.removeAttribute(String name): 刪除域?qū)ο髢?nèi)容
服协。
request 域?qū)ο笾械臄?shù)據(jù)在一次請(qǐng)求中有效,則經(jīng)過(guò)請(qǐng)求轉(zhuǎn)發(fā)啦粹, request 域
中的數(shù)據(jù)依然 存在偿荷,則在請(qǐng)求轉(zhuǎn)發(fā)的過(guò)程中可以通過(guò) request
來(lái)傳輸/共享數(shù)據(jù)。
package com.shsxt.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* request域?qū)ο? * 將數(shù)據(jù)存到request作用域中卖陵,前臺(tái)頁(yè)面(JSP)從作用域中獲取域?qū)ο蟮闹? *
* setAttribute(name,value):設(shè)置作用域遭顶,name是字符串類(lèi)型,value是object類(lèi)型
* getAttribute(name):獲取指定名稱(chēng)的域?qū)ο蟮闹道崮瑁祷氐氖莖bject類(lèi)型
* removeAttribute(name):移除指定名稱(chēng)的域?qū)ο蟮闹? *
* @author Lisa Li
*
*/
@SuppressWarnings("serial")
public class Servlet05 extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("Servlet05....");
// setAttribute(name,value):設(shè)置作用域棒旗,name是字符串類(lèi)型,value是object類(lèi)型
request.setAttribute("userName", "Lisa");
// 請(qǐng)求轉(zhuǎn)發(fā)跳轉(zhuǎn)到index.jsp
request.getRequestDispatcher("index.jsp").forward(request, response);
}
}