分享

J2EE笔记(二) — Java web

 openwudi 2010-10-08

Servlet

Servlet是一种服务器端的Java应用程序,具有独立于平台和协议的特性,可以生成动态的Web页面。 它担当客户请求(Web浏览器或其他HTTP客户程序)与服务器响应(HTTP服务器上的数据库或应用程序)的中间层。 Servlet是位于Web 服务器内部的服务器端的Java应用程序,与传统的从命令行启动的Java应用程序不同,ServletWeb服务器进行加载,该Web服务器必须包含 支持ServletJava虚拟机。

HTTPServlet应用编程接口

HTTP Servlet 使用一个 HTML 表格来发送和接收数据。要创建一个 HTTP Servlet,请扩展 HttpServlet 类, 该类是用专门的方法来处理 HTML 表格的 GenericServlet 的一个子类。 HTML 表单是由 <FORM> 和 </FORM> 标记定义的。表单中典型地包含输入字段(如文本输入字段、复选框、单选按钮和选择列表)和用于提交数据的按钮。当提交信息时,它们还指定服务器应执行哪一个Servlet(或其它的程序)。 HttpServlet 类包含 init()destroy()service() 等方法。其中 init() 和 destroy() 方法是继承的。

(1) init() 方法

在 Servlet 的生命期中,仅执行一次 init() 方法。它是在服务器装入 Servlet 时执行的。 可以配置服务器,以在启动服务器或客户机首次访问 Servlet 时装入 Servlet。 无论有多少客户机访问 Servlet,都不会重复执行 init() 

缺省的 init() 方法通常是符合要求的,但也可以用定制 init() 方法来覆盖它,典型的是管理服务器端资源。 例如,可能编写一个定制 init() 来只用于一次装入 GIF 图像,改进 Servlet 返回 GIF 图像和含有多个客户机请求的性能。另一个示例是初始化数据库连接。缺省的 init() 方法设置了 Servlet 的初始化参数,并用它的 ServletConfig 对象参数来启动配置, 因此所有覆盖 init() 方法的 Servlet 应调用 super.init() 以确保仍然执行这些任务。在调用 service() 方法之前,应确保已完成了 init() 方法。

(2) service() 方法

service() 方法是 Servlet 的核心。每当一个客户请求一个HttpServlet 对象,该对象的service() 方法就要被调用,而且传递给这个方法一个"请求"(ServletRequest)对象和一个"响应"(ServletResponse)对象作为参数。 在 HttpServlet 中已存在 service() 方法。缺省的服务功能是调用与 HTTP 请求的方法相应的 do 功能。例如, 如果 HTTP 请求方法为 GET,则缺省情况下就调用 doGet() Servlet 应该为 Servlet 支持的 HTTP 方法覆盖 do 功能。因为 HttpServlet.service() 方法会检查请求方法是否调用了适当的处理方法,不必要覆盖 service() 方法。只需覆盖相应的 do 方法就可以了。

Servlet的响应可以是下列几种类型:

一个输出流,浏览器根据它的内容类型(text/HTML)进行解释。

一个HTTP错误响应重定向到另一个URLservletJSP

(3)doGet()方法

当一个客户通过HTML 表单发出一个HTTP GET请求或直接请求一个URL时,doGet()方法被调用。与GET请求相关的参数添加到URL的后面,并与这个请求一起发送。当不会修改服务器端的数据时,应该使用doGet()方法。

(4)doPost()方法

当一个客户通过HTML 表单发出一个HTTP POST请求时,doPost()方法被调用。与POST请求相关的参数作为一个单独的HTTP 请求从浏览器发送到服务器。当需要修改服务器端的数据时,应该使用doPost()方法。

(5) destroy() 方法

destroy() 方法仅执行一次,即在服务器停止且卸装Servlet 时执行该方法。典型的,将 Servlet 作为服务器进程的一部分来关闭。缺省的 destroy() 方法通常是符合要求的,但也可以覆盖它,典型的是管理服务器端资源。例如,如果 Servlet 在运行时会累计统计数据,则可以编写一个 destroy() 方法,该方法用于在未装入 Servlet 时将统计数字保存在文件中。另一个示例是关闭数据库连接。

当服务器卸装 Servlet 时,将在所有 service() 方法调用完成后,或在指定的时间间隔过后调用 destroy() 方法。一个Servlet 在运行service() 方法时可能会产生其它的线程,因此请确认在调用 destroy() 方法时,这些线程已终止或完成。

(6) GetServletConfig()方法

GetServletConfig()方法返回一个 ServletConfig 对象,该对象用来返回初始化参数和ServletContextServletContext 接口提供有关servlet 的环境信息。

(7) GetServletInfo()方法

  GetServletInfo()方法是一个可选的方法,它提供有关servlet 的信息,如作者、版本、版权。

当服务器调用sevlet Service()doGet()doPost()这三个方法时,均需要 "请求""响应"对象作为参数。"请求"对象提供有关请求的信息,而"响应"对象提供了一个将响应信息返回给浏览器的一个通信途径。

javax.servlet 软件包中的相关类为ServletResponseServletRequest,而javax.servlet.http 软件包中的相关类为HttpServletRequest 和 HttpServletResponseServlet 通过这些对象与服务器通信并最终与客户机通信。Servlet 能通过调用"请求"对象的方法获知客户机环境,服务器环境的信息和所有由客户机提供的信息。Servlet 可以调用"响应"对象的方法发送响应,该响应是准备发回客户机的。

Web.xml注册映射路径

<web-app>

......

<servlet>

<servlet-name>AnyName</servlet-name>

<servlet-class>HelloServlet</servlet-class>

</servlet>

......

<servlet-mapping>

<servlet-name>AnyName</servlet-name>

<url-pattern>/demo/hello.html</url-pattern>

</servlet-mapping>

......

</web-app>

JSP详解

Servlet可以看作是嵌套了HTML代码的Java类。

JSP可以看作是嵌套了Java代码的HTML页面。

JSP可用一种简单易懂的等式表示为:HTML+Java=JSP

JSP执行过程

JSP 的执行过程

(1) 客户端发出Request (请求)

(2) JSP Container JSP转译成Servlet的源代码;

(3) 将产生的Servlet 的源代码经过编译后,并加载到内存执行;

(4) 把结果Response (响应)至客户端。

在执行 JSP 网页时,通常可分为两个时期:转译时期(Translation Time)和请求时期(Request Time)

转译时期:JSP网页转译成Servlet类。

请求时期:Servlet类执行后,响应结果至客户端。

注:

转译期间主要做了两件事情:将JSP网页转译为 Servlet 源代码(.java),此段称为转译时

(Translation time);将Servlet源代码(.java)编译成 Servlet (.class),此段称为

编译时期(Compilation time)

Servlet处理表单数据

使用request.getParameter("")方法获得提交的数据。

response.setContentType("text/html;charset=utf-8")方法设置发送使用UTF-8编码格式。

request.setCharacterEncoding("utf-8")方法设置接收时使用UTF-8编码格式。

response.getWriter()方法返回一个打印流。

JSP处理表单数据

<% 

String username = request.getParameter("username");

String password= request.getParameter("password");

%>

<%=username%>

<%=password%>

JSP语法结构

JSP原始代码中包含了JSP元素和Template data两类。

Template dataJSP不直接处理的部分,即<%....%>以外的部分。

JSP元素指JSP直接处理的部分,这部分必须符合Java语法,不然会导致编译错误。

JSP语法

JSP语法分为三种类型:

编译器指令(DIRECTIVE<%@ page import="java.io.*" %>

脚本语法(SCRIPTING

动作语法(ACTION<jsp:forward> <jsp:include>

脚本语法

HTML注释 <!--comments--> 客户端可以看到

隐藏注释 <%--comments--%> 不会发送到客户端,尽量写隐藏注释。

声明

表达式

脚本段

编译器指令

编译器指令包括:包含指令、页指令、taglib指令。

他们包含在<%@  %>卷标里。

两个主要的指令是pageinclude

动作语法

主要的有:<jsp:forward> <jsp:include> <jsp:getProperty> <jsp:setProperty> <jsp:useBean>

声明

<% int a%><%! int a%>的区别在于,加了!则变量在Java代码中被声明为全局变量。不加则被声明为成员变量。

表达式

用于页面上输入信息。<%= %>

脚本段

<%  %>

包含指令

include指令:向页面插入一个静态文件的内容。<%@ include file="相对位置" %>

Page指令

Page属性用于定义JSP文件中的全局属性。

属性:

1. language="java" 声明脚本语言的种类,目前只能用Java

2. import="{package.class}"需要导入Java包的列表。这些包用于程序段,表达式以及声明。java.lang.*javax.servlet.*javax.servlet.jsp.*javax.servlet.http.*已经被默认导入。

taglib指令

用于引用定制标签库。

<%@ taglib uri="" prefix=""%>

<jsp:forward>跳转指令

重定向一个HTML文件,JSP文件,或者是一个程序段<jsp:forward>标签从一个JSP文件向另一个文件传递一个包含用户请求的request对象<jsp:forward>标签以下的代码,将不能执行  你能够向目标文件传送参数和值,在这个例子中我们传递的参数名为username值为scott,如果你使用了<jsp:param>标签的话,目标文件必须是一个动态的文件,能够处理参数

例子

  <jsp:forward page="/servlet/login" />

  <jsp:forward page="/servlet/login">

  <jsp:param name="username" value="jsmith" />

</jsp:forward> 

<jsp:include>包含一个静态或动态文件

<jsp:include>元素允许你包含动态文件和静态文件,这两种包含文件的结果是不同的。如果文件仅是静态文件,那么这种包含仅仅是把包含文件的内容加到jsp文件中去,而如果这个文件是动态的,那么这个被包含文件也会被Jsp编译器执行(这一切与asp相似)

你不能从文件名上判断一个文件是动态的还是静态的,比如aspcn.asp 就有可能只是包含一些信息而已,而不需要执行。<jsp:include>能够同时处理这两种文件,因此你就不需要包含时还要判断此文件是动态的还是静态的。如果这个包含文件是动态的,那么你还可以用<jsp:param>还传递参数名和参数值。

JSPinclude指令和include动作区别

<%@ include file=***.jsp%>  是把整个外部文件加载进来,把整个外部文件和原文件转化成一个servlet

<jsp:include page=***.jsp” flush=true/>  include动作元素引入页面时,实际只是引用了***.jsp这个文件被转化并被编译后产生的servlet类文件。既如此,***.jsp就是作为一个单独的文件在执行后才被test.jsp文件运行时调用。

jsp内置对象

定义:可以不加声明就在JSP页面脚本(Java程序片和Java表达式)中使用的成员变量   JSP共有以下9种基本内置组件(可与ASP6种内部组件相对应):

内置对象

代表内容

范围

request

触发服务调用的请求

request

response

对请求的应答

page

session

为请求的客户创建的session对象

session

application

从 servlet配置对象获得的 servlet上下文(如在getServletConfig()getContext()的调用中)

application

out

向输出流写入内容的对象

page

pageContext

本 JSP的页面上下文

page

page

实现处理本页当前请求的类的实例

page

config

本 JSP的 ServletConfig

page

exception

表示JSP页面运行时产生的异常

Page

requestresponse

Request对象代表来自客户端的请求。使用较多的方法有getParametergetParameterNamesgetParameterValues,通过调用这几个方法来获取请求对象中所包含的参数的值。

Response对象代表对客户端的响应。由于比较底层不建议使用。发送文字时直接使用out对象。

pageContext

为上下文对象,代表当前页面运行的一些属性。常用方法有findAttributegetAttributegetAttributesScope。较少使用此对象。

Session

Session对象非常重要,代表服务器与客户端所建立的对话,当需要在不同页面保留客户信息的情况下使用。如在线购物,客户轨迹跟踪等。

概要:

— HTTP是无状态协议。

— Web Server 对每个客户端请求都没有历史记忆。

— Session用来保护客户端信息。

Cookie

Cookie包含一对键值对。下面代码生成一个Cookie并写入用户硬盘。

Cookie myCookie = new Cookie("key","value");

response.addCookie(myCookie );

ServletJSP的比较

有许多相似之处,可以生成动态网页。

JSP的优点是善于网页制作,生成动态页面比较直观。JSP的缺点是不容易跟踪和排错。

Servlet是纯Java语言,擅长处理流程和业务逻辑。Servlet缺点是生成动态网页不直观。

Servlet请求转发与重定向

request.setAttribute("test","hello");

request.getRequestDispatcher("/test.jsp").forward(request,response);这个方法为请求转发,可以传送test属性。

response.sendRedirect("/test.jsp");这个方法为重定向,不能传送test属性,说明不共享用一个request

请求转发和重定向原理图:

 

使用Session

跟踪客户状态

— Web服务器跟踪客户状态通常有四种方法

— 建立含有跟踪数据的隐藏字段

— 重写包含额外参数的URL

— 使用持续的COOKIE

— 使用Servlet API中的Session(会话)机制

隐藏字段

— <inputtype="hidden"name="name"value="value" >此代码不会显示在页面上。

使用Session会话机制

— Session用于跟踪客户状态。Session指的是在一段时间内,单个客户与web服务器的一串相关的交互过程。在一个Session中用户可能会多次请求访问同一个网页,也有可能请求访问不同的服务器资源。

— 当一个Session开始时,Servlet容器创建一个HttpSession对象,在此对象中可以存放用户信息。

— Servlet容易为HttpSession分配一个唯一的标识符,称为Session IDServlet容易把标识符作为COOKIE保存在客户浏览器中。

— 每次客户发送HTTP请求,Servlet容器可以从HttpServletRequest对象中读取Session ID,然后根据Session ID找到相应的HttpSession对象,从而获取用户的状态信息。

Session生命周期

— 当用户第一次访问一个支持Sessionweb应用的时候,将开始一个新的Session

— 在这个用户浏览这个web应用不同的网页的时候,一直处于同一个Session中。

— 默认情况下,JSP都是支持Session的,也可以通过以下语句显示声明Session<%@ page session="true"%>

— 结束Session生命周期:1Session过期。2、服务端调用HttpSessioninvalidate()方法。3、关闭浏览器。

关闭浏览器Session真的就消失了吗?

— HttpSession会把Session ID保存在COOKIE中。

— 这个COOKIE不同于普通的COOKIECOOKIE有两种类型,一个是我们通常理解的存放在客户端硬盘上的COOKIE,这里的类型是会话Session,实际是存储在浏览器进程的内存当中的,所以关闭浏览器也就意味着浏览器进程的内存得到释放,从而COOKIE消失。

— 对于服务器端,我们需要设置Session的最大存活时间,使用户没有在一段时间和服务器交互,Session会自动失效,我们使用HttpSessionsetMaxInactiveInterval()方法来设置时间,此时间以秒为单位。不然服务器永不关闭,会无端的消耗服务器的内存资源。

Servlet监听器

观察者模式:观察者模式(Observer)完美的将观察者和被观察的对象分离开。举个例子,用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数据 的变化,发现数据变化后,就显示在界面上。面向对象设计的一个原则是:系统中的每个类将重点放在某一个功能上,而不是其他方面。一个对象只做一件事情,并 且将他做好。观察者模式在模块之间划定了清晰的界限,提高了应用程序的可维护性和重用性。

监听器就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法将立即被执行。

Servlet规范中定义了多种类型的监听器,它们用于监听的事件源分别为 ServletContext, HttpSession 和 ServletRequest 这三个域对象。

Servlet规范针对这三个对象上的操作,又把这多种类型的监听器划分为三种类型。

— 监听三个域对象创建和销毁的事件监听器

— 监听域对象中属性的增加和删除的事件监听器

— 监听绑定到 HttpSession 域中的某个对象的状态的事件监听器。(查看API文档)

编写和配置监听器

— 和编写其它事件监听器一样,编写servlet监听器也需要实现一个特定的接口,并针对相应动作覆盖接口中的相应方法。

— 和其它事件监听器略有不同的是,servlet监听器的注册不是直接注册在事件源上,而是由WEB容器负责注册,开发人员只需在web.xml文件中使用<listener>标签配置好监听器,web容器就会自动把监听器注册到事件源中。

— 一个 web.xml 文件中可以配置多个 Servlet 事件监听器,web 服务器按照它们在 web.xml 文件中的注册顺序来加载和注册这些 Serlvet 事件监听器。

监听servletContext域对象创建和销毁

— ServletContextListener 接口用于监听 ServletContext 对象的创建和销毁事件。

— 当 ServletContext 对象被创建时,激发contextInitialized (ServletContextEvent sce)方法

— 当 ServletContext 对象被销毁时,激发contextDestroyed(ServletContextEvent sce)方法。

— 提问,servletContext域对象何时创建和销毁:

创建:服务器启动针对每一个web应用创建servletContext

销毁:服务器关闭前先关闭代表每一个web应用的servletContext

监听HttpSession域对象创建和销毁

— HttpSessionListener接口用于监听HttpSession的创建和销毁

— 创建一个Session时,sessionCreated(HttpSessionEvent se) 方法将会被调用。

— 销毁一个Session时,sessionDestroyed (HttpSessionEvent se) 方法将会被调用。

— Session域对象创建和销毁的时机

创建:用户每一次访问时,服务器创建session

销毁:如果用户的session 30分钟没有使用,服务器就会销毁session,我们在web.xml里面也可以配置session失效时间

监听HttpRequest域对象创建和销毁

— ServletRequestListener 接口用于监听ServletRequest 对象的创建和销毁。

— Request 对象被创建时,监听器的requestInitialized方法将会被调用。

— Request对象被销毁时,监听器的requestDestroyed方法将会被调用。

— servletRequest域对象创建和销毁的时机:

创建:用户每一次访问,都会创建一个reqeust

销毁:当前访问结束,request对象就会销毁

监听三个域对象属性变化

— Servlet规范定义了监听 ServletContext, HttpSession, HttpServletRequest 这三个对象中的属性变更信息事件的监听器。

— 这三个监听器接口分别是ServletContextAttributeListener, HttpSessionAttributeListener ServletRequestAttributeListener

— 这三个接口中都定义了三个方法来处理被监听对象中的属性的增加,删除和替换的事件,同一个事件在这三个接口中对应的方法名称完全相同,只是接受的参数类型不同。 

— attributeAdded 方法

— attributeRemoved 方法

— attributeReplaced 方法

自定义标签库开发

编写一个实现Tag接口的Java类,并覆盖doStartTag方法,把jsp页面中的java代码写到doStartTag方法中。

编写标签库描述符(tld)文件,在tld文件中对自定义标签进行描述。

完成以上操作,即可在JSP页面中导入和使用自定义标签。

最重要的两个方法:public int doStartTag()public int doEndTag()

Servlet Filter

Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter。通过Filter技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截,如下所示:

 

Filter开发分为二个步骤:

— 编写java类实现Filter接口,并实现其doFilter方法。

— 在 web.xml 文件中使用<filter><filter-mapping>元素对编写的filter类进行注册,并设置它所能拦截的资源。(动手实验)

Filter

— 在一个web应用中,可以开发编写多个Filter,这些Filter组合起来称之为一个Filter链。

— web服务器根据Filterweb.xml文件中的注册顺序,决定先调用哪个Filter,当第一个FilterdoFilter方法被调用时,web服务器会创建一个代表Filter链的FilterChain对象传递给该方法。在doFilter方法中,开发人员如果调用了FilterChain对象的doFilter方法,则web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第2filter,如果没有,则调用目标资源。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多