在這一節(jié),我們將通過(guò)三個(gè)例子來(lái)幫助讀者更好地理解Servlet的開(kāi)發(fā)與部署過(guò)程,以及Servlet中主要接口與類的使用。在講解實(shí)例時(shí),我們將通過(guò)一步一步地操作來(lái)完成整個(gè)實(shí)例。
在本例中,我們將編寫(xiě)一個(gè)帶表單的HTML頁(yè)面,表單中提供了一個(gè)文本輸入控件,讓用戶輸入他/她的姓名,然后提交給Servlet進(jìn)行處理。在Servlet中,我們從提交的表單信息中取出用戶姓名,然后加上歡迎信息輸出到客戶端。歡迎信息作為Servlet的初始化參數(shù)在web.xml文件中配置。
實(shí)例的開(kāi)發(fā)主要有下列步驟。
用記事本或者UltraEdit等文本編輯工具(讀者也可以使用專門(mén)的網(wǎng)頁(yè)編輯軟件)編寫(xiě)welcome. html,將編寫(xiě)好的welcome.html文件放到%CATALINA_HOME%\webapps\ch02目錄下。完整的代碼如例2-3所示。
例2-3 welcome.html
<html>
<head>
<title>歡迎您!</title>
</head>
<body>
<form action="welcome" method="get">
請(qǐng)輸入用戶名:<input type="text" name="username"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
在HTML代碼中,我們先假定對(duì)此表單進(jìn)行處理的Servlet是welcome,表單采用的提交方法是get。
為了簡(jiǎn)化Servlet的編寫(xiě),Servlet API給我們提供了支持HTTP協(xié)議的javax.servlet.http.HttpServlet類,我們只需要從HttpServlet類派生一個(gè)子類,在子類中完成相應(yīng)的功能就可以了。
編寫(xiě)WelcomeServlet類,從HttpServlet類繼承,重寫(xiě)doGet()方法。將編寫(xiě)好的WelcomeServlet.java源文件放到%CATALINA_HOME%\ webapps\ch02\src目錄下。完整的源代碼如例2-4所示。
例2-4 WelcomeServlet.java
1. package org.sunxin.ch02.servlet;
2.
3. import java.io.IOException;
4. import java.io.PrintWriter;
5.
6. import javax.servlet.ServletException;
7. import javax.servlet.http.HttpServlet;
8. import javax.servlet.http.HttpServletRequest;
9. import javax.servlet.http.HttpServletResponse;
10.
11. public class WelcomeServlet extends HttpServlet
12. {
13. private String greeting;
14.
15. public void init()
16. {
17. greeting = getInitParameter("greeting");
18. //greeting = getServletConfig().getInitParameter("greeting");
19. }
20.
21. public void doGet(HttpServletRequest req, HttpServletResponse resp)
22. throws ServletException,IOException
23. {
24. req.setCharacterEncoding("gb2312");
25. String username=req.getParameter("username");
26. String welcomeInfo=greeting + ", " + user;
27.
28. resp.setContentType("text/html");
29.
30. PrintWriter out=resp.getWriter();
31.
32. out.println("<html><head><title>");
33. out.println("Welcome Page");
34. out.println("</title></head>");
35. out.println("<body>");
36. out.println(welcomeInfo);
37. out.println("</body></html>");
38. out.close();
39. }
40. }
例2-4代碼的第17行,我們調(diào)用getInitParameter()方法得到初始化參數(shù)greeting的值,這個(gè)調(diào)用和第18行注釋的代碼是等價(jià)的。從HttpServlet繼承的getInitParameter()方法實(shí)際上也是調(diào)用ServletConfig對(duì)象的getInitParameter()方法來(lái)得到初始化參數(shù)的。
由于用戶可能會(huì)輸入中文用戶名,因此我們?cè)诖a的第24行設(shè)置請(qǐng)求正文使用的字符編碼是gb2312。
前面我們介紹過(guò),HttpServletRequest對(duì)象封裝了客戶端的請(qǐng)求信息,要獲取請(qǐng)求中某個(gè)參數(shù)的值,可以調(diào)用HttpServletRequest對(duì)象的getParameter()方法,傳遞參數(shù)的名字。在代碼的第25行,我們調(diào)用req.getParameter("username")獲取到用戶輸入的用戶名。注意getParameter()方法的參數(shù)“username”和表單中用于輸入用戶姓名的文本輸入控件的名字“username”必須是一樣的。
第26行,我們用取出的用戶名構(gòu)造一個(gè)歡迎字符串。第28行,設(shè)置響應(yīng)內(nèi)容的MIME類型為text/html。第32~38行,都是在輸出HTML代碼,第36行,將歡迎信息放到<body>元素的開(kāi)始標(biāo)簽和結(jié)束標(biāo)簽之間輸出。第35行,關(guān)閉out對(duì)象。
打開(kāi)命令提示符,進(jìn)入%CATALINA_HOME%\webapps\ch02\src目錄,然后執(zhí)行:
javac -d ..\WEB-INF\classes WelcomeServlet.java
在WEB-INF\classes\org\sunxin\ch02\servlet目錄中生成類文件WelcomeServlet.class。
用記事本或UltraEdit打開(kāi)%CATALINA_HOME%\webapps\ch02\WEB-INF目錄下的web.xml文件,添加對(duì)本例中的Servlet的配置,完整的內(nèi)容如例2-5所示。
例2-5 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>HelloWorldServlet</servlet-name>
<servlet-class>
org.sunxin.ch02.servlet.HelloWorldServlet </servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloWorldServlet</servlet-name>
<url-pattern>/helloworld</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>WelcomeServlet</servlet-name>
<servlet-class>
org.sunxin.ch02.servlet.WelcomeServlet </servlet-class>
<init-param>
<param-name>greeting</param-name>
<param-value>Welcome you</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>WelcomeServlet</servlet-name>
<url-pattern>/welcome</url-pattern>
</servlet-mapping>
</web-app>
新增加的內(nèi)容以粗體顯示。我們?cè)?lt;servlet>元素內(nèi)部使用<init-param>子元素來(lái)為WelcomeServlet配置的初始化參數(shù),在例2-4的init()方法中,有這樣一句代碼:
greeting = getInitParameter("greeting");
這句代碼的作用就是獲取此處配置的greeting初始化參數(shù)的值。
注意,在Servlet 2.2和Servlet 2.3規(guī)范中,web.xml文件使用DTD來(lái)定義文檔的結(jié)構(gòu)。在Servlet 2.2規(guī)范中,web.xml的文檔類型聲明如下:
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
"http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
在Servlet 2.3規(guī)范中,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">
因?yàn)槭怯肈TD來(lái)定義web.xml文檔的結(jié)構(gòu),所以元素出現(xiàn)的次序是有嚴(yán)格限制的,在這兩個(gè)版本中,<servlet>元素必須出現(xiàn)在<servlet-mapping>元素之前。而從Servlet 2.4規(guī)范開(kāi)始,web.xml文件改為用XML Schema來(lái)定義文檔的結(jié)構(gòu),其中一個(gè)好處就是元素出現(xiàn)的次序不再有嚴(yán)格的限定。如果我們開(kāi)發(fā)的Web應(yīng)用程序需要運(yùn)行在支持低版本的Servlet規(guī)范的Web服務(wù)器中運(yùn)行,那么需要將web.xml文件修改為如例2-6所示。
例2-6 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>HelloWorldServlet</servlet-name>
<servlet-class>
org.sunxin.ch02.servlet.HelloWorldServlet </servlet-class>
</servlet>
<servlet>
<servlet-name>WelcomeServlet</servlet-name>
<servlet-class>
org.sunxin.ch02.servlet.WelcomeServlet </servlet-class>
<init-param>
<param-name>greeting</param-name>
<param-value>Welcome you</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>HelloWorldServlet</servlet-name>
<url-pattern>/helloworld</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>WelcomeServlet</servlet-name>
<url-pattern>/welcome</url-pattern>
</servlet-mapping>
</web-app>
注意文件中元素出現(xiàn)的順序。
啟動(dòng)Tomcat服務(wù)器,打開(kāi)IE瀏覽器,在地址欄中輸入:
http://localhost:8080/ch02/welcome.html
出現(xiàn)頁(yè)面后,在文本輸入控件中輸入用戶姓名,如圖2-8所示。
單擊“提交”按鈕,你將看到如圖2-9所示的頁(yè)面。
圖2-8 welcome.html頁(yè)面 圖2-9 以GET方式提交后WelcomeServlet輸出的響應(yīng)信息
注意IE瀏覽器的地址欄部分,因?yàn)閣elcome.html頁(yè)面采用的表單提交方法是get,所以提交的數(shù)據(jù)被附加到請(qǐng)求URL的末端,作為查詢字符串發(fā)送到服務(wù)器端。采用get方法提交表單,和我們直接在瀏覽器的地址欄中輸入附加了查詢字符串的URL的效果是一樣的。在本例中,我們也可以通過(guò)直接輸入如下形式的URL來(lái)提交數(shù)據(jù):
http://localhost:8080/ch02/welcome?username=zhangsan
將例2-3的welcome.html中的表單提交方法改為post,如下:
<form action="welcome" method="post">
保存后,打開(kāi)瀏覽器,在地址欄中輸入http://localhost:8080/ch02/welcome.html,輸入用戶名后,單擊“提交”按鈕,你將看到如圖2-10所示的頁(yè)面。
圖2-10 WelcomeServlet無(wú)法處理post請(qǐng)求,返回HTTP 405錯(cuò)誤信息
這是因?yàn)槲覀冊(cè)赪elcomeServlet類中沒(méi)有重寫(xiě)doPost()方法,而HttpServlet類的doPost()方法的默認(rèn)實(shí)現(xiàn)是返回狀態(tài)代碼為405的HTTP錯(cuò)誤,表示對(duì)于指定資源的請(qǐng)求方法不被允許。如果要對(duì)post請(qǐng)求做出響應(yīng),需要在WelcomeServlet這個(gè)類中覆蓋基類的doPost()方法。我們修改例2-4的WelcomeServlet.java,如例2-7所示。
例2-7 修改后的WelcomeServlet.java
package org.sunxin.ch02.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class WelcomeServlet extends HttpServlet
{
private String greeting;
public void init()
{
greeting = getInitParameter("greeting");
//greeting = getServletConfig().getInitParameter("greeting");
}
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException,IOException
{
req.setCharacterEncoding("gb2312");
String username=req.getParameter("username");
String welcomeInfo=greeting + ", " + username;
resp.setContentType("text/html");
PrintWriter out=resp.getWriter();
out.println("<html><head><title>");
out.println("Welcome Page");
out.println("</title></head>");
out.println("<body>");
out.println(welcomeInfo);
out.println("</body></html>");
out.close();
}
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException,IOException
{
doGet(req,resp);
}
}
在doPost()方法中,直接調(diào)用了doGet()方法對(duì)post請(qǐng)求進(jìn)行處理,這樣,不管是get請(qǐng)求還是post請(qǐng)求,處理結(jié)果都是一樣的。
按照Step3所示的方式編譯WelcomeServlet.java。重啟Tomcat服務(wù)器,在瀏覽器的地址欄中輸入http://localhost:8080/ch02/welcome. html,輸入用戶名后,單擊“提交”按鈕,你將看到如圖2-11所示的頁(yè)面。
圖2-11 post方式提交后WelcomeServlet輸出的響應(yīng)信息
注意IE瀏覽器的地址欄部分,因?yàn)楝F(xiàn)在welcome.html頁(yè)面采用的表單提交方法是post,提交的數(shù)據(jù)作為請(qǐng)求正文的內(nèi)容發(fā)送到服務(wù)器端,所以在URL中就看不到附加的請(qǐng)求數(shù)據(jù)了。通常在提交表單時(shí),如果數(shù)據(jù)量較小,而又沒(méi)有安全性的考慮(例如,提交的數(shù)據(jù)中沒(méi)有密碼等敏感信息),可以采用get方法提交表單。如果數(shù)據(jù)量較大,或者有安全方面的考慮,則應(yīng)該采用post方法提交表單。
在本例中,我們將編寫(xiě)一個(gè)Servlet,用于獲取請(qǐng)求中的消息報(bào)頭,并將這些報(bào)頭的名稱和值輸出到客戶端。此外,我們還利用ServletRequest接口中定義的方法獲取客戶端和服務(wù)器端的IP地址及端口號(hào),并將這些信息輸出到客戶端。在這個(gè)Servlet中,我們還設(shè)置了響應(yīng)的實(shí)體報(bào)頭。實(shí)例的開(kāi)發(fā)主要有下列步驟。
將編寫(xiě)好的OutputInfoServlet.java源文件放到%CATALINA_HOME%\webapps\ ch02\src目錄下。完整的源代碼如例2-8所示。
例2-8 OutputInfoServlet.java
1. package org.sunxin.ch02.servlet;
2.
3. import java.io.IOException;
4. import java.io.PrintWriter;
5. import java.util.Enumeration;
6.
7. import javax.servlet.ServletException;
8. import javax.servlet.http.HttpServlet;
9. import javax.servlet.http.HttpServletRequest;
10. import javax.servlet.http.HttpServletResponse;
11.
12. public class OutputInfoServlet extends HttpServlet
13. {
14. public void doGet(HttpServletRequest req, HttpServletResponse resp)
15. throws ServletException,IOException
16. {
17.
18. resp.setContentType("text/html;charset=gb2312");
19.
20. PrintWriter out=resp.getWriter();
21.
22. Enumeration headNames=req.getHeaderNames();
23.
24. out.println("<html><head>");
25. out.println("<title>Info Page</title>");
26. out.println("</head>");
27. out.println("<body><center>");
28.
29. out.println("<table border=1 align=center>");
30. out.println("<caption>Servlet接收到的HTTP消息報(bào)頭的信息</caption>");
31. out.println("<tr bgcolor=#999999>");
32. out.println("<th>消息報(bào)頭的名字</th>");
33. out.println("<th>消息報(bào)頭的值</th>");
34. out.println("</tr>");
35.
36. while(headNames.hasMoreElements())
37. {
38. String name=(String)headNames.nextElement();
39. String value=req.getHeader(name);
40. out.println("<tr>");
41. out.println("<td>"+name+"</td>");
42. out.println("<td>"+value+"</td>");
43. out.println("</tr>");
44. }
45.
46. out.println("</table><p>");
47.
48. out.println("<table border=1 align=center>");
49. out.println("<caption>其他訪問(wèn)信息</caption>");
50.
51. out.println("<tr>");
52. out.println("<td>客戶端的IP地址</td>");
53. out.println("<td>"+req.getRemoteAddr()+"</td>");
54. out.println("</tr>");
55.
56. out.println("<tr>");
57. out.println("<td>客戶端的端口號(hào)</td>");
58. out.println("<td>"+req.getRemotePort()+"</td>");
59. out.println("</tr>");
60.
61. out.println("<tr>");
62. out.println("<td>服務(wù)器端的IP地址</td>");
63. out.println("<td>"+req.getLocalAddr()+"</td>");
64. out.println("</tr>");
65.
66. out.println("<tr>");
67. out.println("<td>服務(wù)器端的端口號(hào)</td>");
68. out.println("<td>"+req.getLocalPort()+"</td>");
69. out.println("</tr>");
70.
71. out.println("</table>");
72.
73. out.println("</center></body></html>");
74. out.close();
75. }
76. }
在程序代碼的第18行,設(shè)置響應(yīng)內(nèi)容的MIME類型為text/html,因?yàn)轫憫?yīng)內(nèi)容中包含了中文,所以設(shè)置字符編碼方式為gb2312。要注意的是,這一句代碼必須放在第20行代碼的前面,否則將無(wú)法設(shè)置響應(yīng)的字符編碼,out對(duì)象將使用默認(rèn)的字符編碼ISO-8859-1。此外,還要注意的是在text/html和“;”之間不能有空格,即不能寫(xiě)成text/html ;charset=gb2312,否則瀏覽器將不能正確識(shí)別響應(yīng)的內(nèi)容類型。第22行,通過(guò)請(qǐng)求對(duì)象的getHeaderNames()方法調(diào)用,得到請(qǐng)求中包含的所有消息報(bào)頭的名字的枚舉集合。第29~34行,輸出一個(gè)表格,設(shè)置表格的標(biāo)題和表頭。第36~44行,循環(huán)取出枚舉集合中消息報(bào)頭的名字,然后利用報(bào)頭的名字調(diào)用請(qǐng)求對(duì)象的getHeader()方法得到對(duì)應(yīng)的值,將報(bào)頭的名字和值分別放到表格的單元格中。第48~71行,輸出另一個(gè)表格,表格的內(nèi)容是客戶端和服務(wù)器端的IP地址和端口號(hào)。第53行,調(diào)用請(qǐng)求對(duì)象的getRemoteAddr()方法得到發(fā)送請(qǐng)求的客戶端的IP地址。第58行,調(diào)用請(qǐng)求對(duì)象的getRemotePort()方法得到發(fā)送請(qǐng)求的客戶端的端口號(hào),這個(gè)方法是在Servlet 2.4規(guī)范中新增的方法。第63行,調(diào)用getLocalAddr()方法得到接收到請(qǐng)求的服務(wù)器端的IP地址,這個(gè)方法是在Servlet 2.4規(guī)范中新增的方法。第68行,調(diào)用請(qǐng)求對(duì)象的getLocalPort()方法得到接收到請(qǐng)求的服務(wù)器端的端口號(hào),這個(gè)方法是在Servlet 2.4規(guī)范中新增的方法。
打開(kāi)命令提示符,進(jìn)入%CATALINA_HOME%\webapps\ch02\src目錄,然后執(zhí)行:
javac -d ..\WEB-INF\classes OutputInfoServlet.java
在WEB-INF\classes\org\sunxin\ch02\servlet目錄中生成類文件OutputInfoServlet.class。
編輯WEB-INF目錄下的web.xml文件,添加對(duì)本例中的Servlet的配置,完整的內(nèi)容如例2-9所示。
例2-9 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>HelloWorldServlet</servlet-name>
<servlet-class>
org.sunxin.ch02.servlet.HelloWorldServlet </servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloWorldServlet</servlet-name>
<url-pattern>/helloworld</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>WelcomeServlet</servlet-name>
<servlet-class>
org.sunxin.ch02.servlet.WelcomeServlet </servlet-class>
<init-param>
<param-name>greeting</param-name>
<param-value>Welcome you</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>WelcomeServlet</servlet-name>
<url-pattern>/welcome</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>OutputInfoServlet</servlet-name>
<servlet-class>
org.sunxin.ch02.servlet.OutputInfoServlet </servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>OutputInfoServlet</servlet-name>
<url-pattern>/info</url-pattern>
</servlet-mapping>
</web-app>
新增加的內(nèi)容以粗體顯示。
啟動(dòng)Tomcat服務(wù)器,打開(kāi)IE瀏覽器,在地址欄中輸入http://localhost:8080/ch02/info,你將看到如圖2-12所示的頁(yè)面。
圖2-12 使用IE訪問(wèn)OutputInfoServlet
在本例(例2-8)的代碼中,第18行我們調(diào)用:
resp.setContentType("text/html;charset=gb2312");
將會(huì)設(shè)置HTTP響應(yīng)的Content-Type實(shí)體報(bào)頭。這個(gè)實(shí)體報(bào)頭的信息是給客戶端軟件(通常是瀏覽器)看的,在頁(yè)面中并不會(huì)體現(xiàn)出來(lái)。為了查看這句代碼調(diào)用是否正確設(shè)置了Content-Type實(shí)體報(bào)頭,我們可以利用telnet工具去訪問(wèn)本例中的OutputInfoServlet。
首先確保Tomcat服務(wù)器正常啟動(dòng)了。打開(kāi)命令提示符,輸入telnet localhost 8080,回車后,輸入:
GET /ch02/info HTTP/1.1
Host: localhost
注意書(shū)寫(xiě)與空格。然后連續(xù)兩個(gè)回車,你將看到如圖2-13所示的畫(huà)面。
圖2-13 使用telnet工具查看Content-Type實(shí)體報(bào)頭的設(shè)置信息
注意圖2-13中圓角矩形框中的內(nèi)容,說(shuō)明代碼中對(duì)setContentType()方法的調(diào)用確實(shí)設(shè)置了Content-Type實(shí)體報(bào)頭。
在本例中,我們將編寫(xiě)一個(gè)登錄頁(yè)面,用戶輸入用戶名和密碼后,將表單提交給LoginServlet進(jìn)行處理。在LoginServlet中,判斷用戶名和密碼是否正確,如果正確,利用重定向向用戶返回成功登錄頁(yè)面;如果失敗,則向用戶返回一個(gè)HTTP錯(cuò)誤消息。實(shí)例的開(kāi)發(fā)主要有下列步驟。
login.html用于向用戶顯示登錄表單。在%CATALINA_HOME%\webapps\ch02目錄下新建login.html,內(nèi)容如例2-10所示。
例2-10 login.html
<html>
<head>
<title>登錄頁(yè)面</title>
</head>
<body>
<form action="login" method="post">
<table>
<tr>
<td>請(qǐng)輸入用戶名:</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>請(qǐng)輸入密碼:</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td><input type="reset" value="重填"></td>
<td><input type="submit" value="登錄"></td>
</tr>
</table>
</form>
</body>
</html>
在HTML代碼中,我們先假定對(duì)此表單進(jìn)行處理的Servlet是login,因?yàn)樘峤坏臄?shù)據(jù)中包含了用戶的密碼,所以表單的提交方法我們采用post。
success.html用于向用戶顯示歡迎信息。在%CATALINA_HOME%\webapps\ch02目錄下新建success.html,內(nèi)容如例2-11所示。
例2-11 success.html
<html>
<head>
<title>登錄成功</title>
</head>
<body>
登錄成功,歡迎進(jìn)入孫鑫的個(gè)人網(wǎng)站(www.sunxin.org)!
</body>
</html>
在%CATALINA_HOME%\webapps\ch02\src目錄下新建LoginServlet.java,代碼如例2-12所示。
例2-12 LoginServlet.java
1. package org.sunxin.ch02.servlet;
2.
3. import java.io.IOException;
4.
5. import javax.servlet.ServletException;
6. import javax.servlet.http.HttpServlet;
7. import javax.servlet.http.HttpServletRequest;
8. import javax.servlet.http.HttpServletResponse;
9.
10. public class LoginServlet extends HttpServlet
11. {
12. public void doGet(HttpServletRequest req, HttpServletResponse resp)
13. throws ServletException,IOException
14. {
15.
16. resp.setContentType("text/html;charset=gb2312");
17.
18. String name=req.getParameter("username");
19. String pwd=req.getParameter("password");
20.
21. if(name!=null && pwd!=null && name.equals("zhangsan") &&
22. pwd.equals("1234"))
23. {
24. resp.sendRedirect("success.html");
25. }
26. else
27. {
28. resp.sendError(HttpServletResponse.SC_SERVICE_ UNAVAILABLE,"服務(wù)器忙,請(qǐng)稍后再登錄!");
29. }
30.
31. }
32.
33. public void doPost(HttpServletRequest req,HttpServletResponse resp)
34. throws ServletException,IOException
35. {
36. doGet(req,resp);
37. }
38. }
在代碼的第18~19行,調(diào)用請(qǐng)求對(duì)象的getParameter()方法得到用戶名和密碼。第21行首先判斷name和pwd是否為空,這是為了避免出現(xiàn)空指針異常,如果用戶直接在瀏覽器的地址欄中輸入U(xiǎn)RL訪問(wèn)這個(gè)Servlet而沒(méi)有附加username和password查詢字符串,name和pwd將為null;接下來(lái)判斷名字是否是zhangsan,密碼是否是1234。第24行,判斷為真,調(diào)用響應(yīng)對(duì)象的sendRedirect()方法將用戶請(qǐng)求重定向到success.html頁(yè)面。第28行,判斷為假,調(diào)用響應(yīng)對(duì)象的sendError()方法發(fā)送HTTP錯(cuò)誤代碼503(在HttpServletResponse接口中定義為靜態(tài)常量SC_SERVICE_UNAVAILABLE),告訴用戶“服務(wù)器忙,請(qǐng)稍后再登錄”。
打開(kāi)命令提示符,進(jìn)入%CATALINA_HOME%\webapps\ch02\src目錄,然后執(zhí)行:
javac -d ..\WEB-INF\classes LoginServlet.java
在WEB-INF\classes\org\sunxin\ch02\servlet目錄中生成類文件LoginServlet.class。
編輯WEB-INF目錄下的web.xml文件,添加對(duì)本例中的Servlet的配置,完整的內(nèi)容如例2-13所示。
例2-13 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>HelloWorldServlet</servlet-name>
<servlet-class>
org.sunxin.ch02.servlet.HelloWorldServlet </servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloWorldServlet</servlet-name>
<url-pattern>/helloworld</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>WelcomeServlet</servlet-name>
<servlet-class>
org.sunxin.ch02.servlet.WelcomeServlet </servlet-class>
<init-param>
<param-name>greeting</param-name>
<param-value>Welcome you</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>WelcomeServlet</servlet-name>
<url-pattern>/welcome</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>OutputInfoServlet</servlet-name>
<servlet-class>
org.sunxin.ch02.servlet.OutputInfoServlet </servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>OutputInfoServlet</servlet-name>
<url-pattern>/info</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>
org.sunxin.ch02.servlet.LoginServlet </servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
</web-app>
新增加的內(nèi)容以粗體顯示。
啟動(dòng)Tomcat服務(wù)器,打開(kāi)IE瀏覽器,在地址欄中輸入http://localhost:8080/ ch02/login.html,出現(xiàn)頁(yè)面后,在文本輸入控件中輸入zhangsan,在口令輸入控件中輸入1234,單擊“提交”按鈕,將看到如圖2-14所示的頁(yè)面。
注意圖2-14瀏覽器地址欄中的URL。
圖2-14 登錄成功頁(yè)面
回到http://localhost:8080/ch02/login.html頁(yè)面,重新輸入其他的用戶名或密碼,單擊“提交”按鈕,將看到如圖2-15所示的頁(yè)面。
圖2-15 用戶名或密碼錯(cuò)誤,LoginServlet輸出HTTP 503錯(cuò)誤消息
注意圖2-15中圓角矩形框中的內(nèi)容,向用戶顯示的這些錯(cuò)誤消息是我們?cè)陧憫?yīng)對(duì)象的sendError()方法中指定的。
請(qǐng)讀者注意,在本例中,用戶輸入了錯(cuò)誤的用戶名或密碼,LoginServlet向用戶發(fā)送HTTP 503錯(cuò)誤,這只是為了演示sendError()方法的使用,在實(shí)際開(kāi)發(fā)過(guò)程中,應(yīng)該給用戶一個(gè)更友好的提示“用戶名或密碼錯(cuò)誤,請(qǐng)重新輸入”,或者“拒絕此用戶登錄”。
聯(lián)系客服