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-startupname 指定该Servlet的名称urlPatterns/value 完全相同,指定该Servlet处理的URLex:@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 Definitionex: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/jsp22.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/falsefragment:设置该属性是否支持JSP脚本,true/falsertexprvlaue: Runtime Expression Value 是否可以通过动态计算指定。JSTL和DisplayTag2.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>();@Overridepublic 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>");}@Overridepublic 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"/>