Servlet/JSP学习总结

3月29日

一.Servlet技术

1.      编写一个Servelt,需要实现javax.servlet.Servlet接口。该接口定义了5个方法:init(ServletConfigconfig),service(ServletRequestreq,ServletResponseresp),destroy(),getServletConfig(),getServletInfo().

2.      ServletRequest和ServletResponse接口都在javax.servlet包中定义

3.      ServletConfig:Servlet容器使用ServletConfig对象在Servlet初始化期间向它传递配置信息,一个Servlet只有一个ServletConfig对象.

4.      GenericSevlet:GenericServlet类定义了一个通用的、不依赖于具体协议的Servlet,它实现了Servlet接口和ServletConfig接口.

5.      HttpServlet:在javax.servlet.http包中,是一个抽象类,它继承自GenericServlet类,用于创建Web站点的HTTP Servlet。针对HTTP1.1中定义的7中请求方法,HttpServlet分别定义了7个处理方法:doGet,doPost,doHead,doPut,doDelete,doTrace,doOptions。当容器收到一个针对HttpServlet对象的请求时,调用该对象中的方法顺序为:调用公共的service()方法;在公共service()方法中,首先将参数类型转换为HttpServletRequest和HttpServletResponse,然后调用保护的service()方法,将转换后的HttpServletRequest和HttpServletResponse对象作为参数传递进去;在保护的service()方法中,首先调用HttpServlet对象的getMethod()方法,获取HTTP请求方法的名字,然后根据请求方法类型调用相应的doXxx()方法。对于HTTP1.0,这些方法返回状态码400的HTTP错误,表示语法错误。对于HTTP1.1,则返回405错误,表示请求资源的请求方法不被允许。

6.      HttpServletRequest和HttpServletResponse:在javax.servlet.http包中,定义了HttpServletRequest和HttpServletResponse这两个接口。这两个接口继承自ServletRequest和ServletResponse

7.      Servlet上下文:用ServletContext接口表示。可以通过ServletConfig对象的getServletContext()方法得到 ,也可以通过GenericServlet类的getServletContext()方法得到.上下文路径总是以(/)开头,结束没有(/)。

8.      请求转发:通过javax.servlet.RequestDispatcher接口转发。该接口两种方法,forward和include。两者区别:利用include()方法将请求转发给其他Servlet,被调用的Servlet对该请求作出的响应将并入原先的响应对象中,原先的Servlet还可以继续输出响应信息,而利用forward()方法将请求转发给其他的Servlet,将由被调用的Servlet负责对请求作出响应,而原先Servlet的执行则终止。RequestDispatcher对象通过三种方法得到:通过ServletRequest接口中的getRequestDispatcher();通过ServletContext接口的getNamedDispatcher()和getRequestDispatcher()方法。注意的是:ServletContext接口提供的方法参数必须以(/)开始。而ServletRequest接口提供的方法参数可以是山下文的路径,也可以是相对当前Servlet的路径。

二.Web应用程序的部署

1.      通过元素配置:可以放在服务器中;也可以放在Web应用程序中。如果在应用程序中配置,只需要在META-INF子目录下建立一个context.xml文件。

2.      打包WAR文件:进入Web程序根目录下,执行jar –cvf 文件名.war *即可。如果不想包含src目录,则执行:jar –cvf 文件名.war *.html WEB-INF/即可。

三.数据库访问

1.      JDBC驱动程序的类型:JDBC-ODBC桥;部分本地API,部分Java驱动程序;JDBC网络纯Java驱动程序;本地协议纯Java驱动程序。

2.      利用JDBC访问数据库步骤如下:首先调用Class类的forName()方法,接下来调用DriverManager类的getConnection()方法,然后调用Connection对象的createStatement()方法,最后调用Statement对象的executeQuery()方法得到ResultSet对象。得到ResultSet对象后,就可以利用它的方法得到数据库的数据了。

3.      建立连接后,需要对数据库访问,在java.sql包中提供了3个接口,分别定义了对数据库调用的不同方式,这三个接口是:Statement,PreparedStatement和CallableStatement。建议使用PreparedStatement代替Statement。通过PreparedStatement对SQL语句进行预编译,比较安全高效。PreparedStatement对象所代表的SQL语句中的参数用问号(?)来表示,调用setXXX()方法来设置这些参数。CallableStatement对象用于执行SQL存储过程。它是从PreparedStatement接口继承而来。在执行存储过程之前,凡是存储过程中类型为OUT的参数必须被注册,用registerOutParameter()方法来完成。对于类型为IN的参数,可以利用setXXX()方法来设置参数的值。

4.      元数据:在SQL中,用于描述数据库或者它的各个组成部分之一的数据称为元数据。可以调用Result对象的getMetaData()方法来得到ResultSetMetaData对象。

5.      事务隔离级别:Read Uncommitted最低等级,仅保证读取过程中不会读取非法数据;Read Committed,保证一个事务不会读到另一个并行事务已修改但未提交的数据,避免脏读;Repeatable Read,避免了“脏读”和“不可重复读”;Serializable,最严格隔离机制,通过串行化方式运行事务。在Connection接口中定义了setTransactionIsolation()方法,用于设置隔离级别。同时定义了5个常量,用作该方法的参数:TRANSACTION_NONE:不支持事务;TRANSACTION_READ_UNCOMMITTED:可以发生脏读,不可重复读和幻读;TRANSACTION_READ_COMMITTED:禁止脏读,可以发生不可重复读和幻读;TRANSACTION_REPEATABLE_READ:禁止脏读和不可重复读,可以发生幻读;TRANSACTION_SERIALIZABLE:禁止脏读,不可重复读和幻读。

6.      JDBC数据源和连接池:除了之前的建立数据库的连接方式,还有通过向一个JNDI(Java Naming and Directory)服务器查询来得到DataSource对象,然后调用对象的getConnection()方法来建立数据库的连接。步骤如下:通过javax.naming.Context接口来创建一个命名对象,然后通过这个对象的lookup()方法来得到DataSource对象。Javax.sql.DataSource接口可以有3种类型的实现:基本的实现,与调用驱动的方法得到连接对象一样;连接池的实现,这种实现需要和一个中间层连接池管理器一起工作;分布式事务实现,这种实现需要和一个中间层事务管理器和连接池管理器一起工作。在Tomcat中,可以在元素的内容中使用元素来配置JDBC数据源。

3月31日

四.会话跟踪

1.      Java Servlet API使用Session来跟踪会话和管理会话内的状态。在Servlet规范中,描述了下列三种机制用于会话跟踪:SSL(Secure Socket Layer,安全套接字层)会话;Cookie;URL重写。

2.      SSL会话:它是一种运行于TCP/IP之上和像HTTP这种应用层协议之下的加密技术。SSL是在HTTPS协议中使用的加密技术。SSL可以让采用SSL的服务器认证采用SSL的客户端,并且在客户端和服务器之间保持一种加密的连接。在建立了加密连接的过程中,客户和服务器都可以产生名叫“会话密钥”的东西。它是一种用于加密和解密消息的对称密钥。基于HTTPS协议的服务器可以使用这个客户的对称密钥来建立会话。

3.      Cookie,译为小甜饼,有Netscape公司发明,是最常用的跟踪用户会话的方式。Cookie是一种由服务器发送给客户的片段信息,存储在客户端浏览器的内存中或硬盘上,在客户随后对该服务器的请求中发回它。默认情况下,Java Servlet API采用版本0创建Cookie。在Servlet规范中,用于会话跟踪的Cookie的名字必须是JSESSIONID。

4.      URL重写:当客户端不接受Cookie的时候,可以使用URL重写的机制来跟踪用户的会话。URL重写就是在URL中标识客户的Session ID,Servlet容器解释URL,取出Session ID,根据Session ID将请求与特定的Session关联。如:http://www.sunxin.org/bbs/index.jsp;jsessionid=1234?name=zhangsan&age=18。要跟踪客户端的会话,就需要将所有的发往客户端的URL进行编码,这可以通过调用HttpServletResponse接口中的encodeURL()方法和encodeRedirectURL()方法来实现。其中,encodeRedirectURL()方法主要在sendRedirect()方法调用之前使用,用于编码重定向的URL。

5.      Java Servlet API中,javax.servlet.http.HttpSession接口封装了Session的概念,Servlet容器提供了这个接口的实现。当请求一个会话的时候,Servlet容器就会创建一个HttpSession对象,有了这个对象后,就可以利用这个对象中保存客户的状态信息。整个会话跟踪过程对于客户和开发人员是透明的(由Servlet容器来完成),开发人员所要做的就是得到HttpSession对象,然后调用这个对象setAttribute()或getAttribute()方法来保存或读取客户的状态信息。

6.      Session和Cookie的深入:Session是一种服务器端技术,Session对象在服务器端创建,通常采用散列表来存储信息。Cookie有Netscape公司发明的,用于跟踪会话的一种方式,Cookie是由服务器发送给客户的片段信息,存储在客户端浏览器的内存中或硬盘上,在客户随后对服务器的请求中发回它。Session和Cookie的最大的区别是,Session在服务器端保存信息,Cookie在客户端保存信息。单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。建议 将登陆信息等重要信息存放为Session,其他信息如果需要保留,可以放在Cookie中。

7.      Session的持久化:我们通过HttpSession的实现类实现java.io.Serializable接口,同时Session中保存的对象所属的类也要实现Serializabal接口。

五.Servlet的异常处理机制

1.      在Servlet中,有两种服务器异常处理机制:声明式异常(declarative exception handling)和程序式异常(programmaticexception handling)。

2.      声明式异常处理是在web.xml文件中声明对各种异常的处理办法。这是通过元素来声明的。利用元素可以声明两种类型的错误处理:一是指定对HTTP错误代码的处理;二是指定对程序产生的Java异常的处理。

3.      程序式异常处理就是在Web程序中利用try-catch语句来捕获异常,并对捕获的异常进行相应的处理。可以通过在try-catch语句中处理,或者使用RequestDispatcher来处理异常。

4.      声明式异常处理实现简单,直接在web.xml文件中进行配置就可以了,可以处理HTTP错误代码和Java异常,缺点是:异常处理非常单一,针对每一种异常,都需要在web.xml文件中进行配置;另外由于抛出的异常被Servlet容器处理并做出响应,所以我们无法得知是哪一段程序代码出现了问题。

5.      程序式异常处理容易了解异常在代码中产生的位置,而且对于同一种异常,可以由不同的程序段抛出,并在catch语句中进行统一处理。程序式异常处理的缺点是无法处理HTTP错误,而且往往需要编写较多的异常处理代码。

六.开发线程安全的Servlet

1.      Servlet规范定义,在默认情况下,Servlet容器对声明的每一个Servlet,只创建一个实例。对于多个请求同时访问。Servlet容器维护了一个线程池来服务请求。线程池实际上是等待执行代码的一组线程,这些线程叫做工作者线程。Servlet容器使用一个调度者线程来管理工作者线程。

2.      Servlet开发时,要从两方面注意线程安全问题:变量的线程安全,属性的线程安全。本地变量总是线程安全的,实例变量和类变量不是线程安全的,请求对象的属性访问是线程安全的,而Session对象和上下文对象的属性访问不是线程安全的。

3.      开发线程安全的Servlet几点建议:尽可能地在Servlet中只使用本地变量;应该只使用只读的实例变量和静态变量;不要在Servlet中创建自己的线程。修改共享对象时,一定要使用同步,尽可能地缩小同步代码的范围,不要直接在service()方法或doxxx()方法上进行同步,以免影响性能。如果在多个不同的Servlet中,要对外部对象进行修改操作,一定要加锁,做到互斥的访问。

4月1日

七.JSP技术

1.      jsp和servlet区别:Servlet是Java对CGI的回应。他们在服务器上执行和解释浏览器的请求,承担客户端和其他应用程序之间的中间层的角色。Servlet主要是把动态的内容混合到静态的内容中以产生HTML。

2.      JSP页面在HTML元素中嵌入Java脚本代码和JSP标记,使得文件长度变短,格式更加清晰。另一方面,JSP把静态和动态的内容分离开来,实现了内容和表示的分离。使用JSP,不需要单独配置每一个文件,只要扩展名是.jsp,JSP容器(也是Servlet容器)就会自动识别,将其转换为Servlet为客户端服务。术语Web容器和JSP容器是同义的。

3.      在JSP2.0规范中,元素有三种类型:指令元素,脚本元素和动作元素。

4.      指令元素:主要用于为转换阶段提供整个JSP页面的相关信息,指令不会产生任何的输出到当前的输出流中。指令元素有三种指令:page,include和taglib。

5.      Page指令有15个属性,要注意的是,如果一个页面通过使用errorPage属性定义了错误页面,那么在web.xml文件中的任何错误页面将不会被使用。无论将page指令放在JSP文件的哪个位置,它的作用范围都是整个JSP页面。

6.      Include指令用于在JSP页面中静态包含一个文件。

7.      Taglib指令允许页面使用用户定制的标签。Taglib指令有三个属性:uri,tagdir,prefix。

8.      脚本元素包含三个部分:声明、脚本段和表达式。JSP2.0增加了EL表达式,作为脚本元素的另一个选择。声明脚本元素用于声明在其他脚本元素中可以使用的脚本变量和方法,脚本段是一段JAVA代码,用于描述在对请求的响应中要执行的动作,表达式脚本元素是JAVA语言中完整的表达式,在响应请求时被计算,计算的结果将被转换为字符串,插入到输出流中。

9.      声明:用于在JSP页面的脚本语言中使用的变量和方法。声明必须是完整的声明语句,遵照Java语言的语法。声明不会在当前的输出流中产生产生任何的输出。利用<%! %>声明的变量,在JSP容器转换JSP页面为Servle类时,将作为该类的实例变量或者类变量,在多用户并发访问时,这将导致线程安全的问题。

10.  脚本段:脚本段是在请求处理期间要执行的Java代码段。脚本段可以产生输出,并将输出发送到客户端,也可以是一些流程控制语句。脚本段以<%开始,以%>结束。

11.  表达式:表达式脚本元素是Java语言中完整的表达式,在请求处理时计算这些表达式,计算的结果将被转换为字符串,插入到当前的输出流中,表达式以<%=开始,以%>结束。

12.  动作元素:动作元素为请求处理阶段提供信息。JSP2.0规范中定义了20个标准的动作元素:,,;;;;,,;;;;;;,;,,,

13.  JSP的隐含对象:request,response,.pageContext,session,application,out,config,page和exception.

14.  对象和范围:在JSP中,有4种范围:page,request,session,application

4月8日

十一. 标签库

1.  标签库API:标签库API定义在javax.servlet.jsp.tagext包中,要开发自定义标签,其核心就是要编写标签处理器类,一个标签对于一个标签处理器类,而一个标签库则是很多标签处理器的集合。所有标签处理器类都要事先JspTag接口。它没有任何方法,主要是作为Tag和SimpleTag接口的共同基类。在JSP2.0之前,所有的标签处理器类都要实现Tag接口,我们称这样的标签为传统标签(classic tag)。后来为了简化标签的开发,JSP2.0规范又定义了一种新的类型规范,称为简单标签(Simple Tag),其对应的处理器类要实现SimpleTag接口。

2.  Tag接口:javax.servlet.jsp.tagest.Tag接口定义了所有的传统标签处理器需要实现的基本方法。

3.  Iteration Tag接口:javax.servlet.jsp.tagext.Iteration Tag接口继承自Tag接口,它新增了一个方法和一个用于返回值的常量,主要用于控制对标签体的重复处理。新增的方法:doAfterBody()用于在每次对标签体处理之后被调用。新增常量:EVAL_BODY_AGAIN

4.  BodyTag接口:javax.servlet.jsp.tagext.BodyTag接口继承自IterationTag接口,它新增了两个方法和一个用做返回值的常量。实现该接口的标签处理器可以在其内部对标签体执行后的内容进行处理。新增的方法:setBodyContent(BodyContent b),doInitBody();新增的常量:EVAL_BODY_BUFFERED

5.  标签库描述符:编写好标签处理器类后,为了使用标签,还需要在标签库描述符文件中配置标签的相关信息,标签库描述符(Tag Library Descriptor,TLD)是一个XML文档,用来描述一个标签库,包含了标签的名字、标签处理器类和标签的属性等信息。JSP容器使用标签库描述符来解释页面中使用的自定义标签。标签库描述符文件使用的扩展名是“.tld”。当标签库部署在JAR文件中时,标签库描述符文件必须放在META-INF目录或子目录下,当标签库直接部署到Web应用程序中时,标签库描述符文件必须放在WEB-INF目录或其子目录下,但不能放在/WEB-INF/classes或/WEB-INF/lib目录下。

 

 

你可能感兴趣的:(Servlet/JSP学习总结)