Servlet
1、MVC规范出现后,Servlet的责任开始明确下来,仅仅作为控制器使用,不再需要生成页面标签,也不在作为视图层的角色使用。
2、JSP的本质是Servlet。
3、Servlet通常被称为服务器端小程序,是运行在服务器端的程序,用于处理及相应客户端的请求。
4、Servlet类必须继承HttpServlet超类,提供不同的方法用于响应客户端的请求:
·doGet:用于响应客户端的Get请求。
·doPost:用于响应客户端的Post请求。
·doPut:用于响应客户端的Put请求。
·doDelete:用于响应客户端的Delete请求。
事实上,客户端的请求通常只有Get和Post两种。
5、大部分时候,Servlet对于所有的请求的响应都是完全一样的。此时,可以采用重写一个方法来代替上面几个方法:只需要重写service()方法即可响应客户端的所有请求。
6、另外,HttpServlet还包含两个方法:
·init(ServletConfig config):创建Servlet实例是调用该方法初始化Servlet资源。
·destroy():销毁Servlet实例时,自动调用该方法回收资源。
如果重写了init方法,则应该在重写该方法的第一行调用super.init(config)。
7、Servlet和JSP的区别:
·Servlet没有内置对象,原来JSP中的内置对象必须由程序员显式创建。
·对于静态的HTML标签,Servlet必须使用页面输出流助逐行输出。
8、Servlet编译需要2个库文件:servlet-api.jar 和 jsp-api.jar,这两个包可以在tomcat的lib目录中找到。
9、编译后的servlet class文件应放在web应用下的WEB-INF目中中的classes文件夹内。
10、从Servlet 3.0开始,配置Servlet有两种方式:
·在Servlet类中使用@WebServlet Annotation进行配置
·通过在web.xml文件中进行配置。
11、@WebServlet 支持的常用属性:
属性 | 是否必须 | 说 明 |
asyncSupported | 否 | 指定该Servlet是否支持异步操作模式。 |
displayName | 否 | 指定该Servlet的显示名。 |
initParams | 否 | 用于为该Servlet配置参数。 |
loadOnStartup | 否 | 用于将该Servlet配置成load-on-startup的Servlet。 |
name | 否 | 指定该Servlet的显示名。 |
urlPatterns/value | 否 | 这个两个属性的作用完全相同。都指定该Servlet处理的url。 |
12、如果打算使用Annotation来配置Servlet,有两点需要指出:
① 不要在web.xml文件的根元素<web-app.../>中指定metadata -complete=”true”。
② 不要在web.xml文件中配置该Servlet。
13、如果使用web.xml文件来配置该Servlet,则需要配置如下两个部分:
① 配置Servlet的名字:对应web.xml文件中的<servlet/>元素。
② 配置Servlet的url:对应web.xml文件中的<servlet-mapping>元素。这一步是可选的,但如果没有配置,则该Servlet不能相应用户请求。
14、当Servlet在容器中运行时,其实例的创建及销毁都不是由程序员决定的,而是由web容器进行控制的。
15、创建Servlet实例有两个时机:
·客户端第一次请求某个Servlet时,系统创建该Servlet实例:大部分Servlet都是这种Servlet。
·Web应用启动时立即创建Servlet实例,即load-on-startup Servlet。
16、每个Servlet的运行都遵循如下声明周期:
① 创建Servlet实例。
② Web容器调用Servlet的init方法,对Servlet 进行初始化。
③ Servlet初始化后,将一直存在于容器中,用于响应客户端的请求。如果客户端发送GET请求,容器调用Servlet的doGet方法处理并相应请求;如果客户端发送的是POST请求,容器调用Servlet的doPost方法并处理相应请求。或者统一使用service方法来处理用户请求。
④ Web容器决定销毁Servlet时,先调用Servlet的destroy方法,通常在关闭Web应用之时销毁Servlet。
17、配置load-on-startup Servlet的2种方式:
·在web.xml文件中通过<servlet.../>元素的<load-on-startup.../>子元素进行配置。
·通过@webServlet Annotation的load-on-startup属性指定。
load-on-startup 元素或属性都只接受一个整型值,这个整型值越小,Servlet就越先实例化。
18、为Servlet配置参数的2种方式:
·通过@WebServlet的initParams属性来设定:
@WebServlet(name=”...”, urlPatterns={...},
initParams={
@WebInitParam(name=”...”, value=”...”)
......
}
)
·通过在web.xml文件中的<servlet.../>元素添加<init-param>子元素来设定:
<servlet>
......
<init-param>
<param-name>...</param-name>
<param-value>...</param-value>
</init-param>
......
</servlet>
JSP2 自定义标签库
1、在JSP规范的1.1版中增加了自定义标签库规范,通过使用自定义标签库,可以在简单的标签中封装复杂的功能。
2、使用自定义标签库的主要目的是为了取代丑陋的JSP脚本。在HTML页面中插入JSP脚本有如下几个坏处:
·JSP脚本非常丑陋,难以阅读。
·JSP脚本和HTML代码混杂,维护成本高。
·HTML页面中嵌入了JSP脚本,导致美工人员难以参与开发。
3、JSP 2 标准下开发自定义标签库步骤:
① 建立一个*.tld文件,每个*.tld文件对应一个标签库,每个标签库可包含多个标签。
② 在JSP文件中使用自定义标签。
4、JSP页面中的标签底层有标签处理类支持。
5、自定义标签类需要继承一个父类:javax.servlet.jsp.tagext. SimpleTagSupport,除此之外,JSP自定义标签类还有如下要求:
·如果标签类包含属性,每个属性都应有对应的getter和setter方法。
·重写doTag()方法,这个方法负责生成页面内容(out = getJspContext.getOut();)
6、TLD是Tag Library Definition的缩写,TLD文件也被称为标签库定义文件。
7、TLD文件是一个标准的XML文件,根元素为taglib,它有如下3个子元素:
·tlib-version:指定该标签库实现的版本,这是一个座位标识的内部版本号,对程序没有太大的作用。
·short-name:该标签库的默认短名,该名称通常也没有太大的用处。
·uri:这个属性非常重要,它指定该标签库的URI,相当于指定该标签库的唯一标识,JSP页面使用标签库时就是通过URI来定位标签库的。
8、taglib元素下可以包含多个tag元素,每个tag元素定义一个标签,tag元素允许出现如下常用的子元素:
·name:该标签的名称,这个子元素很重要,JSP页面中就是根据该名称来使用此标签的。
·tag-class:指定标签的处理类,毋庸置疑,这个子元素非常重要,它指定了标签有那个标签处理类来处理。
·body-content:这个元素也很重要,它指定标签体的具体内容,它的值可以是如下几个:
·tagdependent:指定标签处理类自己负责处理标签体。
·empty:指定该标签只能作为空标签使用。
·scriptless:指定该标签体可以是静态的HTML元素、表达式语言,但不允许出现JSP脚本。
·JSP:指定该标签的标签体可以使用JSP脚本。(因为JSP2规范不在推荐使用JSP脚本,所以JSP2自定义标签的标签体中不能包含JSP脚本,所以,实际上,body-content元素的值不可以是JSP)
·dynamic-attributes:指定该标签是否支持动态属性。只有当定义动态属性标签时才需要该子元素。
9、在JSP页面中确定指定的标签需要两点:
·标签库URI:确定使用哪个标签库。
·标签名:确定使用哪个标签。
10、使用标签库需要如下2个步骤:
·导入标签库:使用taglib编译指令导入标签库,将标签库和指定前缀关联起来。
·使用标签:在JSP页面中使用自定义标签。
11、taglib编译指令语法:
<% taglib uri=”tagliburi” prefix=”tagPrefix” %>
12、使用标签的语法格式如下:
<tagPrefix:tagName tag=Attribute=”tagValue” .../>
<tagBody />
</tagPrefix:tagName>
如果没有标签体,则使用格式如下:
<tagPrefix:tagName tag=Attribute=”tagValue” .../>
13、对于有属性的标签,需要为<tag>元素增加<attribute>子元素,每个attribute子元素定义一个标签属性。<attribute.../>子元素通常还需要指定如下几个子元素:
·name:设置属性名,子元素的值是字符串内容
·required:设置该属性是否为必须属性,该子元素的值是true或false。
·fragment:设置该属性是否支持JSP脚本、表达式等动态内容,子元素的值是true或false。
14、JSTL是Sun提供的一套标签库,这套标签库的功能非常强大。另外,DisplayTag是Apache组织下的一套开源标签库,主要用于生成页面并显示效果。
15、使用getJspBody().invoke()调用可以将标签体内容输出。
16、JSP2规范的自定义标签还允许直接将一段“页面片段”作为属性,这种方式给自定义标签提供了更大的灵活性。以页面片段为属性的标签与普通标签的区别不大,只有两个简单的改变:
·标签处理类中定义类型为JspFragment的属性,该属性代表了页面片段。
·使用标签库时,通过<jsp:attribute.../>动作指令为标签属性指定值。
17、在某些情况下,我们需要传入自定义标签的属性个数是不确定的,属性名也不确定,这就需要使用动态属性标签。定义动态属性标签比普通标签多了如下2个额外的要求:
·标签处理类需要实现DynamicAttributes接口。
·配置标签时通过<dynamic-attributes.../>子元素指定该标签支持动态属性。
Filter
1、Filter可认为是Servlet的一种“加强版”,它主要用于对用户请求进行预处理,也可以对HttpServletResponse进行后处理,是个典型的处理链。
2、Filter也可对用户请求生成响应,这一点与Servlet相同,但实际上很少会使用Filter向用户请求生成响应。
3、使用Filter的完整流程是:Filter对用户请求进行预处理,接着讲请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。
4、Filter有如下几个用处:
·在HttpServletRequest到达Servlet之前,拦截客户的HttpServletRequest。
·根据需要检查HttpServletRequest,也可以修改HttpServletRequest头和数据。
·在HttpServletResponse到达客户端之前,拦截HttpServletResponse。
·根据需要检查HttpServletResponse,也可以修改HttpServletResponse头和数据。
5、Filter有如下几个种类:
·用户授权的Filter:Filter负责检车用户请求,根据请求过滤用户非法请求。
·日志Filter:详细记录某些特殊用户的请求。
·负责解码的Filter:包括对非标准编码的请求解码。
·能改变XML内容的XSLT Filter
Filter可负责拦截多个请求或响应;一个请求或响应也可以被多个Filter拦截。
6、创建一个Filter需要2个步骤:
① 创建Filter处理类。
② web.xml文件中配置Filter。
7、创建Filter必须实现javax.servlet.Filter接口,在接口中定义如下三个方法:
·void init(FilterConfig config):用于完成Filter的初始化。
·void destroy():用于Filter销毁前,完成某些资源的回收。
·voiddoFilter(ServletRequest request, ServletResponse response, FilterChain chain):实现过滤功能,该方法就是对每个请求即响应增加额外处理。
8、配置Filter的2种方法:
① 在Filter类中通过Annotation配置:
@WebFilter(filterName=”...”, urlPatterens=”...”)
② 在web.xml文件中通过配置文件进行配置:
<filter>
<filter-name>...</filter-name>
<filter-class>...</filter-class>
</filter>
<filter-mapping>
<filter-name>...</filter-name>
<url-pattern>...<url-pattern>
</filter-mapping>
9、@WebFilter修饰一个Filter类,用于对Filter进行配置,常用属性如下:
属性 | 是否必须 | 说 明 |
asyncSupported | 否 | 指定该Filter是否支持异步操作模式。 |
dispatcherTypes | 否 | 指定该Filter仅对哪种dispatcher模式的请求进行过滤。该属性支持ASYNC、ERROR、FORWARD、INCLUDE、REQUEST这个5个值的任意组合,默认值为同时过滤5种模式的请求。 |
displayName | 否 | 指定该Filter的显示名。 |
initParams | 否 | 用于为该Filter配置参数。 |
filterName | 否 | 指定该Filter的显示名。 |
urlPatterns/value | 否 | 这个两个属性的作用完全相同。都指定该Filter所拦截的url。 |
servletNames | 否 | 该属性值可以指定多个Servlet名称,用于指定该Filter仅对这几个Servlet过滤。 |
10、Servlet通常指配置一个URL,而Filter可以同时拦截多个请求的URL。因此在配置Filter的URL模式时通常会使用模式字符串,使得Filter可以拦截多个请求。
11、在实际项目中Filter中的doFilter方法里的代码就是从多个Servlet的service方法里抽取通用代码,通过使用Filter可以实现更好的代码复用。
12、大部分搜索引擎会有限考虑收录静态的HTML,而不是动态的jsp页面。因此互联网上大部分网站都会考虑使用伪静态,就是将jsp页面这种动态URL伪装成静态HTML页面。现有的URL rewrite开源项目为这种思路提供了实现。
13、URL rewrite 配置信息:
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<filter-class>
org.tuckey.web.filters.urlrewriteFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>UrlrewriteFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
14、WEB-INF路径下的urlrewrite.xml文件定义了伪静态的映射规则,该规则基于正则表达式。
Listener
1、Servlet API 提供了大量监听器(Listener)来监听web应用的内部事件,从而允许当web内部事件发生时回调事件监听器内的方法。
2、使用Listener需要的2个步骤:
·定义Listener实现类。
·通过Annotation或在web.xml中配置Listener。
3、常用的Web 事件监听器接口:
·ServletContextListener:用于监听web应用的启动和关闭。
·ServletContextAttributeListener:用于监听ServletContext范围(application)内属性的改变。
·ServletRequestListener:用于监听用户请求。
·ServletRequestAttributeListener:用于监听ServletRequest范围(request)内属性的改变。
·HttpSessionListener:用于监听用户session的开始和结束。
·HttpSessionAttributeListener:用于监听HttpSession范围(session)内属性的改变。
4、配置Listener只要向Web应用注册Listener实现类即可,无需配置参数,因此十分简单。为Web应用配置Listener也有两种方式:
·使用@WebListener修饰Listener即可。
·在web.xml文档中使用<listener.../>元素进行配置:
<listener>
<listener-class>...</listener-class>
</listener>
5、ServletContextListener接口包含方法:
·contextInitialized(ServletContextEvent sce):启动web应用时,系统调用Listener的该方法。
·contextDestroyed(ServletContextEvent sce):关闭web应用时,系统调用Listener的该方法。
6、ServletContextAttributeListener接口包含的方法:
·attributeAdded(ServletContextAttributeEvent event):当程序把一个属性存入application范围时触发该方法。
·attributeRemoved(ServletContextAttributeEvent event):当程序把一个属性从application范围删除时触发该方法。
·attributeReplaced(ServletContextAttributeEvent event):当程序替换application范围内的属性时触发该方法。