JSP/Servlet及相關技術詳解(二)


2.10 Servlet介紹
2.10.1 Servelt的開發
Servelt必須繼承HttpServlet。
Servlet提供不同的方法用於響應客戶端請求。
>doGet:GET請求
>doPost:POST請求
>doPut:PUT請求
>doDelete:DELETE請求
重寫這4個方法來響應客戶端請求,或者重寫service()方法。

>init(ServletConfig config)
>destroy()

Servlet和JSP的區別在於:
>Servlet中沒有內置對象,原來JSP中的內置對象都必須由程序顯示創建。
>對於靜態的HTML標籤,Servlet都必須使用頁面輸出劉住行顯示。
普通Servlet類裏的service()方法的作用,完全等同於JSP生成Servlet類的_jspService()方法。

2.10.2 Servlet的配置
從Servlet3.0開始,配置Servlet有兩種方式:
>在Servlet類中使用@WebServlet Annotation進行配置。
>通過在web.xml文件中進行配置。

@WebServlet支持的常用屬性
asyncSupported    是否支持異步模式
displayName        指定該Servlet的顯示名
initParams        爲該Servlet配置參數
loadOnStartup    配置該Servlet配置成load-on-startup
name            指定該Servlet的名稱
urlPatterns/value        完全相同,指定該Servlet處理的URL
ex:
@WebServlet(name="firstServelt", urlPatterns={"/firstServlet"})

注意:不要在web.xml的<web-app.../>中指定metadata-complete="true"

web.xml ex:
<!-- 配置Servlet的名字 -->
<servlet>
       <!--指定名字,相當於name屬性-->
       <servleta-name>firstServlet</servlet-name>
       <!--指定Servlet的實現類-->
       <servlet-class>pack.FirstServlet</servlet-class>
</servlet>
<servlet-mapping>
       <!--指定Servlet的名字-->
       <servlet-name>firstServlet</servlet-name>
       <!-- 指定Servlet映射的URL地址,相當與urlPattern -->
       <url-pattern>/aa</url-pattern>
</servlet-mapping>

2.10.3 JSP/Servlet的生命週期
創建:
客戶端第一次請求某個Servelt時,系統創建該Servlet的實例:大部分的Servlet都是這種。
web應用啓動時立即創建Servlet實例,即load-on-startup Servlet。

生命週期:
1.創建
2.init()
3.Servlet初始化後,將一直存在於容器中,用於響應客戶端請求。
4.destroy()

2.10.4 load-on-startup Servlet
這種Servlet通常作爲應用的基礎Servlet使用,提供重要的後臺服務。
@WebServlet(loadOnStartup=1)
or
<servlet>
<servlet-name>timerServlet</servlet-name>
<servlet-class>pack.TimerServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

2.10.5 訪問Servlet的配置參數
使用ServletConfig對象獲取參數:getInitParameter(String name)
配置方式:
@WebServlet(name="testServlet", urlPatterns={"/testServlet"},
initParams={@WebInitParam(name="driver", value="com.mysql.jdbc.Driver"),
@WebInitParam(name="url", value="jdbc:mysql://localhost:3306/javaee"),
@WebInitParam(name="user", value="root"),
@WebInitParam(name="pass", value="123456")})
or:
<servlet>
<servlet-name>testServlet</servlet-name>
<servlet-class>pack.testServlet</servlet-class>
<init-param>
<param-name>driver</param-name>
<param-value>com.mysql.jdbc.Driver</param-value>
</init-param>
<init-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost:3306/javaee</param-value>
</init-param>
....
</servlet>

2.10.6 使用Servlet作爲控制器

2.11 JSP2的自定義標籤
在JSP規範的1.1版中增加了自定義標籤規範,自定義標籤是一種非常優秀的表現層組件技術。
JSP 2規範簡化了標籤庫的開發,步驟:
1.開發自定義標籤處理類
2.建立一個*.tld文件,每個*.tld文件對應一個標籤庫,每個標籤庫可包含多個標籤。
3.在JSP文件中使用自定義標籤

2.11.1 開發自定義標籤類
自定義標籤類應該繼承一個父類:javax.servlet.jsp.tagext.SimpleTagSupport。
如果標籤包含屬性,每個屬性都有對應的getter和setter方法。
重寫doTag()方法,這個方法負責生成頁面內容。
ex:
public class HelloWorldTag extends SimpleTagSupport{
      public void doTag() throws JspException, IOException{
                //獲取頁面輸出流,並輸出字符串
                getJspContext().getOut().write("Hello World "+new java.util.Date());
      }
}

2.11.2 建立TLD文件
TLD:Tag Library Definition
ex:
mytaglib.tld
<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
   http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
   version="2.0">
   <description>A tag library exercising SimpleTag handlers.</description>
   <tlib-version>1.0</tlib-version>
   <short-name>mytaglib</short-name>
   <uri>http://tomcat.apache.org/mytaglib</uri>
   <tag>
       <description>Outputs Hello, World</description>
       <name>helloWorld</name>
       <tag-class>jsp2.examples.simpletag.HelloWorldSimpleTag</tag-class>
       <body-content>empty</body-content>
   </tag>
</taglib>

body-content子元素:
tagdependent:指定標籤處理類自己負責處理標籤體。
empty:指定該標籤只能作爲空標籤使用
scriptless:指定該標籤的標籤提可以是靜態HTML元素、表達式語言,但不允許出現JSP腳本。

dynamic-attributes:指定該標籤是否支持動態屬性。
參考:apache-tomcat-7.0.39/webapps/examples/WEB-INF/jsp2

2.11.3 使用標籤庫
在JSP頁面中確定指定的標籤需要兩點。
>標籤庫URI:確定使用哪個標籤庫。
>標籤名:確定使用哪個標籤庫。

使用步驟:
>導入標籤庫:使用taglib編譯指令導入標籤庫,就是將標籤庫和指定前綴關聯起來。
<%@taglib uri="tagliburi" prefix="tagPrefix" %>
>使用標籤:在JSP頁面中使用自定義標籤。
<tagPrefix:tagName tagAttribute="tagValue"...>
<tagBody/>
</tagPrefix:tagName>

ex:
<%@taglib uri="http://tomcat.apache.org/mytaglib" prefix="mytag" %>

<mytag:helloWorld/>

2.11.4 帶屬性的標籤
必須定義getter和setter方法
tld實例:
   <tag>
       <description>Populates the page context with a BookBean</description>
       <name>findBook</name>
       <tag-class>jsp2.examples.simpletag.FindBookSimpleTag</tag-class>
       <body-content>empty</body-content>
       <attribute>
           <name>var</name>
           <required>true</required>
           <rtexprvalue>true</rtexprvalue>
       </attribute>
   </tag>
   <tag>
       <description>
           Takes 3 fragments and invokes them in a random order
       </description>
       <name>shuffle</name>
       <tag-class>jsp2.examples.simpletag.ShuffleSimpleTag</tag-class>
       <body-content>empty</body-content>
       <attribute>
           <name>fragment1</name>
           <required>true</required>
           <fragment>true</fragment>
       </attribute>
       <attribute>
           <name>fragment2</name>
           <required>true</required>
           <fragment>true</fragment>
       </attribute>
       <attribute>
           <name>fragment3</name>
           <required>true</required>
           <fragment>true</fragment>
       </attribute>
   </tag>
name:設置屬性名,子元素的值必須是字符串內容。
requirement:設置該屬性是否爲必須屬性,true/false
fragment:設置該屬性是否支持JSP腳本,true/false
rtexprvlaue: Runtime Expression Value 是否可以通過動態計算指定。

JSTL和DisplayTag

2.11.5 帶標籤體的標籤
ex:
public class IteratorTag extends SimpleTagSupport{
      private String collection;
      private    String item;
      //省略getter/setter
      public void doTag() throws JspException, IOException{
             //從page scope中獲取屬性名爲collection的集合
             Collection itemList = (Collection)getJspContext().getAttribute(collection);
             for(Object s:itemList){
                     //將集合的元素設置到page範圍
                     getJspContext().setAttribute(item, s);
                  //輸出標籤體
                     getJspBody().invoke(null);
          }
      }
}

tld:
<body-content>scriptless</body-content>

jsp:
<mytag:iterator collection="a" item="item">
<tr>
       <td>${pageScope.item}</td> <!--JSP expression lauguage -->
</tr>
</mytag:iterator>


2.11.6 以頁面片段作爲屬性的標籤
>標籤處理類中定義類型爲JspFragment的屬性,該屬性代表了“頁面片段”
>使用標籤庫時,通過<jsp:attribute.../>動作指令爲標籤庫屬性指定值。

ex:
public class FragmentTag extends SimpleTagSupport{
      private JspFragment fragment;
      //getter/setter省略
      @Override
      public void doTag() throws JspException, IOException{
                JspWrite out = getJspContext().getOut();
             out.println("<div style='padding:10px;border:1px solid black'>");
             out.println("<h3>下面是動態傳入的JSP片段</h3>");
             fragment.invoke(null);
             out.println("</div>");
      }
}

tld:和普通的一致

jsp:
<mytag:fragment>
       <jsp:attribute name="fragment">
                      <mytag:helloWorld/>
       </jsp:attribute>
</mytag:fragment>

<mytag:fragment>
       <jsp:attribute name="fragment">
                      ${pageContext.request.remoteAddr}
       </jsp:attribute>
</mytag:fragment>

2.11.7 動態屬性的標籤
在某些特殊情況下,我們需要傳入自定義標籤的屬性個數是不確定的,屬性名也不確定。需要使用動態屬性的標籤。
>標籤處理類還需要實現DynamicAttributes接口。
>配置標籤時通過<dynamic-attribute.../>子元素指定該標籤支持動態屬性。

ex:
public class DynaAttributesTag extends SimpleTagSupport implements DynamicAttributes
{
private ArrayList<String> keys = new ArrayList<String>();
private ArrayList<Object> values = new ArrayList<Object>();

@Override
public voi doTag() throws JspException, IOException{
JspWriter out = getJspContext().getOut();
out.println("<ol>");
for(int i = 0; i<keys.size(); i++){
String key = keys.get(i);
Object value = values.get(i);
out.println("<li>"+key+" = "+value+"</li>");
}
out.println("</ol>");
}

@Override
public void setDynamicAttributes(String uri, String localName, Object value) throws JspException{
keys.add(localName);
values.add(value);
}
}

tld:
<tag>
<name>dynaAttr</name>
<tag-class>DynaAttributesTag</tag-class>
<body-content>empty</body-content>
<dynamic-attributes>true</dynamic-attribute>
</tag>

jsp:
<mytag:dynaAttr name="digit" other="education"/>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章