一、What.
Servlet 為何物?兩種配置方式是什麼?
複製程式碼
Servlet狹義指的就是一個叫做“Servlet”的介面,廣義指實現了這個介面的Java程式,執行在服務端,用來處理任何型別的請求、擴充套件基於HTTP協議的Web伺服器。 兩種配置方式為XML標籤式和註解式。
二、Why.
編寫Servlet為什麼還要配置?
複製程式碼
當我們要開發編寫一個針對請求的處理類,只實現Servlet介面是不行的。就像你造的酒很香,但是客人不知道去哪買一樣。這是你要貼出標語、路標作為指示說明。類似的,你編寫的“香噴噴”的Servlet實現類,也要配置說明下(“打個廣告”),讓外來的請求能夠找到對應的處理類。
三、How.
兩種方式如何配置?
複製程式碼
知識點其實不多,但為了讓我們學習知識更有興趣,我們每練習一個Demo應該給它賦予一個場景需求。 本次Demo練習,我們用兩種配置方式做一個Servlet相關的檢視兌獎號碼的例子。
(一)XML標籤式配置.
在Servlet 3.0版本之前,Servlet的配置說明只能通過在WEB-INF 目錄下的web.xml檔案中新增標籤的形式。
<web-app>
<servlet>
<!--servlet的暱稱、代號,共下文中的引用-->
<servlet-name>CheckNumber</servlet-name>
<!--servlet對應的類檔案,包名+類名-->
<servlet-class>com.breaker.servlet.CheckServlet</servlet-class>
<!--servlet內部的初始化引數,非必需配置-->
<init-param>
<param-name>user</param-name>
<param-value>Breaker93</param-value>
</init-param>
<init-param>
<param-name>my_jianshu_url</param-name>
<param-value>http://www.jianshu.com/u/187408ee66d4</param-value>
</init-param>
<!--通知Servlet容器(“tomcat”)在啟動的時候初始化建立該Servlet的例項,非必需配置 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<!--為代號為“CheckNumber”的Servlet設定瀏覽器訪問地址(要與上文中的Serlet
的代號名稱一致,否則會找不到的),
例如http://192.168.0.100:8080/DemoProject/checkNumber -->
<servlet-name>CheckNumber</servlet-name>
<!--此處的名稱與servlet-name的值無關,隨便設定的,
只為了瀏覽器中請求方便 -->
<url-pattern>/checkNumber</url-pattern>
</servlet-mapping>
</web-app>
複製程式碼
此種配置中的Servlet實現類是這樣編寫的:
//HttpServlet繼承了GenericServlet類,GenericServlet繼承了Servlet介面,
//他們都是Servlet API提供,非個人編寫的;所以CheckServlet是間接實現的Servlet介面。
public class CheckServlet extends HttpServlet{
//處理get請求,在此方法內編寫處理邏輯。
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
System.out.println("我的簡書連結:"+getServletConfig().getInitParameter("my_jianshu_url"));
String[] number=req.getParameterValues("number");
for(int i=0;i<7;i++){
System.out.print(number[i]);
}
System.out.println("---------");
String[] awardNum=new String[7];
Random random=new Random();
for(int i=0;i<7;i++){
awardNum[i] = random.nextInt(10)+"";
System.out.print(awardNum[i]);
}
System.out.println("------");
int count = 0,max = 0,position = 0;
for(int i= 0;i<awardNum.length;i++){
if(awardNum[i].equals(number[i])){
count++;
if (count>max) {
position=i;
max=count;
}
}else{
count=0;
}
}
req.setAttribute("number", number);
req.setAttribute("awardNum", awardNum);
req.setAttribute("bool", "");
req.setAttribute("begin",8 );
req.setAttribute("end", 8);
String[] result = {"六等獎","五等獎","四等獎","三等獎","二等獎","一等獎"};
if(max >1){
req.setAttribute("bool", true);
req.setAttribute("result","恭喜你中了" +result[max-2]);
req.setAttribute("begin", position-max+1);
req.setAttribute("end", position);
}
RequestDispatcher dispatcher = req.getRequestDispatcher("/showResult.jsp");
dispatcher.forward(req, resp);
}
//處理post請求,在此方法內編寫處理邏輯。
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
super.doPost(req, resp);
System.out.println("doPost() executed");
}
}
複製程式碼
Jsp頁面中是這樣請求的Servlet:
//checkNumber 與<url-pattern>/checkNumber</url-pattern>對應一致才能請求到;
//此種請求等同於action="http://127.0.0.1:8080/DemoProject/checkNumber"
<form action="checkNumber">
...
...
</form>
複製程式碼
(二)註解式.
在Servlet 3.0版本之後,WEB-INF路徑下的web.xml檔案不再是必需的,但通常還是建議保留。提供的註解(annotation),使得不再需要在web.xml檔案中進行Servlet的部署描述,簡化開發流程。
開發Servlet 3.0的程式需要一定的環境支援。Servlet3是Java EE6規範的一部分,Tomcat需要Tomcat7才支援Java EE6,Tomcat7需要使用JDK6。
直接在Servlet實現類裡配置:
//HttpServlet繼承了GenericServlet類,GenericServlet繼承了Servlet介面,
//他們都是Servlet API提供,非個人編寫的;所以CheckServlet是間接實現的Servlet介面。
/*@WebServlet將一個繼承於javax.servlet.http.HttpServlet的類定義為Servlet元件。
*  @WebServlet有很多的屬性:
*  asyncSupported: 宣告Servlet是否支援非同步操作模式。
*  description:   Servlet的描述。
*  displayName: Servlet的顯示名稱。
*  initParams: Servlet的init引數。
*  name:     Servlet的名稱。
*  urlPatterns:   Servlet的訪問URL。
*  value:    Servlet的訪問URL。
*
*  Servlet的訪問URL是Servlet的必選屬性,可以選擇使用urlPatterns或者value定義。
* 例如:@WebServlet(name="AnnotationServlet",value="/AnnotationServlet")。
*
*  也可以定義多個URL訪問:
*  如@WebServlet(name="AnnotationServlet",urlPatterns={"/AnnotationServlet","/AnnotationServlet2"})
*  或者@WebServlet(name="AnnotationServlet",value={"/AnnotationServlet","/AnnotationServlet2"})
*/
@WebServlet(name="CheckNumber",urlPatterns={"/checkNumber"},initParams= {@WebInitParam(name = "my_jianshu_url", value = "http://www.jianshu.com/u/187408ee66d4")},loadOnStartup = 1)
public class CheckServlet extends HttpServlet{
//處理get請求,在此方法內編寫處理邏輯。
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
System.out.println("我的簡書連結:"+getServletConfig().getInitParameter("my_jianshu_url"));
String[] number=req.getParameterValues("number");
for(int i=0;i<7;i++){
System.out.print(number[i]);
}
System.out.println("---------");
String[] awardNum=new String[7];
Random random=new Random();
for(int i=0;i<7;i++){
awardNum[i] = random.nextInt(10)+"";
System.out.print(awardNum[i]);
}
System.out.println("------");
int count = 0,max = 0,position = 0;
for(int i= 0;i<awardNum.length;i++){
if(awardNum[i].equals(number[i])){
count++;
if (count>max) {
position=i;
max=count;
}
}else{
count=0;
}
}
req.setAttribute("number", number);
req.setAttribute("awardNum", awardNum);
req.setAttribute("bool", "");
req.setAttribute("begin",8 );
req.setAttribute("end", 8);
String[] result = {"六等獎","五等獎","四等獎","三等獎","二等獎","一等獎"};
if(max >1){
req.setAttribute("bool", true);
req.setAttribute("result","恭喜你中了" +result[max-2]);
req.setAttribute("begin", position-max+1);
req.setAttribute("end", position);
}
RequestDispatcher dispatcher = req.getRequestDispatcher("/showResult.jsp");
dispatcher.forward(req, resp);
}
//處理post請求,在此方法內編寫處理邏輯。
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
super.doPost(req, resp);
System.out.println("doPost() executed");
}
}
複製程式碼
四、Summary.
- 兩種配置方式不要混用,避免出現同時配置@WebServlet註解標記和web.xml中等標籤的現象。
- 兩種配置方式比較: XML配置形式,在需要修改Servlet的配置資訊(比如初始化引數的值)時,只需在伺服器訪問目錄直接修改web.xml檔案而不需要修改java檔案然後再重新編譯成class檔案; 但是當web.xml檔案中出現大量的Servlet配置時,就會顯得冗雜,而註解方式讓配置更方便、簡練。
本節Demo原始碼GitHub下載: https://github.com/Breaker-93/Demo0923breaker_Servlet.git 若有疑問、請留言。