Servlet開(kāi)發(fā)JavaWeb工程示例詳解
一、什么是Servlet?
Servlet是在服務(wù)器上運(yùn)行的小程序,也就是一個(gè)Java類,但比較特殊,不需要new,自動(dòng)就可以運(yùn)行。也有創(chuàng)建、垃圾回收和銷毀過(guò)程。Servlet是JavaWeb的三大組件之一(Servlet、Filter、Listener),它屬于動(dòng)態(tài)資源。Servlet的作用是處理請(qǐng)求,服務(wù)器會(huì)把接收到的請(qǐng)求交給Servlet來(lái)處理,在Servlet中通常需要:
- 接收請(qǐng)求數(shù)據(jù);
- 處理請(qǐng)求;
- 完成響應(yīng)。
例如客戶端發(fā)出登錄請(qǐng)求,或者輸出注冊(cè)請(qǐng)求,這些請(qǐng)求都應(yīng)該由Servlet來(lái)完成處理。Servlet需要我們自己來(lái)編寫,每個(gè)Servlet必須實(shí)現(xiàn)javax.servlet.Servlet接口。Servlet對(duì)象駐留在服務(wù)器內(nèi)存中。
1、編寫一個(gè)Servlet程序
寫一個(gè)java類,實(shí)現(xiàn)Servlet接口,實(shí)現(xiàn)了該接口,該類就不是普通的類了。
package servletdemo; import javax.servlet.*; import javax.servlet.annotation.WebServlet; import java.io.IOException; @WebServlet("/servlet") public class servletDemo implements Servlet { @Override public void init(ServletConfig servletConfig) throws ServletException { System.out.println("Hello Servlet"); } @Override public ServletConfig getServletConfig() { return null; } @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { } @Override public String getServletInfo() { return null; } @Override public void destroy() { } }
部署應(yīng)用到tomcat服務(wù)器。
測(cè)試:http://localhost:8080/MyMavenHome_war/servlet
在IDEA控制臺(tái)輸出 hello servlet,初體驗(yàn)成功!
二、Servlet的生命周期
實(shí)例化-->初始化-->服務(wù)->銷毀
出生:(實(shí)例化-->初始化)第一次訪問(wèn)Servlet就出生了(默認(rèn)情況下)。(說(shuō)明我可以改變它的出生時(shí)機(jī),比如讓servlet在服務(wù)器啟動(dòng)時(shí)就創(chuàng)建)
活著:(服務(wù))應(yīng)用活著,servlet就活著。(Servlet是單實(shí)例,其中的service()方法是多線程的。)
死亡:(銷毀)應(yīng)用被卸載了,servlet就銷毀了。
package servletdemo; import javax.servlet.*; import javax.servlet.annotation.WebServlet; import java.io.IOException; @WebServlet("/servlet") public class servletDemo implements Servlet { //Servlet生命周期的方法:實(shí)例化方法(new 對(duì)象,無(wú)參構(gòu)造) //在servlet第一次被訪問(wèn)時(shí)調(diào)用 public servletDemo() { System.out.println("*******servletDemo執(zhí)行了"); } //Servlet生命周期的方法:初始化方法 //在servlet第一次被訪問(wèn)時(shí)調(diào)用 @Override public void init(ServletConfig servletConfig) throws ServletException { System.out.println("*********init執(zhí)行了"); } @Override public ServletConfig getServletConfig() { return null; } //Servlet生命周期的方法:服務(wù)方法 //每次訪問(wèn)時(shí)都會(huì)被調(diào)用 @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("*******service執(zhí)行了"); } @Override public String getServletInfo() { return null; } //Servlet生命周期的方法:銷毀方法 //當(dāng)應(yīng)用被卸載時(shí)調(diào)用 @Override public void destroy() { System.out.println("*******destroy執(zhí)行了"); } }
三、實(shí)現(xiàn)Servlet的方式
實(shí)現(xiàn)Servlet有三種方式:
- 實(shí)現(xiàn)javax.servlet.Servlet接口;
- 繼承javax.servlet.GenericServlet類;
- 繼承javax.servlet.http.HttpServlet類;
自定義Servlet類的繼承結(jié)構(gòu),如下圖:
1、實(shí)現(xiàn)javax.servlet.Servlet接口(參見(jiàn):編寫一個(gè)servlet程序)
2、繼承javax.servlet.GenericServlet類(抽象類)(適配器模式)
GenericServlet類(抽象類)已經(jīng)實(shí)現(xiàn)了Servlet接口,我們用哪個(gè)方法就調(diào)用哪方法,不用再去全部實(shí)現(xiàn)了,哪怕是全部的空實(shí)現(xiàn)。
3、繼承javax.servlet.http.HttpServlet類(抽象類)(模板方法設(shè)計(jì)模式)
模板是HttpServlet類中的私有service()方法(開(kāi)發(fā)中常用方式)
HttpServlet類(抽象類)繼承了GenericServlet類(抽象類)
package servletdemo; 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("/servlet1") public class servlet extends HttpServlet { //具體實(shí)現(xiàn)1 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("******MydoGet*******"); System.out.println(req.getRemoteAddr()); } //具體實(shí)現(xiàn)2 @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("*******MydoPost******"); } }
注意:不要重寫父類Httpservlet中的service()方法,因?yàn)樵摲椒〞?huì)調(diào)用Httpservlet中私有的service()方法,
而該私有的service()方法會(huì)根據(jù)不同的提交表單的方式,會(huì)調(diào)用相應(yīng)的doGet()、doPost()、doHead()等方法。
我們?nèi)ブ貙戇@些不同的表單提交的方法即可。
Servlet(接口) -->GenericServlet(抽象類/適配器) -->HttpServlet(功能抽象類/模板)-->(繼承HttpServlet,具體實(shí)現(xiàn)類,重寫其功能)
4、公牛表白的故事
此故事純屬本人腦洞虛構(gòu)
故事內(nèi)容:草原上有一頭公牛喜歡一頭母牛,但是公牛不敢直接向母牛表白,有一天公牛找到一頭小牛,想讓小牛把他想對(duì)母牛說(shuō)的話說(shuō)給母牛聽(tīng),小牛答應(yīng)了,劇情很雞血,就這樣,看我用servlet實(shí)現(xiàn)
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <body> <h2>公牛表白準(zhǔn)備</h2> <a href="/servlet2" rel="external nofollow" >去表白</a> </body> </html>
package com.demo.servlet; import javax.servlet.*; import javax.servlet.annotation.WebServlet; import java.io.IOException; @WebServlet("/servlet2") public class ServletDemo2 extends GenericServlet { @Override public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { System.out.println("我是草原上的公牛"); System.out.println("我讓小牛把我對(duì)母牛的愛(ài)傳給她"); System.out.println("該說(shuō)的話我給小牛說(shuō)了,小牛聽(tīng)到了給我回復(fù)收到,并把我說(shuō)的話傳給母牛"); ServletContext application = this.getServletContext(); application.setAttribute("name","母牛"); application.getRequestDispatcher("/servlet3").forward(req,res); } }
package com.demo.servlet; import javax.servlet.ServletContext; 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.io.PrintWriter; @WebServlet("/servlet3") public class ServletDemo3 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req,resp); System.out.println("我是小牛"); //設(shè)置輸出格式和字符編碼 resp.setContentType("text/html;charset=utf-8"); //向頁(yè)面輸出內(nèi)容 PrintWriter out = resp.getWriter(); out.println("<h1>我是小牛</h1>"); ServletContext application = this.getServletContext(); String name = (String) application.getAttribute("name"); System.out.println("收到的名字:"+name); out.println("收到的名字:"+name); System.out.println("小牛收到"); application.setAttribute("love","公牛說(shuō)他愛(ài)你"); application.getRequestDispatcher("/servlet4").forward(req,resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("我是dopost"); resp.setContentType("text/html;charset=utf-8"); PrintWriter out = resp.getWriter(); out.println("<h1>我是servlet33</h1>"); } @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.service(req, resp); System.out.println("我是service333"); resp.setContentType("text/html;charset=utf-8"); PrintWriter out = resp.getWriter(); out.println("<h1>我是servlet333</h1>"); } }
package com.demo.servlet; 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.io.PrintWriter; @WebServlet("/servlet4") public class Servlet4 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req,resp); System.out.println("我是母牛"); String love = (String) this.getServletContext().getAttribute("love"); System.out.println(love); resp.setContentType("text/html;charset=utf-8"); //向頁(yè)面輸出內(nèi)容 PrintWriter out = resp.getWriter(); out.println("收到的表白:"+love); System.out.println("母牛收到"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { } }
5、servlet的映射細(xì)節(jié)
1、servlet的映射細(xì)節(jié)一:
一個(gè)servlet可以配置多個(gè)映射路徑(或者說(shuō):多個(gè)映射路徑可以指向同一個(gè)servlet),只要是name是一樣的就行
2、servlet的映射細(xì)節(jié)二:
通配符*代表任意字符串
url-pattern:*.xxx 以.xxx結(jié)尾的請(qǐng)求都可以訪問(wèn) 注:不要加/
url-pattern:/* 以任意字符串結(jié)尾的請(qǐng)求都可以訪問(wèn)
url-pattern:/xxxx/*以/xxxx/開(kāi)頭的請(qǐng)求都可以訪問(wèn)
6、對(duì)servlet配置有兩種方法
1、在web.xml中對(duì)servlet進(jìn)行配置
2、利用注解進(jìn)行配置
在servlet類的上面寫入注解@WebServlet("/hello")
7、實(shí)例一——在web.xml中配置
1、在Web.xml中配置路徑和參數(shù)
<!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> <servlet> <servlet-name>Servletdemo1</servlet-name> <servlet-class>com.demo.servlet.Servletdemo1</servlet-class> <init-param> <param-name>name</param-name> <param-value>tom</param-value> </init-param> <init-param> <param-name>password</param-name> <param-value>1234</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>Servletdemo1</servlet-name> <url-pattern>/servlet</url-pattern> </servlet-mapping> <context-param> <param-name>k</param-name> <param-value>xxxxxxxx</param-value> </context-param> </web-app>
2、在servlet中獲取參數(shù)和值
package com.demo.servlet; import javax.servlet.*; import java.io.IOException; import java.io.PrintWriter; import java.util.Enumeration; public class Servletdemo1 implements Servlet { private ServletConfig servletConfig; @Override public void init(ServletConfig config) throws ServletException { servletConfig=config; System.out.println("init調(diào)用了"); } @Override public ServletConfig getServletConfig() { return servletConfig; } @Override public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { //設(shè)置輸出格式和字符編碼 res.setContentType("text/html;charset=utf-8"); //向頁(yè)面輸出內(nèi)容 PrintWriter out = res.getWriter(); out.println("我是service"+"<br>"); System.out.println("我是service"); //方法一 String name = servletConfig.getInitParameter("name"); String password = servletConfig.getInitParameter("password"); System.out.println("在控制臺(tái)輸出信息:"); System.out.println("name:"+name+"password:"+password); out.println("name:"+name+" "+"password:"+password+"<br>"); //方法二 Enumeration<String> en = servletConfig.getInitParameterNames(); while (en.hasMoreElements()){ String names = en.nextElement(); String values = servletConfig.getInitParameter(names); System.out.println("在控制臺(tái)輸出信息:"); System.out.println(names+" "+values); out.println(names+" "+values+"<br>"); } String k = servletConfig.getServletContext().getInitParameter("k"); System.out.println("在控制臺(tái)輸出信息:"); System.out.println("k:"+k+"<br>"); out.println("k"+k); } @Override public String getServletInfo() { return null; } @Override public void destroy() { } }
8、實(shí)例二——利用注解配置
package com.demo.servlet; import javax.servlet.ServletContext; 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.io.PrintWriter; @WebServlet("/hello") public class Servlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req,resp); ServletContext servletContext = this.getServletContext(); servletContext.setAttribute("user","Tom"); String user = (String)servletContext.getAttribute("user"); //從請(qǐng)求的地址欄或表單中獲取信息 String user2 = req.getParameter("user"); System.out.println("獲取Context容器中的信息:"+user); System.out.println("在控制臺(tái)輸出從訪問(wèn)的地址欄獲取的信息:"+user2); resp.setContentType("text/html"); resp.setCharacterEncoding("utf-8"); PrintWriter out = resp.getWriter(); out.append("<!DOCTYPE html>") .append("<html><head></head><body>") .append("用戶是"+user) .append("</body></html>"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { } }
四、Servlet的線程安全
整個(gè)生命周期是單實(shí)例,但每次訪問(wèn)時(shí)為多線程。
一:?jiǎn)螌?shí)例變成多實(shí)例,但過(guò)時(shí)了,因?yàn)楹馁M(fèi)資源多,服務(wù)器壓力大。
二:加線程鎖,但數(shù)據(jù)會(huì)重復(fù)出現(xiàn)(沒(méi)有同步機(jī)制),且運(yùn)行效率低。
三:解決線程安全問(wèn)題的最佳辦法:不要寫全局變量,而寫局部變量(即改變變量的作用域)。
五、ServletContext對(duì)象(重要)
ServletContext:代表的是整個(gè)應(yīng)用。一個(gè)應(yīng)用只有一個(gè)ServletContext對(duì)象。單實(shí)例。
一個(gè)項(xiàng)目只有一個(gè)ServletContext對(duì)象,服務(wù)器會(huì)為每個(gè)應(yīng)用創(chuàng)建一個(gè)ServletContext對(duì)象,我們可以在N多個(gè)Servlet中來(lái)獲取這個(gè)唯一的對(duì)象,使用它可以給多個(gè)Servlet傳遞數(shù)據(jù),與Tomcat同生同死。
- ServletContext對(duì)象的創(chuàng)建是在服務(wù)器啟動(dòng)時(shí)完成的
- ServletContext對(duì)象的銷毀是在服務(wù)器關(guān)閉時(shí)完成的。
ServletContext對(duì)象的作用是在整個(gè)Web應(yīng)用的動(dòng)態(tài)資源直接共享數(shù)據(jù)。例如在AServlet中向ServletContext對(duì)象中保存一個(gè)值,然后在BServlet中就可以獲取這個(gè)值,這就是數(shù)據(jù)共享。
1、獲取ServletContext
在Servlet中獲取ServletContext對(duì)象:
在void init(ServletConfig config)中:
ServletContext context = config.getServletContext();
public class DemoServlet implements Servlet { public void init(ServletConfig config) throws ServletException { ServletContext context = config.getServletContext(); } }
GenericServlet類有g(shù)etServletContext()方法,所以可以直接使用this.getServletContext()類獲取。在GenericServlet或HttpServlet中獲取ServletContext對(duì)象:
public class HttpServletDemo extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context = this.getServletContext(); } }
HttpSession中也可以通過(guò)getServletContext()方法來(lái)獲得
2、域?qū)ο蟮墓δ?
ServletContext是JavaWeb四大域?qū)ο笾唬?/p>
- PageContext
- ServletRequest
- HttpSession
- ServletContext
所有域?qū)ο蠖际怯写嫒?shù)據(jù)的功能,因?yàn)橛驅(qū)ο髢?nèi)部有一個(gè)Map,用來(lái)存儲(chǔ)數(shù)據(jù),下面是ServletContext對(duì)象用來(lái)操作數(shù)據(jù)的方法:
void setAttribute(String name,Object val):用來(lái)存儲(chǔ)一個(gè)對(duì)象,也可以成為存儲(chǔ)一個(gè)域,參數(shù)分別為域的屬性名和屬性值,如果多次調(diào)用該方法,并且使用相同的name,那么就會(huì)覆蓋上一次的值,這一特性與Map相似。Object getAttribute(String name):用來(lái)獲取ServletContext中的數(shù)據(jù),當(dāng)前在獲取之前需要先存儲(chǔ)。void removeAttribute(String name):用來(lái)移除ServletContext中的域?qū)傩裕绻麉?shù)name不存在,那么該方法什么都不做。Enumeration getAttributeNames():獲取所有域?qū)傩缘拿Q。
2.獲取全局配置信息:
方法:public String getInitParamenter(String name)// 根據(jù)配置文件中的key得到value
3、讀取簡(jiǎn)單的資源文件(即只包含key=value的形式):
方法:public StringgetRealPath(Stringpath)//根據(jù)資源名稱得到資源的絕對(duì)路徑,可以得到當(dāng)前應(yīng)用任何位置的任何資源。
public class AServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //獲取帶有盤符的路徑 String path = this.getServletContext().getRealPath("/a.txt"); //獲取資源路徑后,再獲取輸入流對(duì)象 InputStream is = this.getServletContext().getResourceAsStream("/a.txt"); //獲取當(dāng)前路徑下的所有資源路徑 Set<String> paths = this.getServletContext().getResourcePaths("/WEB-INF"); } }
4、Servlet的轉(zhuǎn)發(fā)與重定向
轉(zhuǎn)發(fā)和重定向都能讓瀏覽器獲得另外一個(gè)URL所指向的資源,但兩者的內(nèi)部運(yùn)行機(jī)制有著很大的區(qū)別。
1、轉(zhuǎn)發(fā):有兩種方式獲得轉(zhuǎn)發(fā)對(duì)象(RequestDispatcher):一種是通過(guò)HttpServletRequest的getRequestDispatcher()方法獲得,一種是通過(guò)ServletContext的getRequestDispatcher()方法獲得;
以前的request范圍中存放的變量不會(huì)失效,就像把兩個(gè)頁(yè)面拼到了一起。 例如:
request.getRequestDispatcher (“demo.jsp"). forward(request, response);//轉(zhuǎn)發(fā)到demo.jsp
詳解:假設(shè)瀏覽器訪問(wèn)servlet1,而servlet1想讓servlet2為客戶端服務(wù)。此時(shí)servlet1調(diào)用forward()方法,將請(qǐng)求轉(zhuǎn)發(fā)給servlet2。但是調(diào)用forward()方法,對(duì)于瀏覽器來(lái)說(shuō)是透明的,瀏覽器并不知道為其服務(wù)的Servlet已經(jīng)換成Servlet2,它只知道發(fā)出了一個(gè)請(qǐng)求,獲得了一個(gè)響應(yīng)。瀏覽器URL的地址欄不變。
2、重定向:HttpServletResponse的sendRedirect()方法。
服務(wù)器根據(jù)此請(qǐng)求尋找資源并發(fā)送給客戶,它可以重定向到任意URL,不能共享request范圍內(nèi)的數(shù)據(jù)。例如:response.sendRedirect(“demo.jsp");//重定向到demo.jsp
詳解:假設(shè)瀏覽器訪問(wèn)servlet1,而servlet1想讓servlet2為客戶端服務(wù)。此時(shí)servlet1調(diào)用sendRedirect()方法,將客戶端的請(qǐng)求重新定向到Servlet2。接著瀏覽器訪問(wèn)servlet2,servlet2對(duì)客戶端請(qǐng)求作出反應(yīng)。瀏覽器URL的地址欄改變。
3、主要區(qū)別:
(1)sendRedirect()方法不但可以在位于同一個(gè)主機(jī)上的不同Web應(yīng)用程序之間進(jìn)行重定向,而且可以將客戶端重定向到其他服務(wù)器上的Web應(yīng)用程序資源。而forward()方法只能將請(qǐng)求轉(zhuǎn)發(fā)給同一Web應(yīng)用的組件。
(2)sendRedirect()方法不能轉(zhuǎn)發(fā)到“/WEB-INF/”路徑下的jsp頁(yè)面資源,而getRequestDispatcher().forword()可以重定向到“/WEB-INF/”路徑下的jsp頁(yè)面資源。如request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
(3)轉(zhuǎn)發(fā):瀏覽器URL的地址欄不變。
重定向:瀏覽器URL的地址欄改變。
5、實(shí)現(xiàn)Servlet的請(qǐng)求轉(zhuǎn)發(fā):
方法:public RequestDispatchergetRequestDispatcher(String path)//參數(shù)表示要跳轉(zhuǎn)到哪去
6、依賴和關(guān)聯(lián)
如果是通過(guò)參數(shù)傳過(guò)來(lái)的對(duì)象,就叫依賴。
通過(guò)方法得到的對(duì)象,就叫關(guān)聯(lián)。
六、HTTP請(qǐng)求與響應(yīng)
1、HTTP請(qǐng)求常用方法
Cookie[] getCookies()
返回一個(gè)數(shù)組,包含客戶端發(fā)送該請(qǐng)求的所有的 Cookie 對(duì)象。
Enumeration getAttributeNames()
返回一個(gè)枚舉,包含提供給該請(qǐng)求可用的屬性名稱。
HttpSession getSession()
返回與該請(qǐng)求關(guān)聯(lián)的當(dāng)前 session 會(huì)話,或者如果請(qǐng)求沒(méi)有 session 會(huì)話,則創(chuàng)建一個(gè)。
HttpSession getSession(boolean create)
返回與該請(qǐng)求關(guān)聯(lián)的當(dāng)前 HttpSession,或者如果沒(méi)有當(dāng)前會(huì)話,且創(chuàng)建是真的,則返回一個(gè)新的 session 會(huì)話。
String getRequestedSessionId()
返回由客戶端指定的 session 會(huì)話 ID。
Object getAttribute(String name)
以對(duì)象形式返回已命名屬性的值,如果沒(méi)有給定名稱的屬性存在,則返回 null。
String getCharacterEncoding()
返回請(qǐng)求主體中使用的字符編碼的名稱。
String getContentType()
返回請(qǐng)求主體的 MIME 類型,如果不知道類型則返回 null。
String getContextPath()
返回指示請(qǐng)求上下文的請(qǐng)求 URI 部分。
String getQueryString()
返回包含在路徑后的請(qǐng)求 URL 中的查詢字符串。
String getRemoteUser()
如果用戶已通過(guò)身份驗(yàn)證,則返回發(fā)出請(qǐng)求的登錄用戶,或者如果用戶未通過(guò)身份驗(yàn)證,則返回 null。
int getParameterMap()
將參數(shù)封裝成 Map 類型。
2、設(shè)置HTTP響應(yīng)頭的方法
void reset()
清除緩沖區(qū)中存在的任何數(shù)據(jù),包括狀態(tài)碼和頭。
void resetBuffer()
清除響應(yīng)中基礎(chǔ)緩沖區(qū)的內(nèi)容,不清除狀態(tài)碼和頭。
void setCharacterEncoding(String charset)
設(shè)置被發(fā)送到客戶端的響應(yīng)的字符編碼(MIME 字符集)例如,UTF-8。
void setStatus(int sc)
為該響應(yīng)設(shè)置狀態(tài)碼。
void setIntHeader(String name, int value)
設(shè)置一個(gè)帶有給定的名稱和整數(shù)值的響應(yīng)報(bào)頭。
HTTP Header 響應(yīng)實(shí)例:
//導(dǎo)入必需的 java 庫(kù) import java.io.IOException; import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/Refresh") //擴(kuò)展 HttpServlet 類 public class Refresh extends HttpServlet { // 處理 GET 方法請(qǐng)求的方法 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 設(shè)置刷新自動(dòng)加載時(shí)間為 5 秒 response.setIntHeader("Refresh", 5); // 設(shè)置響應(yīng)內(nèi)容類型 response.setContentType("text/html;charset=UTF-8"); //使用默認(rèn)時(shí)區(qū)和語(yǔ)言環(huán)境獲得一個(gè)日歷 Calendar cale = Calendar.getInstance(); //將Calendar類型轉(zhuǎn)換成Date類型 Date tasktime=cale.getTime(); //設(shè)置日期輸出的格式 SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //格式化輸出 String nowTime = df.format(tasktime); PrintWriter out = response.getWriter(); String title = "自動(dòng)刷新 Header 設(shè)置 - 菜鳥(niǎo)教程實(shí)例"; String docType = "<!DOCTYPE html>\n"; out.println(docType + "<html>\n" + "<head><title>" + title + "</title></head>\n"+ "<body bgcolor=\"#f0f0f0\">\n" + "<h1 align=\"center\">" + title + "</h1>\n" + "<p>當(dāng)前時(shí)間是:" + nowTime + "</p>\n"); } // 處理 POST 方法請(qǐng)求的方法 public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
以上測(cè)試實(shí)例是位于 TomcatTest 項(xiàng)目下,對(duì)應(yīng)的 web.xml 配置為:
<?xml version="1.0" encoding="UTF-8"?> <web-app> <servlet> <!-- 類名 --> <servlet-name>Refresh</servlet-name> <!-- 所在的包 --> <servlet-class>com.runoob.test.Refresh</servlet-class> </servlet> <servlet-mapping> <servlet-name>Refresh</servlet-name> 同上面的類名 <!-- 訪問(wèn)的網(wǎng)址 --> <url-pattern>/TomcatTest/Refresh</url-pattern> </servlet-mapping> </web-app>
現(xiàn)在,調(diào)用上面的 Servlet,每隔 5 秒會(huì)顯示當(dāng)前系統(tǒng)時(shí)間。
3、HTTP狀態(tài)碼
404:服務(wù)器無(wú)法找到所請(qǐng)求的頁(yè)面。
403:禁止訪問(wèn)所請(qǐng)求的頁(yè)面。
401:所請(qǐng)求的頁(yè)面需要用戶名和密碼。
405:在請(qǐng)求中指定的方法是不允許的。
307:所請(qǐng)求的頁(yè)面已經(jīng)臨時(shí)轉(zhuǎn)移到一個(gè)新的 URL。
500:未完成的請(qǐng)求。服務(wù)器遇到了一個(gè)意外的情況。
下面的方法可用于在 Servlet 程序中設(shè)置 HTTP 狀態(tài)碼。這些方法通過(guò)HttpServletResponse對(duì)象可用。
public void setStatus ( int statusCode )
該方法設(shè)置一個(gè)任意的狀態(tài)碼。setStatus 方法接受一個(gè) int(狀態(tài)碼)作為參數(shù)。如果您的反應(yīng)包含了一個(gè)特殊的狀態(tài)碼和文檔,請(qǐng)確保在使用PrintWriter實(shí)際返回任何內(nèi)容之前調(diào)用 setStatus。
public void sendError(int code, String message)
該方法發(fā)送一個(gè)狀態(tài)碼(通常為 404),連同一個(gè)在 HTML 文檔內(nèi)部自動(dòng)格式化并發(fā)送到客戶端的短消息。
// 設(shè)置錯(cuò)誤代碼和原因 response.sendError(407, "Need authentication!!!" );
4、Servlet接口&訪問(wèn)方式介紹
Servlet是實(shí)現(xiàn)了javax.servlet.Servlet接口的類,這個(gè)接口規(guī)定了特定的方法來(lái)處理特定的請(qǐng)求,我們只需要實(shí)現(xiàn)Servlet相關(guān)的方法,Servlet規(guī)范是建立在HTTP協(xié)議上的,http1.1規(guī)范支持OPTIONS/GET/POST/HEAD/PUT/DELETE/TRACE等7種訪問(wèn)方式。下面我們重點(diǎn)介紹Get/Post。
1、GET:表示查詢信息,URL中附帶少量參數(shù)信息,URL總長(zhǎng)度不超過(guò)255個(gè)字符,參數(shù)還會(huì)在瀏覽器的地址欄中顯示
2、POST:表示提交信息,一般用于提交大數(shù)據(jù)信息或者文件,提交的內(nèi)容不收長(zhǎng)度限制,也不會(huì)在地址欄中顯示。
3、HEAD:表示查詢文檔頭信息,服務(wù)器返回的文件類型,長(zhǎng)度,最后修改時(shí)間等等,該方式較少使用。
4、OPTIONS /PUT /DELETE /TRACE:是被聲明了但還沒(méi)有被使用web訪問(wèn)方式,幾乎不用。
到此這篇關(guān)于Servlet開(kāi)發(fā)JavaWeb工程示例詳解的文章就介紹到這了,更多相關(guān)Servlet開(kāi)發(fā)JavaWeb內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 解決Javaweb 提交表單到servlet時(shí)出現(xiàn)空白頁(yè)面,但網(wǎng)站不報(bào)錯(cuò)問(wèn)題
- JavaWeb Servlet實(shí)現(xiàn)網(wǎng)頁(yè)登錄功能
- JavaWeb實(shí)戰(zhàn)之用Servlet+JDBC實(shí)現(xiàn)用戶登錄與注冊(cè)
- JavaWeb項(xiàng)目Servlet無(wú)法訪問(wèn)問(wèn)題解決
- IDEA新建javaWeb以及Servlet簡(jiǎn)單實(shí)現(xiàn)小結(jié)
- JavaWeb Servlet中url-pattern的使用
- javaweb中ajax請(qǐng)求后臺(tái)servlet(實(shí)例)
- Javaweb中使用Servlet編寫簡(jiǎn)單的接口案例詳解
相關(guān)文章
SpringBoot中的@RequestMapping注解的用法示例
@RequestMapping注解是SpringBoot中最常用的注解之一,它可以幫助開(kāi)發(fā)者定義和處理HTTP請(qǐng)求,本篇文章我們將詳細(xì)為大家介紹如何使用SpringBoot中的@RequestMapping注解,感興趣的同學(xué)跟著小編一起來(lái)學(xué)習(xí)吧2023-06-06spring security獲取用戶信息的實(shí)現(xiàn)代碼
這篇文章主要介紹了spring security獲取用戶信息的實(shí)現(xiàn)代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12JAVA日常開(kāi)發(fā)中一些常見(jiàn)問(wèn)題歸納講解
這篇文章主要給大家介紹了JAVA日常開(kāi)發(fā)中一些常見(jiàn)問(wèn)題的相關(guān)資料,包括語(yǔ)法錯(cuò)誤、數(shù)據(jù)類型問(wèn)題、面向?qū)ο缶幊虇?wèn)題、集合類問(wèn)題以及文件操作問(wèn)題,通過(guò)詳細(xì)的分析和示例,幫助程序員提高代碼的健壯性和可維護(hù)性,需要的朋友可以參考下2024-12-12java集合中HashSet LinkedHashSet TreeSet三者異同面試精講
這篇文章主要為大家介紹了java集合中HashSet LinkedHashSet TreeSet三者異同面試精講,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10Spring?MVC請(qǐng)求轉(zhuǎn)發(fā)與請(qǐng)求重定向的示例詳解
轉(zhuǎn)發(fā)指服務(wù)器接收請(qǐng)求后,從一個(gè)資源跳轉(zhuǎn)到另一個(gè)資源中,請(qǐng)求轉(zhuǎn)發(fā)是一次請(qǐng)求,不會(huì)改變?yōu)g覽器的請(qǐng)求地址,這篇文章主要介紹了Spring?MVC請(qǐng)求轉(zhuǎn)發(fā)與請(qǐng)求重定向的相關(guān)知識(shí),需要的朋友可以參考下2023-09-09JAVA Swing實(shí)現(xiàn)窗口添加課程信息過(guò)程解析
這篇文章主要介紹了JAVA Swing實(shí)現(xiàn)窗口添加課程信息過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10詳解分別用Kotlin和java寫RecyclerView的示例
本篇文章主要介紹了詳解分別用Kotlin和java寫RecyclerView的示例,詳解分別用Kotlin和java寫RecyclerView的示例2017-12-12java中javamail收發(fā)郵件實(shí)現(xiàn)方法
這篇文章主要為大家詳細(xì)介紹了java中javamail收發(fā)郵件實(shí)現(xiàn)方法,實(shí)例分析了javamail的使用方法與相關(guān)注意事項(xiàng),非常具有實(shí)用價(jià)值,感興趣的小伙伴們可以參考一下2016-02-02