Your Ad Here
首页 | 编程语言 | 网站建设 | 游戏天堂 | 冲浪宝典 | 网络安全 | 操作系统 | 软件时空 | 硬件指南 | 病毒相关 | IT 认证
软讯网络 > 编程语言 > Java > Servlet与JSP核心编程读书笔记
【标  题】:Servlet与JSP核心编程读书笔记
【关键字】:Servlet,JSP
【来  源】:http://blog.csdn.net/gjl2004yn/archive/2007/04/16/1566623.aspx

Servlet与JSP核心编程读书笔记

Your Ad Here  

3 servlet 基础

1.         servlet 的生命周期。

a)         init方法:首次创建servlet时,它的init方法会得到调用,因此,init是放置一次性设置代码的地方。

                         i.              可以使用此方法进行常规初始化,用来创建或载入在Servlet生命期内用到的一些数据,或者执行某些一次性的计算。

                       ii.              由初始化参数控制的初始化。
要理解init参数的动机,您需要了解什么样的人可能希望对Servlet的行为方式进行定制。其中包括:开发人员、最终用户、部署人员。
开发人员通过改变代码改变Servlet的行为。
最终用户通过向HTML表单提供数据改变Servlet的行为。
部署人员为了能够在不修改Servlet的源代码的情况下,就可以将Servlet在机器间移动,以及改变特定的参数(例如,数据库的地址,连接共享大小,或者数据文件的位置)。init参数的目的就是为了提供这项能力。

b)        service方法:在init之后,针对每个用户请求,都会创建一个纯种,该线程调用前面创建的实例的service方法。service方法检查HTTP请求的类型(GETPOSTPUTDELETE等)并相应地调用doGetdoPostdoPutdoDelete等方法。

c)        doGetdoPostdoXxx方法
GET
请求起因于正常的URL请求,或没有指定METHODHTML表单。POST请求起因于特别将POST列为METHODHTML表单。你可以覆盖doGet/doPost方法来处理。
    DELETE
请求由doDelete处理,PUT doPut方法处理,OPTIONS doOptions处理,TRACE doTrace方法处理。OPTIONSTRACE的请求在Servlet中是自动支持的。
    doHead
以处理HEAD请求(HEAD请求规定,服务器应该只返回正常的HTTP头,不含与之相关联的文档)。为了能够更快地生成对HEAD请求的响应(例如来自定制客户的请求,只需要HTTP报头,不需构建实际的文档输出),会实现doHead方法。

2.         SingleThreadModel接口

a)         通过让Servlet实现这个接口,系统会保证不会有多个请求线程同时访问该servlet的单个实例。大多数和情况下,系统将所有的请求排队,一次只将一个请求转给单个servlet实例。

b)        此接口已经过时,如果要同步最好使用synchronized关键字。

4 客户请求的处理:表单数据

1.         表单数据的读取。

a)         单个值的读取:getParameter(表单项名称),表单项名称大小写敏感。如果表单项存在但没有相应的值,返回空的String;如果没有这样的表单项,则返回null

b)        多个值的读取:getParameterValues(表单项名称),如果同一表单项名称在表单数据中多次出现,则应该调用getParameterValues(返回字符串的数组)。对于不存在的表单项名称,getParameterValues的返回值是null,如果参数只有单一的值,则返回只有一个元素的数组。
如果是HTML表单的设计者,最好保证每个文本字段、复选框或其他用户界面元素都有一个唯一的名称。

2.         参数名的查找:getParameterNamesgetParameterMap
getParameterNames
Enumeration的形式返回表单项名称列表,其中的的每一项都可以转换成String,并可以用在getParametergetParameterValues调用中。如果当前请求中没有表单名称返回空的Enumeration(不是null)。

Enumeration
只是一个接口,它保证实际的类实现了hasMoreElementsnextElement方法:它并不保证具体的实现会采用某种特定的底层数据结构。
getParameterNames
的替代方案是getParameterMap。这个方法返回一个Map:表单名称(字符串)是表的键,表单项的值是表的值。

3.         读取上载的文件和原始数据:getReadergetInputStream
当数据不是HTML表单提交,而是来自于定制的客户程序时,可能需要自己读取和分析这些数据。最常见的客户程序是applet

当数据来自于上载的文件时,可能需要自己读取数据。servletAPI没有定义任何机制来读取<input type=”file”>元素的文件。

4.         多字符集输入的读取:setCharacterEncoding(字符集名称)
request.getParameter
使用服务器的当前字符集解释输入。要改变这种默认行为,需要使用ServletRequestsetCharacterEncoding方法。setCharacterEncoding必须在访问任何请求参数之前调用。

我们可以按照某个字符集读取参数,然后将它转换到另外的字符集;或者用某些字符集提供的自动检测特性。
第一种方案:使用getByte提取出原始的字节数据,之后将这些字节连同期望字符集的名称一同传递给String的构造函数。
例:
    String firstNameWrongEncoding = request.getParameter(“firstName”);
    String firstName = new String(firstNameWrongEncoding.getBytes(), “shift_JIS”);
第二种方案:需要使用一种支持从默认字符集进行检测和转换的字符集。
例:如果允许输入既可以是英语,也可以是日语,则要使用下面的语句:
    request.setCharacterEncoding(“JISAutoDetect”);
    String firstName = request.getParameter(“firstName”);

5.         参数缺失或异常时默认值的应用
如果用户没有提供必需的信息,那么该servlet应该怎么处理这种情况

a)         使用默认值

b)        重新显示这个表单(提示用户缺失的值)。

c)        请求中的参数需要检查下面三种情况:

                         i.              参数的值为null
用户使用了错误的表单或使用了包含GET数据的URL书签,但在制作URL书签之后,参数名发生变化,都会发生返回值为null的情况。

                       ii.              参数的值为空字符串(“”)
用户没有输入指定的值。为了安全起见,最好调用trim,移除用户可能输入的任何空格。

                      iii.              参数的值为非空字符串,但格式错误
在长度和类型(只要求数值的字段)上输入错误。在设计servlet时,要使之能够优雅地处理参数缺失(null或空字符串)或格式不正确等情况。

6.         过滤字符串中的HTML特殊字符

a)         如果servlet希望生成含有诸如<>等字符的HTML,只需简单地使用标准的HTML字符实体——&lt;&gt;

b)        如果您需要读取请求参数,并将它们的值显示在生成的页面中,则必须过滤出那些特殊的HTML字符。不这样做可能会导致输出中缺失部分,或者某些部分格式错误。

c)        Java字符串虽不可改变的(即不能修改),因此,重复的字符串拼接操作需要复制许多字符串片段,并在使用后废弃。建议在循环中执行重复性的拼接操作时,应该使用可以改变的数据结构:StringBuffer是通常的选择。

7.         根据请求参数自动填充Java对象:表单bean

a)         普通的Java对象,如果它所属的类使用私有字段,且拥有遵循get/set命令约定的方法,则可以看作是bean。方法名(除去单词“get””set”,并且首字母小写)称为属性(property)。

8.         当参数缺失或异常时重新显示输入表单。

a)         由同一servlet提供表单、处理数据并提供最后的结果。
表单省略Action属性,从而,表单提交时会自动发送到表单自身的URL

b)        由一个servlet提供表单:由第二个servlet处理数据并提供结果。
从一个servlet转到另外的servlet可以使用response.sendredirectRequestDispatcherforward方法。将数据从负责处理的servlet传递回显示表单的servlet时,最简单的方式是将它存储在HttpSession对象中。

c)        由一个JSP页面“手动地”提供表单:由一个servletJSP页面处理数据并提供结果。

d)        由一个JSP页面提供表单,用从数据对象获取的值自动填写表单中相应的字段:由一个servletJSP页面处理这些数据并提供最终结果。

5 客户请求的处理:HTTP请求报头

1.         简介:请求报头在JSP中的读取及应用与在servlet中相同。请求报头由浏览器间接地设定,并紧跟在初始的GETPOST请求行之后发送。

2.         请求报头的读取。
只需用报头的名称为参数,调用HttpServletRequestgetHeader方法。如果当前的请求中提供了指定的报头,则这个调用返回一个String,否则返回null。在HTTP1.0中,请求的所有报头都是可选的:在HTTP1.1中,只有Host是必需的。因而,在使用请求报头之前一定要检查是否为null。报头名称对大小写不敏感。

a)         访问HTTP报头的方法汇总。
getHeader
是读取输入报头的通用方式。访问其他常用报头的方法有:

                         i.              getCookies方法返回Cookie报头的内容。

                       ii.              getAuthTypegetRemoteUser
返回Authorization报头进行拆分,分解成它的各个构成部分。

                      iii.              getContentLength
返回Content-Length 报送的值(作为一个int值返回)

                     iv.              getContentType
返回Content-Type报头的值(作为一个String返回)

                       v.              getDateHeader getIntHeader
读取指定的报头,然后分别将它们转换成Dateint值。

                     vi.              getHeaderNames
可以使用此方法得到一个Enumeration,枚举当前特定请求中所有的报头名称。

                    vii.              getHeaders
大多数情况下,每个报头名称在请求中只出现一次。然而,报头偶尔也有可能出现多次,每次出现列出各自的值。可以使用此方法得到一个Enumeration,枚举报头每次出现所对应的值。

b)        获取主请求行自身的信息,同样是使用HttpServletRequest提供的方法:

                         i.              getMethod
返回主请求方法(一般是GETPOST,也有可能是HEADPUTDELETE方法)

                       ii.              getRequestURI
返回URL中主机和端口之后,但在表单数据之前的部分。例:http://randomhost.com/servlet/search.BookSearch?subject=jspgetRequestURI返回“/servlet/search.BookSearch”。

                      iii.              getQueryString
返回表单数据。http://randomhost.com/servlet/search.BookSearch?subject=jspgetQueryString返回“subject=jsp”。

                     iv.              getProtocol
返回请求行的第三部分,一般为HTTP/1.0HTTP/1.1

c)        了解HTTP1.1请求报头

                         i.              Accept:这个报头指明浏览器或其他客户程序能够处理的MIME类型。

                       ii.              Accept-Charset:标明浏览器可以使用的字符集(如ISO-8859-1)。

                      iii.              Accept-Encoding:详细列出客户端能够处理的编码类型。gzipcompress是二种最常见的值。

                     iv.              Accept-Language:列出客户程序首选的语言。

                       v.              Authorization:在访问密码保护的Web页面时,客户用这个报头来标识自己的身份。

                     vi.              Connection:标明客户是否能够处理持续性HTTP连接。持续性连接允许客户或其他浏览器在单个socket 中读取多个文件(例如HTML文件及相关的几幅图像),从而节省协商几个独立连接所需的开销。
服务器只在读完HTTP请求之后,才会调用servletservlet的工作只是使服务器能够使用持续性连接;servlet通过设置Content-Length响应报头来做到这一点。

                    vii.              Content-Length:这个报头只适用于POST请求,用来给定POST数据的大小,以字节为单位。只需简单地使用request.getContentlength()就可以得到这个报头的值。

                  viii.              Cookie:这个报头向服务器返回cookie,这些cookie是之前由服务器发送给浏览器的。不要直接读取这个报头,而要使用requet.getCookies

                     ix.              Host:它标明原始URL中给出的主机名和端口号。

                       x.              if-Modified-Since:仅当页面在指定的日期之后发生更改的情况下,客户程序才希望获取该页面。

                     xi.              If-Unmodified-Since:这个报头和If-Modified-Since正好相反;它规定仅当文档比指定的日期要旧时,操作才需要继续。一般来说,If-Modified-Since用在GET请求中(“仅当文档比我缓存的版本要新时,才传送该文档”),而If-Unmodified-Since用在PUT请求中(“仅当我生成这个文档之后,没有其他人对它做过更改时,才更新这个文档”)。

                    xii.              Referer:标明引用Web页面的URL。例如,如果您在Web页面1 单击指向Web页面2的链接,那么,在浏览器请求Web页面2 时,就会将Web页面1 URL引入Referer报头。

                  xiii.              User-Agent:标识生成请求的浏览器或其他客户程序,根据这个报头,可以针对不同类型的浏览器返回不同的内容。

6 服务器响应的生成:HTTP状态代码

简介:Web服务器对请求的响应,一般由一个状态行、一些响应报头、一个空行和相应的文档构成。状态行由HTTP版本、一个状态代码(整数)、以及一段对应状态代码的简短消息(如OK)组成。除MIME类型的Content-Type报头之外,其他的报头都是可选的。

1.         HTTP1.1 中可用的特定状态代码。共分为5类:

a)         100-199
都是信息性的,标示客户应该采取的其他动作。

b)        200-299
表示请求成功。

c)        300-399
用于那些已经移走的文件,常常包括Location报头,指出新的地址。

d)        400-499
表明客户引发的错误。

e)         500-599
表示由服务器引发的错误。

2.         状态代码的指定:

a)         设置任意状态代码:setStatus(一个整数)建议使用HttpServletResponse中定义的常量。因为HTTP请求由状态行、一个或多个报头、一个空行、以及实际的文档按照此处开出的次序组成。所以要在用PrintWriter实际返回任何内容之前调用setStatus

b)        设置302404状态代码:sendRedirectsendError
这两个方法都会抛出IOException异常,而setStatus不会。

状态代码302命令浏览器连接到新位置。sendRedirect方法生成302响应以及Location报头,给出新文档的URL
状态代码404用于服务器没有找到文档的情况。sendError方法发送状态代码(一向为404)以及一小段简短的消息,这段消息被自动安排到HTML文档中发送给客户。

7 服务器响应的生成:HTTP响应报头

响应报头可以用来:指定cookie;提供页面的修改日期(用于客户端缓存),指示浏览器在指定的时间间隔后重新载入页面;给出文件的大小使持续性HTTP连接的应用成为可能;指定生成文档的类型以及执行许多其他任务。

1.         设置响应报头。

a)         setHeader(String headerName, String headerValue)
这个方法将指定名称的响应报头设为给定的值。

b)        setDateHeader(String header, long milliseconds)
这个方法省去将Java日期转换成GMD时间字符串的麻烦。

c)        setIntHeader(String header, int headerValue)
这个方法可以省去在将整数插入到报头之前将int转换成String的不便。

HTTP
允许相同的报头名多次出现,有时,我们希望加入新的报头,而非替换已有的同名报头。方法setHeadersetDateHeadersetIntHeader会替换任何同名的已有报头,而addHeaderaddDateHeaderaddIntHeader等方法可以添加一个报头。

d)        setContentType(String mimeType)
这个方法设置Content-Type报头,大多数servlet都要用到这个方法。

e)         setContentLength(int length)
这个方法设置Content-Length报头,如果浏览器支持持续性(继续使用)HTTP连接,这个报送十分有用。

f)         addCookie(Cookie c)
这个方法向Set-Cookie报头插入一个cookie。由于响应中一般都会拥有多个Set-Cookie行,故而没有对应的setCookie方法。

g)        sendRedirect(String address)
将状态代码设为302,同时设置