Web小结---Servlet,JSP,过滤器和监听器,四个作用域和九个内置对象,EL表达式语言,自定义标签,JSTL,国际化与汉字的编码
原文地址:http://blog.csdn.net/imnol/archive/2007/08/15/1745288.aspx
一 Servlet
1、Servlet、ServletConfig:前者对应一个Servlet类,后者对应的是在web.xml中的配置信息
(1)Servlet:
init(ServletConfig):只再类加载并实例化后会被调用一次。
service(ServletRequest,ServletResponse):会被调用多次
destroy():只有一次
getServletConfig()
getServletInfo()
(2)ServletCionfig
getServletName()
getInitParameter(String):---<servlet><init-param></init-param></servlet>
getInitParameterNames():
getServletContext
注意ServletContext中也有getInitParameter(String),它对应的是:<context-param>中嵌套的元素
这个<context-param>和<servlet>标签是同级别的,初始化的是整个应用程序
2、两个类:
GenericServlet/HttpServlet:
GenericServlet实现Servlet和ServletConfig,HttpServlet继承自GenericServlet,而且它是和HTTP协议相关的。
(1)GenericServlet:具有一个无参的init方法,方便子类的覆盖。
(2)HttpServlet:具有两个service方法,并且有7个do方法。重写的时候一般重写do方法
3、Servlet配置
指的是web.xml中的信息,
<servlet>
<servlet-name></servlet-name>
<servlet-class></servlet-class>
<init-param></init-param>
</servlet>
//上面的配置对应的可以说就是ServletConfig中的东西
<servlet-mapping>
<servlet-name></servlet-name>
<url-pattern></url-pattern>
</servlet-mapping>
4、WEB应用程序文件夹的结构
--WEB-INF
|
|------------web.xml
|------------lib文件夹 JAR文件
|------------classes 类文件
|------------tags TagFile标签文件
--静态资源与JSP文件
5、请求和响应:
(1)请求ServletRequest->HttpServletRequest
getParameter(String)、
getHeader()、
getParameterValues(String)、用于复选框
getParameterNames、
getRemoteAddr、得到远程地址
getLocalAddr、得到本地地址
getLocale、得到本地化信息
getSession/getCookies
getRequestDispatcher
(2)响应ServletResponse->HttpServletResponse
sendRedirect
sendError
setHeader/addHeader/setIntHeader
getWriter/getOutputStream :这两个方法绝对不可以同时被调用!!!!!
setContentType/setCharacterEncoding
6、请求的转发和响应的重定向之间的区别要搞清楚
(1)转发:
A、三种转发的方法:
RequestDispatcher.forward/include
<jsp:include>
<jsp:forward> 等价于RequestDispatcher.forward();return;
也就是说使用RequestDispatcher.forward()后,下面的代码仍然要执行,但是<jsp:forward>执行后,下面的代码就不执行了。
pageContext.forward/include
B、如何得到RequestDispatcher:
request.getRequestDispatcher
ServletContext.getRequestDispatcher
RequestDispatcher的请求转发、Jsp页面中指令元素include、以及ServletContext中的getResourceAsStream(String path)
(用来读出文件夹中的路径资源)都可以访问WEB-INF文件夹,
比如为了防止用户访问一些受保护的页面(比如控制器Servlet),把它们放到WEB-INF中去,请求转发的时候可以去访问。
有的时候需要读取WEB-INF中的一些配置资源,需要ServletContext中的getResourceAsStream方法。
而且有的网站的各个页面具有相同的头图片和尾图片,这些东东就可以放到WEB-INF文件夹中用page元素的include指令来包含进来。
注意如果使用ServletContext的RequestDispatcher,要从A应用程序转发请求到B,必须设定A的crossContext值为true!
(2)重定向
response.sendRedirect:比如在注册结束后转到下一个页面的时候,一定要使用重定向改变浏览器的URL地址!
请求的转发不可能脱离Tomcat服务器的范围,如果想要脱离本服务器的话,只能通过响应重定向的方式。重定向要生成一个临时的响应,(响应
一旦生成请求就结束了)浏览器接到这个临时的响应后不显示任何东西而是发送请求去找新的地址。
二、JSP
1、模板和元素:
对于JSP来说,它是不可执行的,必须翻译成Servlet才能执行,必须要容器特殊处理的叫做元素,
直接打印到输出流中去的是模板
元素分为以下几种:
1脚本元素
2指令元素
3动作元素
1脚本元素:
(1)脚本片断:翻译后原封不动的放到service方法里面
(2)脚本声明:放在类里面,但是是在service方法外面,
(3)脚本表达式:原封不动的放到out.print里面去,脚本表达式不可以加分号。
内置对象绝对不可以在脚本声明中去用!因为它们的作用是在service方法里面的。
2指令元素:
Page指令:
include指令<%@include file=""%>,包含的这个文件一定是按照纯文本的格式去读取,读取文件的时候就有编码的问题,这时候就是pageEncoding
的设置问题了。
taglib指令
3页面乱码:pageEncoding/contentType
前者设置jsp页面读取的形式,后者设置一个响应的报头,告诉浏览器以什么编码格式去显示
如果没有设置pageEncoding而是只设置了contentType的话,那么pageEncoding要受contentType影响,反之亦然。
也就是两者只设一者的话都会按照一个编码去显示!
无论请求还是响应,递交的时候默认都是按照iso-8859-1去解码的。一定要保证读写和显示时候的编码都是一致的
4 动作元素:
<jsp:useBean>:主要作用:开放一个脚本变量并且向作用域里面存一个属性
<jsp:setProperty>
<jsp:getProperty>
<jsp:forward>
<jsp:include>
<jsp:param>
前六个比较重要!
<jsp:invoke>
<jsp:doBody>
<jsp:plugin>
<jsp:fallback>
<jsp:params>
三、过滤器和监听器
1、Filter/FilterConfig
init(FilterConfig)
doFilter(ServletRequest,ServletResponse,FilterChain)
destroy()
<filter>
<filter-name>
<filter-class>
</filter>
<filter-mapping>
<filter-name>
<url-pattern>|<servlet-name>
</filter-mapping>
url-pattern相同的过滤器处于一个过滤器链上,执行的顺序完全按照web.xml中的先后顺序进行。
2、监听器->ServletContext/HttpSession/ServletRequest
(1)生命周期
ServletContextListener:初始化(从BBS中读取全部讨论区并存储在应用程序的作用域中或是将全部封杀的IP读出来存储)和销毁
HttpSessionListener/HttpSessionActivationListener
ServletRequestListener
(2)属性的增删改
一般是AttributeListener去作的
<listener>
<listener-class>包名.类名</listener-class>
</listener>
四、四个作用域和九个内置对象
1、页面作用域对应的是pageContext,而不是page
2、内置对象:
pageContext/request/session/application
out->是JspWriter的实例,它有缓存,而PrintWriter没有缓存,在页面结束的时候一定会通过响应生成PrintWriter去写出缓存的内容!
如果缓存满了的话,要看:如果<%@page autoFlush="true"%>,则会自动刷新,如果是false,会抛出异常的!response.getWriter()
返回的是PrintWriter,不是JspWriter。
exception->isErrorPage=true的时候才有用
session:两种跟踪机制:一种是通过客户端的cookie存储,另外一种是将sessionId存在服务器端,
config->ServletConfig
page->Object->this
response:
五、EL表达式语言:
${}
1、常量、函数、变量的表达式
2、变量是存储在某一作用域中的同名的属性值
3、函数是在tld文件中声明的引用一个类的公共且静态的方法
4、11个内置对象
(1)作用域:pageScope/requestScope/sessionScope/applicationScope
(2)和页面通信:pageContext
(3)请求参数的:param/paramValues
(4)报头:header/headerValues
(5)Cookies/initParam ---<context-param>
5、点操作符和[]操作符和empty
对javaBean,是调用getter方法,
对map,是调用get(Object)方法,
对作用域,是调用getAttribute(String)
对pageContext,也是调用getter方法,可以得到所有的内置对象
对param,是去取得参数
对header,是去拿报头
对initParam,是去拿初始化参数
[]操作符主要是针对数组
六 自定义标签
1、Tag接口(传统接口系列)
JspTag
(1)Tag : doStartTag(返回值是SKIP_BODY/EVAL_BODY_INCLUDE)/doEndTag(返回SKIP_PAGE或是EVAL_PAGE)
(2)IterationTag->TagSupport
doAfterBody:EVAL_BODY_AGAIN/SKIP_BODY
(3)BodyTag->BodyTagSupport
doInitBody
doAfterBody:EVAL_BODY_BUFFERED->BodyContent:pageContext里面有一个pushBody,用来将体包起来,这时候再用getOut方法得到
的不再是JspWriter了,而是bodyContent了。BodyContent的生成是调用了pushBody方法,这里面又涉及一个getEnclosingWriter(),它
是BodyContent的一个方法,可以得到它里面包的输出流JspWriter,但是要注意要是进行了一次以上的pushBody但是没有进行popBody的话,那么
拿出来的就是里面包的BodyContent了,但是由于BodyContent是JspWriter的子类,所以也是符合方法声明的
2、SimpleTag接口(简单接口系列)
setJspContext()
setParent()
setJspBody(JspFragment) 注意JspFragment是标签体,里面绝对不可以有脚本元素的!注册的时候content元素中要么设置为empty,
要么设置为scriptless,也就是简单标签的标签体是不可以有脚本元素的!
doTag()
JspFragment.invoke(null):直接弄到输出流中去
JspFragment.invoke(StringWriter out):将输出流弄到StringWriter中去,然后调用out.toString可以将体变成字符串的形式
3、Tag File标签文件
.tag
可以放在/WEB-INF/tags里面或者/META-INF/tags里面也可以
至于标签文件的tld可以放在WEB-INF中也可以放在META-INF中去,都是没有问题的
标签文件描述的是标签处理类,jsp描述的是Servlet,二者都是不可运行的,注意标签文件中有<%@tag%>,里面可以设置不少标签的属性
还有<%@attribute %>,<%@taglib%>和<%@include%>也可以用,属性可以是JspFragment
比如:<my:first>
<jsp:attribute>
</jsp:attribute>
<jsp:body>
</jsp:body>
</my:first>
<jsp:invoke name=var>运算结果就放在了var里面
<jsp:doBody> 处理体
七、JSTL
一共5个库,我们说了core、sql、i18n、fn标记库(就是表达式语言的函数库)
我们没有讲xml的标签库
八、国际化与汉字的编码
ResourceBundle
两种形式:
1、ListResourceBundle
2、写一个Properties文件,里面有一个nativetoacsii命令进行,参照前面的笔记转码
基名和扩展名:起名字都是要有标准的
Locale:本地化对象
getBundle方法可以通过传入基名和本地化对象来处理
<fmt:bundle>
<fmt:setBundle>
<fmt:message>
汉字编码:GB2312/GB13000(GBK)/GB18030
Unicode UCS/UTF-8