kl800.com省心范文网

基于JAVA的WEB应用开发实训教程


基于JAVA 的WEB 应用开发实训教程

?????? ?? ? ?

第一章

WEB 应用体系架构简介

基于 Java 技术的 Web 应用开发 Web 应用体系架构基本知识 1 2 3 4 Web 应用的 B/S 结构编程模式
HTTP 协议请求相应模式

1 1 1 1 1

5 5 5 5 5

Web 应用程序的发展 Web 应用程序中的服务器端技术

??????WEB 应用模型: 基于 B/S 结构:浏览器—服务器 (WEB 服务器+WEB 应用服务器) IBM HTTP SERVER,MS IIS, APACHE IBM WEBSPHERE APPLICATION SERVER ??????HTTP 请求/响应模型: 请求消息和响应消息 一个完整的 HTTP 会话过程: 1)客户端和 WEB 服务器建立连接,通过默认 8080 端口。2)连接后,客户端向服务器发 送 HTTP 请求消息,WEB 服务器处理请求消息,并将响应消息送给客户端,3)连接关闭 HTTP 是一个无状态的协议:客户端访问WEB 服务器上某个 WEB 页面都要建立独立的连 接,服务器不保留前一次访问的信息。服务器不保留客户机的状态信息。所以服务器需要采 取一定措施保留用户状态数据。 ??????HTTP 消息格式: 三个部分:起始行,题头域,一个空行后的消息体 POST /certify HTTP/1.1 POST 方法, HTTP 版本号 Host:172.23.77.94 主机地 址 Content-Type: text/xml 消息内容的类型 Content-Length:16 消息内容的长度 Hello,IBM World 消息体

1) 起始行:包含 HTTP 方法(GET,POST),URI,HTTP 版本号 例如:GET /default.html HTTP/1.0 无效的 URI 请求返回错误代码(404),如是指向生成数据的资源,servlet,数据在响 应消息中返回。递交表单用 POST 方法,GET 方法向服务器请求资源由 URI 指示请求地址 2)HTTP 消息---题头域 名称 目的 举例 Accept 可接受的媒体类型 Accept:image/gif 如没有,则假设客户端可接 Accept:image/jpeg 受所有的媒体 Accept-Language 客户端希望响应优先使用的 Accept-Language:en-us 语言 发送到接受者的消息题的媒 Content-type:text/html Content-type 介类型

1

基于JAVA 的WEB 应用开发实训教程

Host User-Agent ??????HTTP 响应消 息

所请求资源的主机名称和端 口号 包含发出请求消息的客户端 的信息

User-Agent:Mozilla/4.0

包含状态行+0个或多个题头域 版本号, 响应状态码,成功响应 HTTP/1.1 200 OK Content-Type:text/plain Content-Length;25 Welcome to the IBM World! 常见的HTTP 响应状态码: 200 OK 请求成功 400 不良请求 由于语法错误而导致服务器无法理解请求信息 401 未授权 请求要求身份验证和或授权 404 为发现 服务器未发现与请求 URI 匹配的内容 500 内部服务器错误 服务器出错,无法处理请求 ??????WEB 应用程序发展—静态 Client server Web browser HTTP request WEB SERVER HTTP Response ??????WEB 应用程序发展---Applet Client WEB Browser With JVM HTTP Response File System ??????WEB 应用程序发展--Servlet Client Web Browser Requests for static resource Requests for dynamic resource HTTP Response Web Server Web Container File System
2

File System

network

server HTTP Request WEB Server

server HTTP Request Web Server Plugin

基于JAVA 的WEB 应用开发实训教程

Servlet 是运行在服务器上的WEB Container 中的,WEB 容器,WEB 应用服务器提供WEB Container,用于管理 Servlet 这样的服务器端组件。 带来问题: Servlet 会把业务逻辑和显示逻辑混合在一起 ??????WEB 应用程序发展---JSP Web Container service(req, res) method() Servlet JavaBean forward(req,res) Reponse RequestDispatcher methods() Service(req,res) Java Server Page JSP 实现更好的MVC 结构,分离视图、控制和业务逻辑 JSP 页面显示给用户的数据,Servlet 控制页面的流程,JSP 和 Servlet 调用 JavaBean ??????WEB 应用程序发展---EJB Web HTTP Web Browser Server Container EJB Container Java Application EJB 是 Enterprise JavaBean,提供了对业务逻辑封装。JavaBean 可以通过WebContainer 来访 问 EJB,JAVA 应用程序客户端也可以访问 EJB。 ??????Web 应用程序中的服务器端技术---ASP VBScript 代码被 ASP 引擎解释执行 ??????Web 应用程序中的服务器端技术—ASP.NET 页面表现与代码分离,能使用多种语言,VB.NET 和 C#,ASP.NET 程序是编译 ??????Web 应用程序中的服务器端技术执行--JSP 使用JAVA 语言,在 HTML 代码中混合程序代码,由语言引擎执行程序代码 JSP 被编译成 Servlet 并有 JAVA 虚拟机执行,这种编译操作仅在对 JSP 页面的第一次请求时 发生。 Request

3

基于JAVA 的WEB 应用开发实训教程

第二章 J2EE 简介

2 2 2 2 2 2 2 2 2 1 2 3 4 5 6 7 1

J2EE 架构模式 J2EE 构建企业级应用
MVC 设计模式

5 9 9 5 5 5 5 9 9

J2EE Blueprints J2EE 的组件和容器 J2EE 的标准服务 J2EE 的特性和优势 J2EE 打包与部署 J2EE 构建企业级应用

目的在于克服C/S 架构的弊端,采纳 B/S 架构来构建应用 J2EE 为 JAVA 技术开发服务器端应用提供了一个平台独立的,可移植的,多用户的,安全 的和基于标准的企业级平台,从而简化了企业应用的开发、部署和管理。 企业级应用:指那些为商业组织、大型企业而创建并部署的解决方案和应用。 企业级应用特点及需求: 结构复杂,涉及外部资源多,事务密集,数据量大,用户数多, 安全性高。 需求:高可用性、安全性、可依赖性和可扩展性。 9 2 2 MVC 设计模式 Model 模型, View 视图 , Controller 控制器 Model 提供应用业务逻辑,指对业务数据、信息的处理模块,包括对业务数据的存取、加工、 综合等。 View 指用户界面:用户与程序交互的接口,用户可以通过View 输入信息,另一方面程序通 过 View 将数据结果以某种形式显示给用户。 Controller 负责view 和 model 之间的流程控制。 MVC 的优势: 三层分离有利于项目小组按小组成员各自的擅长进行分工 控制部分代码相对稳定,业务逻辑跟随商业流程的变化而变化,视图模块根据用户需求更改 而更改,有利于代码修改过程中进行模块的分离。 在 J2EE 中,EJB 提供应用业务逻辑,实现 Model,HTML,JSP 实现用户界面,VIEW。Servlet 实现控制器。 J2EE Blueprints(J2EE 应用设计模型)体系模型 是开发人员设计和优化 J2EE 组件的基本原则,同时为围绕开发工作进行职能分工给出了指导性策 略,以帮助应用开发人员合理地分配技术资源。 J2EE 是 JAVA 技术构建多层次企业级应用的一系列标准。不是现成的产品,各平台开发商 按照J2EE 规范分别开发了不同的J2EE 应用服务器,以及开发J2EE 企业级应用的IDE 工具。 ???IBM 的J2EE 产品 IBM 的 J2EE 应用服务器就是 WAS(WebSphere Application Server)4.0 版本符合 J2EE1.2 规 范,5.0 版本符合 J2EE1.3 规范。 开发 J2EE 企业级应用的工具就是 WSAD(Websphere Studio Application Developer),5.0
4

基于JAVA 的WEB 应用开发实训教程

版本

J2EE 容器包括: ◆ Web 容器 服务器端容器,包括两种组件JSP 和 Servlet,JSP 和 Servlet 都是 Web 服务器 的功能扩展,接受 Web 请求,返回动态的 Web 页面。Web 容器中的组件可使用 EJB 容器中 的组件完成复杂的商务逻辑。 ◆ EJB 容器 服务器端容器,包含的组件为 EJB(Enterprise JavaBeans),它是 J2EE 的核心之
5

基于JAVA 的WEB 应用开发实训教程

一,主要用于服务器端的商业逻辑的实现。EJB 规范定义了一个开发和部署分布式商业逻辑 的框架,以简化企业级应用的开发,使其较容易地具备可伸缩性、可移植性、分布式事务处 理、多用户和安全性等。 ◆ Applet 容器 客户端容器,包含的组件为 Applet。Applet 是嵌在浏览器中的一种轻量级客 户端,一般而言,仅当使用 Web 页面无法充分地表现数据或应用界面的时候,才使用它。 Applet 是一种替代Web 页面的手段,我们仅能够使用J2SE 开发Applet,Applet 无法使用J2EE 的各种Service 和 API,这是为了安全性的考虑。 ◆ Application Client 容器 客户端容器,包含的组件为 Application Client。Application Client 相对 Applet 而言是一种较重量级的客户端,它能够使用 J2EE 的大多数 Service 和 API。 通过这四个容器,J2EE 能够灵活地实现前面描述的企业级应用的架构。 在 View 部分,J2EE 提供了三种手段:Web 容器中的JSP(或 Servlet)、Applet 和 Application Client,分别能够实现面向浏览器的数据表现和面向桌面应用的数据表现。Web 容器中的 Servlet 是实现 Controller 部分业务流程控制的主要手段;而EJB 则主要针对 Model 部分的业 务逻辑实现。至于与各种企业资源和企业级应用相连接,则是依靠J2EE 的各种服务和 API。 在 J2EE 的各种服务和 API 中,JDBC 和 JCA 用于企业资源(各种企业信息系统和数据库等) 的连接,JAX-RPC、JAXR 和SAAJ 则是实现 Web Services 和 Web Services 连接的基本支持。 J2EE 的各种组件 我们就 J2EE 的各种组件、服务和 API,进行更加详细的阐述,看看在开发不同类型的企业 级应用时,根据各自需求和目标的不同,应当如何灵活使用并组合不同的组件和服务。 · Servlet Servlet 是 Java 平台上的 CGI 技术。Servlet 在服务器端运行,动态地生成 Web 页面。与传统 的 CGI 和许多其它类似 CGI 的技术相比,Java Servlet 具有更高的效率并更容易使用。对于 Servlet,重复的请求不会导致同一程序的多次转载,它是依靠线程的方式来支持并发访问的。 · JSP JSP(Java Server Page)是一种实现普通静态 HTML 和动态页面输出混合编码的技术。从这一 点来看,非常类似 Microsoft ASP、PHP 等技术。借助形式上的内容和外观表现的分离,Web 页面制作的任务可以比较方便地划分给页面设计人员和程序员,并方便地通过 JSP 来合成。 在运行时态,JSP 将会被首先转换成 Servlet,并以 Servlet 的形态编译运行,因此它的效率 和功能与 Servlet 相比没有差别,一样具有很高的效率。 · EJB EJB 定义了一组可重用的组件:Enterprise Beans。开发人员可以利用这些组件,像搭积木一 样建立分布式应用。在装配组件时,所有的 Enterprise Beans 都需要配置到 EJB 服务器(一般 的 Weblogic、WebSphere 等J2EE 应用服务器都是 EJB 服务器)中。EJB 服务器作为容器和低 层平台的桥梁管理着 EJB 容器,并向该容器提供访问系统服务的能力。所有的 EJB 实例都 运行在 EJB 容器中。EJB 容器提供了系统级的服务,控制了 EJB 的生命周期。EJB 容器为 它的开发人员代管了诸如安全性、远程连接、生命周期管理及事务管理等技术环节,简化了 商业逻辑的开发。EJB 中定义了三种 Enterprise Beans: ◆ Session Beans ◆ Entity Beans ◆ Message-driven Beans · JDBC JDBC(Java Database Connectivity,Java 数据库连接)API 是一个标准 SQL(Structured Query Language,结构化查询语言)数据库访问接口,它使数据库开发人员能够用标准 Java API 编 写数据库应用程序。JDBC API 主要用来连接数据库和直接调用 SQL 命令执行各种 SQL 语
6

基于JAVA 的WEB 应用开发实训教程

句。利用JDBC API 可以执行一般的 SQL 语句、动态 SQL 语句及带 IN 和 OUT 参数的存储 过程。Java 中的 JDBC 相当与 Microsoft 平台中的ODBC(Open Database Connectivity)。 · JMS JMS(Java Message Service,Java 消息服务)是一组Java 应用接口,它提供创建、发送、接收、 读取消息的服务。JMS API 定义了一组公共的应用程序接口和相应语法,使得 Java 应用能 够和各种消息中间件进行通信,这些消息中间件包括 IBM MQ-Series、Microsoft MSMQ 及 纯 Java 的SonicMQ。通过使用 JMS API,开发人员无需掌握不同消息产品的使用方法,也 可以使用统一的 JMS API 来操纵各种消息中间件。通过使用 JMS,能够最大限度地提升消 息应用的可移植性。 JMS 既支持点对点的消息通信,也支持发布/订阅式的消息通信。 · JNDI 由于J2EE 应用程序组件一般分布在不同的机器上,所以需要一种机制以便于组件客户使用 者查找和引用组件及资源。在 J2EE 体系中,使用JNDI(Java Naming and Directory Interface) 定位各种对象,这些对象包括 EJB、数据库驱动、JDBC 数据源及消息连接等。JNDI API 为 应用程序提供了一个统一的接口来完成标准的目录操作,如通过对象属性来查找和定位该对 象。由于 JNDI 是独立于目录协议的,应用还可以使用 JNDI 访问各种特定的目录服务,如 LDAP、NDS 和 DNS 等。 · JTA JTA(Java Transaction API)提供了J2EE 中处理事务的标准接口,它支持事务的开始、回滚和 提交。同时在一般的J2EE 平台上,总提供一个 JTS(Java Transaction Service)作为标准的事务 处理服务,开发人员可以使用 JTA 来使用 JTS。 · JCA JCA(J2EE Connector Architecture)是 J2EE 体系架构的一部分,为开发人员提供了一套连接各 种企业信息系统(EIS,包括 ERP、SCM、CRM 等)的体系架构,对于EIS 开发商而言,它们 只需要开发一套基于 JCA 的 EIS 连接适配器,开发人员就能够在任何的 J2EE 应用服务器中 连接并使用它。基于 JCA 的连接适配器的实现,需要涉及 J2EE 中的事务管理、安全管理及 连接管理等服务组件。 · JMX JMX(Java Management Extensions)的前身是 JMAPI。JMX 致力于解决分布式系统管理的问 题。JMX 是一种应用编程接口、可扩展对象和方法的集合体,可以跨越各种异构操作系统 平台、系统体系结构和网络传输协议,开发无缝集成的面向系统、网络和服务的管理应用。 JMX 是一个完整的网络管理应用程序开发环境,它同时提供了厂商需要收集的完整的特性 清单、可生成资源清单表格、图形化的用户接口;访问 SNMP 的网络 API;主机间远程过 程调用;数据库访问方法等。 · JAAS JAAS(Java Authentication and Authorization Service)实现了一个 Java 版本的标准 Pluggable Authentication Module(PAM)的框架。JAAS 可用来进行用户身份的鉴定,从而能够可靠并安 全地确定谁在执行 Java 代码。同时 JAAS 还能通过对用户进行授权,实现基于用户的访问 控制。 · JACC JACC(Java Authorization Service Provider Contract for Containers)在 J2EE 应用服务器和特定 的授权认证服务器之间定义了一个连接的协约,以便将各种授权认证服务器插入到J2EE 产 品中去。 · JAX-RPC 通过使用 JAX-RPC(Java API for XML-based RPC),已有的 Java 类或Java 应用都能够被重新
7

基于JAVA 的WEB 应用开发实训教程

包装,并以 Web Services 的形式发布。JAX-RPC 提供了将 RPC 参数(in/out)编码和解码的 API,使开发人员可以方便地使用 SOAP 消息来完成 RPC 调用。同样,对于那些使用 EJB(Enterprise JavaBeans)的商业应用而言,同样可以使用 JAX-RPC 来包装成 Web 服务,而 这个Web Servoce 的WSDL 界面是与原先的EJB 的方法是对应一致的。JAX-RPC 为用户包 装了 Web 服务的部署和实现,对 Web 服务的开发人员而言,SOAP/WSDL 变得透明,这有 利于加速 Web 服务的开发周期。 · JAXR JAXR(Java API for XML Registries)提供了与多种类型注册服务进行交互的 API。JAXR 运 行客户端访问与JAXR 规范相兼容的 Web Servcices,这里的 Web Services 即为注册服务。 Pluggable Provider、Registry-specific JAXR Provider、JAXR Bridge Provider(支持 UDDI Registry 和 ebXML Registry/Repository 等)。 · SAAJ SAAJ(SOAP with Attachemnts API for Java)是JAX-RPC 的一个增强,为进行低层次的 SOAP 消息操纵提供了支持。 J2EE 的组件和容器 ????J2EE 的三层模型:
?运行在客户端机器上的客户层组件(Client Tier) ?运行在 J2EE 服务器上的 Web 层组件(Web Tier) ?运行在 J2EE 服务器上的业务逻辑层组件(Business Tier) ?运行在 EIS 服务器上的企业信息系统(Enterprise information system)层软件(EIS Tier)

客户层组件 J2EE 应用程序可以是基于 web 方式的,也可以是基于传统方式的。 web 层组件 J2EE web 层组件可以是JSP 页面或 Servlets。按照J2EE 规范,静态的HTML 页面和Applets 不算是 web 层组件。 业务层组件
8

基于JAVA 的WEB 应用开发实训教程

业务层代码的逻辑用来满足银行,零售,金融等特殊商务领域的需要,由运行在业务层上 的 enterprise bean 进行处理 企业信息系统层 (EIS Tier) 企业信息系统层处理企业信息系统软件包括企业基础建设系统例如企业资源计划(ERP),大 型机事务处理,数据库系统,和其它已有信息系统。 基于组件,具有平台无关性的 J2EE 结构使得 J2EE 程序的编写十分简单,因为业务逻辑被 封装成可复用的组件,并且 J2EE 服务器以容器的形式为所有的组件类型提供后台服务。因 为不用自己开发这种服务,所以可以集中精力解决手头的业务问题。 J2EE 容器设置定制了 J2EE 服务器所提供的内在支持,包括安全,事务管理, JNDI(Java Naming and Directory Interface)寻址,远程连接等服务。

EJB 容器管理所有 J2EE 应用程序中企业级 bean

的执行。enterprise bean 和它们的容器

运行在 J2EE 服务器上。 Web 容器管理所有 J2EE 应用程序中 JSP 页面和 Servlet 组件的执行。Web 组件和它们的容 器运行在 J2EE 服务器上。 应用程序客户端容器管理所有 J2EE 应用程序中应用程序客户端组件的执行。应用程序客户 端和它们的容器运行在 J2EE 服务器上。 Applet 容器是运行在客户端机器上的 web 浏览器和 Java 插件的结合。 ????J2EE 的标准服务 1. JDBC(Java Database Connectivity): JDBC API 为访问不同的数据库提供了一种统一的途径,象 ODBC 一样,JDBC 对开发者屏蔽了 一些细节问题,另外,JDCB 对数据库的访问也具有平台无关性。 2. JNDI(Java Name and Directory Interface): JNDI API 被用于执行名字和目录服务。它提供了一致的模型来存取和操作企业级的资源如 DNS 和 LDAP,本地文件系统,或应用服务器中的对象。 3. EJB(Enterprise JavaBean): J2EE 技术之所以赢得某体广泛重视的原因之一就是 EJB。它们提供了一个框架来开发和实施
9

基于JAVA 的WEB 应用开发实训教程

分布式商务逻辑,由此很显著地简化了具有可伸缩性和高度复杂的企业级应用的开发。EJB 规范定义了 EJB 组件在何时如何与它们的容器进行交互作用。容器负责提供公用的服务,例 如目录服务、事务管理、安全性、资源缓冲池以及容错性。但这里值得注意的是,EJB 并不 是实现 J2EE 的唯一途径。正是由于 J2EE 的开放性,使得有的厂商能够以一种和 EJB 平行的 方式来达到同样的目的。 4. RMI(Remote Method Invoke): 正如其名字所表示的那样,RMI 协议调用远程对象上方法。它使用了序列化方式在客户端和 服务器端传递数据。RMI 是一种被 EJB 使用的更底层的协议。 5. Java IDL/CORBA: 在 Java IDL 的支持下,开发人员可以将 Java 和 CORBA 集成在一起。他们可以创建 Java 对 象并使之可在 CORBA ORB 中展开,或者他们还可以创建 Java 类并作为和其它 ORB 一起展开 的 CORBA 对象的客户。后一种方法提供了另外一种途径,通过它 Java 可以被用于将你的新 的应用和旧的系统相集成。 6. JSP(Java Server Pages) : JSP 页面由 HTML 代码和嵌入其中的 Java 代码所组成。服务器在页面被客户端所请求以后对 这些 Java 代码进行处理,然后将生成的 HTML 页面返回给客户端的浏览器。 7. Java Servlet : Servlet 是一种小型的 Java 程序,它扩展了 Web 服务器的功能。作为一种服务器端的 应用,当被请求时开始执行,这和 CGI Perl 脚本很相似。Servlet 提供的功能大多与 JSP 类似,不过实现的方式不同。JSP 通常是大多数 HTML 代码中嵌入少量的 Java 代码,而 servlets 全部由 Java 写成并且生成 HTML。 8. XML(Extensible Markup Language): XML 是一种可以用来定义其它标记语言的语言。它被用来在不同的商务过程中共享数据。XML 的发展和 Java 是相互独立的,但是,它和 Java 具有的相同目标—平台独立性。通过将 Java 和 XML 的组合,您可以得到一个完美的具有平台独立性的解决方案。 9. JMS(Java Message Service): JMS 是用于和面向消息的中间件相互通信的应用程序接口(API)。它既支持点对点的域,有 支持发布/订阅(publish/subscribe)类型的域,并且提供对下列类型的支持:经认可的消息 传递,事务型消息的传递,一致性消息和具有持久性的订阅者支持。JMS 还提供了另一种方 式来对您的应用与旧的后台系统相集成。 10. JTA(Java Transaction Architecture): JTA 定义了一种标准的 API,应用系统由此可以访问各种事务监控。 11. JTS(Java Transaction Service): JTS 是 CORBA OTS 事务监控的基本的实现。JTS 规定了事务管理器的实现方式。该事务管理 器是在高层支持 Java Transaction API (JTA)规范,并且在较底层实现 OMG OTS specification 的 Java 映像。JTS 事务管理器为应用服务器、资源管理器、独立的 应用以及通信资源管理器提供了事务服务。 12. JavaMail: JavaMail 是用于存取邮件服务器的 API,它提供了一套邮件服务器的抽象类。不仅支持 SMTP 服务器,也支持 IMAP 服务器。 13. JAF(JavaBeans Activation Framework): JavaMail 利用 JAF 来处理 MIME 编码的邮件附件。MIME 的字节流可以被转换成 Java 对象, 或者转换自 Java 对象。大多数应用都可以不需要直接使用 JAF。 J2EE 的特性和优势
10

基于JAVA 的WEB 应用开发实训教程

JAVA 平台有三个版本:

J2ME(JAVA 2 PLATFORM MICRO EDITION)小型设备和智能卡 J2SE(JAVA 2 PLATFORM STANDARD EDITION)桌面系统 J2EE(JAVA 2 PALTFORM ENTERPRISE EDITION)企业级应用 J2EE 的优势: 提供了标准的服务、组件、客户端和工具。 组件模型:实现了 MVC 设计模式 提供了很强的可扩展性、可伸缩性。 J2EE 打包与部署 UNIT 3 基于 Servlet 和 JSP 的 Web 应用 Servlet 的基本知识 Servlet 的任务 Servlet 的局限性 静态动态网页制作 JSP 的基本知识 JSP 转换为 Servlet JSP 与 Servlet 的用途 Servlet 的基本知识 1. 什么是 Java Servlet? Servlet 是一个标准的服务器端的 java 应用程序,可以生成动态的 Web 页面。 Servlet 由 Web 服务器进行加载,这个服务器必须包含支持 servlet 的虚拟机。Servlet 也 是服务器组件,它被装载到 web 服务器或应用服务器的 java 虚拟机内运行。 Servlet 属于 WEB 层,运行在 WEB CONTAINER 中. Servlet 具有平台无关性。 2. Servlet 的任务 1) 读取客户端发送的所有数据:数据通常是在 WEB 页面的表单中输入的 2) 读取浏览器发送的 HTTP 请求数据:包括浏览器功能,Cookie,请求的客户端的主 机名 3) 生成结果:需要与数据库通信、调用 RMI 或 CORBA 4) 在文档内设置结果的格式:将信息嵌入到 HTML 中 5) 设置合适的 HTTP 响应参数:告诉浏等览器返回的文档类型,设置 Cookie 6) 将文档返回到客户端:以 HTML 等发送到客户端 简单 Servlet 示例: package simple.servlet; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class FirstSimpleServlet extends HttpServlet { protected void service(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{ response.setContentType("text/html");
11

基于JAVA 的WEB 应用开发实训教程

PrintWriter out=response.getWriter(); out.println("<HTML><TITLE>First servlet</TITLE><BODY>"); out.println("<H2>This is your first servlet.</H2><HR>"); out.println("</BODY></HTML>"); } } Servlet 局限性: 1. 很难对 HTML 做出修改,每次修改必须重新编译 Servlet 2. HTML 是硬编码,维护不同的语言很困难。 3. HTML 嵌入在 Servlet 中,存在职责问题。WEB 设计人员构建 HTML 页面,不熟悉 JAVA 编 程,混合使用 HTML 和 JAVA 代码,很难分清页面设计和编程的职责。 静态动态页面制作 静态的 WEB 页面意味着简单的组织结构:有时需要根据客户端的请求生成单独的不同的页 面。 需要产生动态页面的情况: 该 WEB 页面基于客户端提交的数据 从经常变换的数据得出 WEB 页面 该 WEB 页面使用来自公司数据库或其他服务器端资源的信息。 JSP 的基本知识 什么是 JSP Java Server Page。用来开发含有动态内容的网页的技术。 JSP 规范是由 SUN MICROSYSTEM 公司倡导饿。编写一次,随处运行 扩展名:.jsp 示例:
<HTML> <BODY>

<% out.println(“<H1> Hello world!</H1>”);
%> </BODY> </HTML>

JSP 转换为 Servlet
Jsp 容器将 JSP 文件转换为 java.class 文件

HelloWorld.jsp

JSP 页面请求 浏览器

Servlet 容器 器

JSP 容 HelloWorld.class

HelloWorld.java

JSP 是 JAVA Servlet 技术的自然发展。JSP 页面的处理过程是先将 JSP 页面编译预处理成 Java servlet 后,再执行生成 Servlet 并产生结果的。 .jsp 经预处理后转换为.java,编译器编译源代码,并生成可由 Servlet 容器执行的 class 文件。 <body> This is my JSP page. <br>
12

基于JAVA 的WEB 应用开发实训教程

<%=new java.util.Date() %> </body> JSP 与 Servlet 的用途 什么时候使用 Servlet?什么使用 JSP Servlet 可以返回HTML 页面用于显示,但在Servlet 中手动书写HTML 代码非常繁琐,Servlet 主要用于 WEB 应用程序的流程控制,验证用户输入合法性以及调用其他业务逻辑对象来访 问数据等,而JSP 主要用于页面显示。 运行环境设置 9 4

4 4

1 2

符合 JSP 规范的开发环境中的 Web 服务器 以 Tomcat 服务器为核心配置 JSP、Servlet 运行环境

9 9

1. 符合JSP 规范的开发环境中的 WEB 服务器 Apache Tomcat:目前版本 5.025,可以作为小型独立服务器,测试 Servlet 和 JSP,免费 Allaire Jrun: 作为 NetScape Enterprise 或FastTrack 服务器,IIS、Microsoft Personal WebServer 插件的一种 Servlet 和 JSP 引擎。 New Atalanta 的 ServletExec Gefion Software 的LiteWebServer(LWS) 2. 以 Tomcat 服务器为核心配置 JSP、Servlet 运行环境 设置安装环境步骤:下载并安装 Java 2 SDK1.4.2 下载并安装 Tomcat 5.0.25 设置端口号 设置环境变量 测试 Tomcat 安装 Tomcat 过程中,设置密码 admin Password: ******* 选择本机 JDK 路径 设置端口号:默认端口号 8080 Tomcat 的配置文件 server.xml,将端口号 8080 改为 80; Server.xml 位于 Tomcat 安装文件夹中的 conf 文件夹下,将 port 属性值改为 80。 <Connector port=”80” maxThreads=”150” ?? 配置环境变量: JAVA_HOME= C:\J2SDK1.4.2.05 CLASSPATH=.; %JAVAHOME%\lib PATH= %JAVA_HOME%\bin 测试服务器 执行 Tomcat 安装目录下的 bin 目录下的 startup.bat 文件 或直接在服务中开启 Apache Tomcat 服务; 测试 http://localhost:8080

13

基于JAVA 的WEB 应用开发实训教程

UNIT 5 简单 Web 应用的开发样例 Java Web 应用的目录结构 简单 HTML 和 JSP 页测试 Servlet 样例开发、编译、部署、测试 1. Java Web 应用的目录结构

简单WEB 应用的开发样例 9 9 9 9

WEB-INF/classes 目录放置 Servlet 类 WEB-INF/lib 目录放置 java Archive 文件 HTML 和图片等静态资源直接放在应用程序目录下或在应用程序目录下的任何子目录中。 用户不可以简单地放在浏览器的地址栏里输入 URL 来调用 WEB-INF 目录下的资源;

2.简单 HTML 和 JSP 页测试 把下列 Hello.html 文件放在 Tomcat 安装目录的下述文件夹下: 安装目录/webapps/root <HTML> <HEAD> <TITLE>myFirstHTML</TITLE> </HEAD> <BODY bgcolor=”#777777”> <H1> This is my first HTML</H1> Hello , java web world! </BODY> </HTML>
14

基于JAVA 的WEB 应用开发实训教程

启动服务器后,在地址栏总输入 http://localhost:8080/hello.html

简单JSP 测试: <html> <head> <title>My JSP 'index.jsp' starting page</title> </head> <body> This is my JSP page. <br> <%=new java.util.Date() %> </body> </html> 将 JSP 文件放置在安装目录/webapps/root 下 在浏览器地址栏输入 http://localhost:8080/Hello.jsp

3. 简单的servlet 样例—创建目录 我们编写的 servlet 文件放置在D:\myJavaWebApp 下 由于 servlet 和 jsp 不是JAVA 2 平台的组成部分,必须向编译程序指出servlet 类。服务器已 经知道 servlet 类,但用于开发的编译程序javac 不知道,因此如果不设置 CLASSPATH,试 图编译 Servlet、标记库或其他使用 Servlet API 的类将会失败,将 Servlet JAR 文件的位置添 加到你的开发CLASSPATH 中。 Servlet API 文 件 的 位 置 是 : C:\Program Files\Apache Software Foundation\Tomcat 5.0\common\lib\servlet-api.jar CLASSPATH= C:\Program Files\Apache Software Foundation\Tomcat 5.0\common\lib\servlet-api.jar;d:\myJavaWebApp 编辑 FirstSimpleServlet.java package simple.servlet; import java.io.*;
15

基于JAVA 的WEB 应用开发实训教程

import javax.servlet.*; import javax.servlet.http.*; public class FirstSimpleServlet extends HttpServlet { protected void service(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{ response.setContentType("text/html"); PrintWriter out=response.getWriter(); out.println("<HTML><TITLE>First servlet</TITLE><BODY>"); out.println("<H2>This is your first servlet.</H2><HR>"); out.println("</BODY></HTML>"); } } 编译 FirstSimpleServlet.java javac FirstSimpleServlet.java 生成 FirstSimpleServlet.class 文件 部署 servlet 复制 servlet 的 class 文件至 Tomcat 安装目录下/webapps/root/web-inf/classes 修改 web.xml,添加 servlet 的映射:web.xml 文件在安装目录/webapps/root/web-inf 文件夹中。 <web-apps> …… <servlet> <servlet-name> FirstSimpleServlet</servlet-name> <servlet-class>FirstSimpleServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name> FirstSimpleServlet</servlet-name> <url-pattern>/servlet/FirstSimpleServlet.html</url-pattern> </servlet-mapping> 测试 Servlet Http://localhost:8080/servlet/FirstSimpleServlet 运行时的类路径: 和 JSP 不同的是:Servlet 必须在 Servlet 引擎对应的类路径中 需要把所有的 Servlet 目录添加到系统类路径中去 大多数的 servlet 引擎都包含一个特殊的URL 用于/servlet 目录的映射,表示希望运行 servlet 的信号。 与 JSP 不同的是,servlet 不需要用文件后面的扩展名来指示文件的类型。 Servlet 的基本知识 9 Servlet 的应用 Servlet 相比于 CGI 的特性 Servlet 的处理流程 Servlet 容器 Servlet 的基本结构 1. 什么是 servlet? 标准的服务器端的 java 应用程序
16

9 9 9 9 9

基于JAVA 的WEB 应用开发实训教程

属于 WEB 层,运行在 WEB CONTAINER 中,它们在来自 WEB 浏览器或其他客户端的请 求与HTTP 服务器上的数据库或应用程序之间起一个中间层的作用。 2. Servlet 相比于 CGI 的特性 相似点:产生动态 WEB 内容方面,能响应来自 HTML 请求的用户事件,然后动态的创建 HTML 响应给用户。 比传统的 CGI 程序相比有以下优点: 可移植性和平台无关性。 持久性和性能上,传统 CGI 对于每个 HTTP 请求都要启动一个新进程。如果 CGI 本身相对 较短,执行进程所花时间短,而启动该进程的系统开销可能会占掉大部分执行时间。而 Servlet 只要被 WEB 服务器装载依次,就能被每个客户请求调用。Servlet 不会因每个请求 而产生一个多余的新的 servlet 实例。 Servlet 是用 JAVA 编写的,继承了 JAVA 语言所有优点。 易于编写,功能强大 与系统资源交互:调用文件、访问数据库、APPLET、JAVA 应用程序等 作为其他服务的客户端程序 servlet 可以被链接,一个 servlet 调用另一个 servlet 与协议和平台无关。 3.Servlet 的处理流程 Browser(client) web server 3.servlet 引擎调用 1.client 向 server 发出请求 2.server 将请求信息 servlet 的 service 方法 发给 servlet Application server Servlet 实例 5.server 将响应返回给 browser 4.Servlet 构建一个响应,并将其 传给 server

4.Servlet 容器
Servlet 是由 web 服务器中的 web container 管理的。Web 容器的角色是管理装载和初始化 servlet,处理服务请求,卸载或撤消 Servlet。 某一时刻在 web 容器中只有一个特定的 servlet 对象的实例,当 servlet 第一次装进运行环境, web 容器负责实现 servlet 的初始化,在 servlet 的整个生命周期内,servlet 在这里保持激活 状态或持久状态。 第一个客户对这个 servlet 的请求是通过在 servlet 的初始对象实例上创建一个新线程来处理 的。Web 容器负责创建每个处理请求的新线程。另外它还负责最后的卸载或重新安装 servlet。 1)web 容器装载 servlet1。初始化 servlet 的实例变量。并且在 servlet 生命周期内保持激活 状态也就是持久状态。两个客户浏览器请求了 servlet1 的服务。Web 容器为每个请求生成一 个新的线程。每个线程都能访问最初装载的实例变量,每个线程处理它自己的请求,并把响 应返回给请求客户。

JAVA Servlet API
Servlet 通过 API 来处理客户的请求。有两个包组成:javax.servlet 和 javax.servlet.http Javax.servlet 包中包含支持通用的独立于协议的 servlet 的类,servlet 能用于多种协议。 Javax.servlet.http 包扩展了上述基础包的功能,对 HTTP 协议提供了特别的支持。 Javax.servlet.Servlet 是一个接口类,它是 java Servlet API 的一个集中的抽象类,这个类定义 了 Servlet 必须实现的方法,比如处理请求的 service( )方法。 而 GenericService 类实现了 Servlet 这个接口,而它定义了一个通用的与协议无关的 Servlet.
17

基于JAVA 的WEB 应用开发实训教程

Javax.servlet.Servlet Javax.servlet.GenericServlet Javax.servlet.http.HttpServlet

5. Servlet 的基本结构
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class ServletTemplate extends HttpServlet{

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {
//use “ request” to read imcoming HTTP headers //e.g. cookies and query data from HTML forms. //use response to specify the HTTP response status //code and headers(e.g. the content type, cookies) PrintWriter out=response.getWriter(); //use “out” to send content to browser. } } 此 Servlet 处理 Get 请求,GET 请求是 Web 页面的一种常用的浏览器请求类型。当用户在地 址栏里输入 URL,访问一个 WEB 地址,或递交一个未指定 METHOD 的 HTML 表单,或 指定 METHOD=GET 的 HTML 表单时,浏览器将产生这种请求。Servlet 也可以处理 POST 请求,这是在 HTML 表单的 METHOD 指定为 POST 时。

生成纯文本的 Servlet
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class HelloWorld extends HttpServlet{

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {
PrintWriter out=response.getWriter(); Out.println(“Hello World”); } }

生成 HTML 的 Servlet
1. 设置HTTP 响应头信息内容类型为HTML 2. 修改 println 语句以建立合法的WEB 页面。 Response.setContentType(“text/html”);

Serlet 响应
Servlet 发送响应需要做两件事 1) 设置HTTP 响应头 2) 返回响应内容
18

基于JAVA 的WEB 应用开发实训教程

3) 注意,在用 PrintWriter 实际返回任何内容前必须设置响应头

ContentType
1) HTML(text/html) 2)GIF 图象(image/gif) 3) Excel 电子表格(application/vnd.ms-excel)

HttpServlet
Javax.servlet.http.HttpServlet 支持HTTP 协议 实现 HTTP 方法: doGet( )处理GET 请求(URL) doPost( )处理 POST 请求(HTML 表单) Request 和 Response doGet( ) 和 doPost( )方法的参数 1) HttpServletRequest 提供访问请求信息 2) HttpServletResponse 动态产生的响应 大多数 Servlet 读入一个请求,并产生一个动态的响应 Servlet 生命周期 1 2 3 4 5 Servlet 生命周期的定义 Init 的方法 Service 方法 SingleThreadModel 接口 Destroy 方法

9 9 5 5 5 5

1.Servlet 生命周期的定义 每个 Servlet 都有一个生命周期,定义了一个 Servlet 如何被加载和被初始化,怎样接受请求、 响应请求,怎样提供服务。Servlet 的生命周期从它被装入到 web 应用服务器的内存开始, 在终止或重新装入 Servlet 时结束。 所有的 java servlet 都必须直接或间接地实现这个接口 javax.servlet.Servlet,才能在 Servlet 引 擎 ( Web Container ) 中 运 行 。 Java.servlet.Servlet 接 口 定 义 了 一 些 方 法 , 如 init(),service(),destroy()方法。 创建 Servlet 实例-???调用 init( )方法初始化 等候处理请求,Servlet 处于“可用服务”状态, 每当有客户请求Servlet,web 容器创建一个新的 Servlet 线程,每个请求调用 service( )方法, service( )方法会根据所接收到的 HTTP 请求类型调用doGet , doPost,或别的 doXXXFANGFA 当 WEB 容器卸载 Servlet 时,调用 destroy 方法,释放使用的任何资源。 2.Init 的方法 Servlet 的初始化 什么情况下初始化 Servlet? ?????启动服务器时(配置了自动装入选项) ?????没有配置自动装入项,当客户首次向 Servlet 发出请求时,初始化 Servlet ?????重新装入 Servlet 时也会初始化 Servlet. Public void init( ) throws ServletException{ 初始化代码 } 如: 初始化一个连接数据库的init 方法的实例
19

基于JAVA 的WEB 应用开发实训教程

protected Connection conn; public void init( ) { try{ Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver?); Conn=DriverManager.getConnection(“jdbc:odbc:usingjsp”); } catch(Exception exc){ getServletContext().log(“Error making JDBC connection:”,exc); } } 初始化参数 读取特定服务器的初始化参数,如 Servlet 可能需要知道数据库设置、口令、特定服务器的 性能参数。这些参数封装在 ServletConfig 的对象中。还有一个 ServletContext 对象,表书有 关 Servlet 环境的信息。 Public void init( ) throws ServletException{ ServletConfig config=getServletConfig( ); String param1=config.getInitParameter(“parameter1”); } web.xml <web-app> <display-name> Welcome to Tomcat </display-name> <description> Welcome to Tomcat </description> <servlet> <servlet-name> FirstSimpleServlet</servlet-name> <servlet-class>FirstSimpleServlet</servlet-class> <init-param> <param-name>parameter1</param-name> <param-value>The value of the parameter1</param-value> </init-param> </servlet> </web-app> servlet 如何处理请求? 两个重要的参数对象 HttpServletRequest HttpServletResponse Service( ) DoGet( ) DoPost()
20

基于JAVA 的WEB 应用开发实训教程

创建

初始化

可用服务

服务不可用

服务请求

销毁 卸载

Servlet 被初始化后,处于响应请求的就绪状态。 每当服务器接受 Servlet 请求时,服务器产生一个新进程并调用 service( )方法。Service 方法 检查HTTP 请求类型(GET,POST,PUT,DELETE)并根据类型 doGet( ),doPost( ),doPut() 方 法。 这些方法都以 HttpServletRequest request, HttpServletResponse respons 对象为参数 HttpServletRequest 对象封装了客户的请求信息,包括客户的环境和从客户端送到服务器 端的任何数据。

HttpServletResponse

封装了动态产生的响应。 Service( )方法 一般用如下方法来声明: public void service(HttpServletRequest request, HttpServletResponse respons throws java.io.IOException { … } )

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {
PrintWriter out=response.getWriter(); Out.println(“Hello World”); } 处理 POST 和 GET 的 Servlet 如果有一个既要处理 POST,又要处理 GET 的 Servlet,可以让 doPost()方法调用 doGet(), 反之也可。

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {
代码…. }

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {
doGet(request,response); }
21

基于JAVA 的WEB 应用开发实训教程

SingleThreadModel 接口 Servlet 的多个线程可能同时访问一些共享数据,doGet,doPost 方法的处理必须谨慎; 要阻止多线程的访问,可以使 servlet 实现 SingleThreadModel 接口; 一般写法: public class OurSTServlet extends HttpServlet implement SingleThreadModel { …. } Servlet 如何被释放:destroy() ,释放资源 如关闭数据库连接的 Servlet destroy 方法: public void destroy( ) { try{ if(conn!=null) { conn.close(); } } catch(SQLException exc){ getServletContext().log(“Error closing JDBC connection”,exc); } } 8 表单处理 8 8 8 8 1 2 3 4 Servlet 表单处理的方法 表单处理示例 Servlet 处理 HTTP 请求头 Servlet 处理 HTTP 响应头、状态码

9 9 9 9 9

1 Servlet 表单处理的方法 9 例题 1 北京欢迎你! package star.moon; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class HelloBeijing extends HttpServlet { public void init(ServletConfig config) throws ServletException { super.init(config); } public void service(HttpServletRequest reqest,HttpServletResponse response) throws IOException { response.setContentType("text/html;charset=GB2312");//设置响应的 MIME 类型 PrintWriter out=response.getWriter();//获得一个向客户发送数据的输出流 out.println("<html><body>"); out.println("<h2>北京奥运圆满成功!</h2>"); out.println("</body></html>");
22

基于JAVA 的WEB 应用开发实训教程

} } web.xml:
<servlet> <servlet-name>hello</servlet-name> <servlet-class>star.moon.HelloBeijing</servlet-class> </servlet> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/lookHello</url-pattern> </servlet-mapping>

例题 2:字母 package star.moon; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class ShowLetter extends HttpServlet { public void init(ServletConfig config) throws ServletException { super.init(config); } public void service(HttpServletRequest request,HttpServletResponse response) throws IOException { response.setContentType("text/html;charset=GB2312"); PrintWriter out=response.getWriter();
23

基于JAVA 的WEB 应用开发实训教程

out.println("<html><body>"); out.print("<BR>小写希腊字母: "); for(char c='α';c<='ω';c++) { out.print(" "+c); } out.print("<BR>大写希腊字母: "); for(char c='Α';c<='Ω';c++) { out.print(" "+c); } out.println("</body></html>"); } } web.xml
<welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <servlet> <servlet-name>hello</servlet-name> <servlet-class>star.moon.ShowLetter</servlet-class> </servlet> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/helpMeShow</url-pattern> </servlet-mapping>

index.jsp:
<Font size=3> 单击超链接查看希腊字母表: <BR><A href="helpMeShow">查看希腊字母表</A> </Font> 例题 3

package star.moon; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class ComputerPI extends HttpServlet { double sum=0,i=1,j=1; int number=0; public void init(ServletConfig config) throws ServletException {super.init(config); } public synchronized void service(HttpServletRequest request, HttpServletResponse response) throws IOException { response.setContentType("text/html;charset=GB2312"); PrintWriter out=response.getWriter();
24

基于JAVA 的WEB 应用开发实训教程

out.println("<html><body>"); number++; sum=sum+i/j; //PI=4*(1-1/3+1/5-1/7+….) j=j+2; i=-i; out.println("servlet:"+getServletName()+"已经被请求了"+number+"次"); out.println("<BR>现在PI的值是:"); out.println(4*sum); out.println("</body></html>"); } }
<welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <servlet> <servlet-name>hello</servlet-name> <servlet-class>star.moon.Computer</servlet-class> </servlet> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/getResult</url-pattern> </servlet-mapping> index.jsp <FORM action="getResult" method=post> <BR>输入圆的半径:<Input Type=text name=radius> <Input Type=submit value="提交"> 例题 4 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>MyHtml.html</title> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="this is my page"> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <!--<link rel="stylesheet" type="text/css" href="./styles.css">--> </head> <body> <h1 align="center"> please input your contact information:</h1> <form action="/sxd1/servlet/CustomerInfo"> your name:<input type="text" name="Name"><br> your eamil:<input type="text" name="Email"><br> your phone number:<input type="text" name="Tel"><br>

25

基于JAVA 的WEB 应用开发实训教程

<input type="submit" value="Submit"> </body> </html> import import import import import import public public java.io.IOException; java.io.PrintWriter; javax.servlet.ServletException; javax.servlet.http.HttpServlet; javax.servlet.http.HttpServletRequest; javax.servlet.http.HttpServletResponse; class void CustomerInfo extends HttpServlet { doGet(HttpServletRequest request, HttpServletResponse ServletException, IOException {

response) throws response.setContentType("text/html"); PrintWriter out=response.getWriter(); out.println("<html><head><title>Check information</title>"+ "</head><body><br>"+ "please check your information:<hr>"+ "your name is "+ request.getParameter("Name")+ "your email is "+ request.getParameter("Email")+ "your phone number is "+ request.getParameter("Tel")+ "</body></html>"); out.flush(); out.close();
}

web.xml <servlet-name>CustomerInfo</servlet-name> <servlet-class>CustomerInfo</servlet-class> </servlet> <servlet-mapping> <servlet-name>CustomerInfo</servlet-name> <url-pattern>/servlet/CustomerInfo</url-pattern> </servlet-mapping>

获取参数示例: Public class SerarchServlet extends HttpServlet{ Public void doPost( HttpServletRequest ServletExcetption,IOException{ ….. Enumeration enum=req.getParameterNames( ); While(enum.hasMoreElements() ){ String name=(String) enum.netElement();
26

req,

HttpServletResponse

res)

throws

基于JAVA 的WEB 应用开发实训教程

String } } } 8 3

value=req.getParameter(name);

Servlet 处理 HTTP 请求头

9

1.HTTP 请求头 从 HTTP 请求头中获取浏览器发送给服务器的 HTTP 信息; 请求头是直接由浏览器设置,并在 HTTP 请求消息中直接发送。 GET /servlet/Search?keyword=bmw HTTP 1.1 Accept: image/gif ,image/jpg. */* Accept-Encoding :gzip Connection:Keep-Alive Cookie:userID=user12345 Host:www.runningauto.com Referer:http://www.runningauto.com/searchCar.html User-Agent:Mozillz/4.7[en](Win98;U) 2. Servlet 读取请求头 HttpServletRequest 封装了 HTTP 请求信息 HttpServletRequest 类定义了从请求对象中抽取信息的一系列方法; getHeader(“Accept-Language”) 3. 访问请求头的特殊方法 getCookies( ) : 返回 Cookie 头的内容,解析后存放在 Cookie 对象的数组中。 getContentType( ), getContentLength() getHeaderName() getHeaders( ) getMethod( ) :返回 GET, POST getRequestURI( ) 返回URL 主机和端口号后表单数据之前的部分 URL http://www.runningauto.com/servlet/Search, getRequestURI( ) 返回/servlet/Search getProtocol( ) 4. 获取HTTP 请求头示例 一段HTTP 请求信息 POST /Music/SearchServlet HTTP/1.0 Referer:http://www.music.ibm.com/musicSearch.html Connetion :Keep-Alive User-Agent:Mozila/4.72 [en](winNT 5.0 ;U) Host:localhost:8080 Accept:image/gif,image/x-xbitmap,image/jpeg.*/* Accept-Language:en Accept-Charset:iso-8859-1,*,utf-8 Content-length:50 Song_title=hello&song_artist=Jones&limit_number=20 获取HTTP 请求头示例 Public void SearchServlet(HttpServletRequest request,HttpServletResponse response)
27

基于JAVA 的WEB 应用开发实训教程

{ …. String method=request.getMethod(); If(method.equals(“GET”) { …. } String lang=request.getHeader(“Accept-Language”); } HTTP 响应 HttpServletResponse 封装了动态产生的相应 Servlet 通过 HttpServletResponse 把所有的响应消息传递给客户 设置Content-Type,状态码 设置响应头(cookie,caching) 响应对象还可以是指向另一个 URL 的重定向 HttpServletResponse 的方法 HTTP 响应信息 HTTP /1.1 200 OK Content-Type:text/plain Hello World SetHeader 方法设置响应头 Response.setHeader(“Accept”,”image/png”); WEB 服务器响应浏览器或其他客户程序的请求时,其响应消息一般由以下及格部分组成: 一个状态行,几个响应头,一个空行,和返回的内容文档。 HttpServletResponse 的方法 setContentType() setContentLength( ) addCookie( ) HTTP1.1 状态代码及其含义 100-199 表示初始的请求已经接受,客户应当继续发送请求的其余部分 200~299 表示响应成功 300~399 表示重定向 400~499 表示客户端错误 500~599 表示服务器端错误 HttpServletResponse 设置状态码 HttpServletResponse.setStatus( ) 设置响应头示例 9 Servlet 相关的接口和类 9 Java Servlet API Java servlet API 是定义了WEB 客户端和 Web Servlet 之间标准接口的一组 java 类 这组API有两个包组成: javax.servlet javax.servlet.http javax servlet:包中所包含的是编写 Servlet 所需的最基本的类和接口,独立于协议的
28

基于JAVA 的WEB 应用开发实训教程

javax.servlet.http:包扩展了上述基础包的功能,对HTTP 协议提供了特别的支持。 9 1 Javax.servlet 包中的接口 Javax.servlet 包 接口(7个): Servlet ServletRequest ServletResponse SingleThreadModel ServletConfig ServletContext RequestDispather 类(3个) GenericServlet ServletInputStream ServletOutputStream 异常: ServletException UnavilabletException 9 3 Javax.servlet.http 包中的接口

9

9

接口(5个) HttpServletRequest HttpServletResponse HttpSession HttpSessionBindingListener HttpSessionContext 类 4 个: Cookie HttpServlet HttpSessionBindingEvent HttpUtils Servlet 接口: Javax.servlet 包 接口(7 个): Servlet 该接口是一个抽象类,定义了Servlet 必须实现的方法,如初始化方法,处理 请求的service( )方法和 destroy 方法等。 HttpServlet 类继承了 GenericServlet 类,支持 HTTP 协议 通常不需要直接实现 Servlet 接口,而是继承 GenericServlet 类或者 HttpServlet 类。 接口定义: public abstract interface Servlet{ public void destroy( ); //当所有线程结束时,调用此方法,释放所占用的全部资源 public ServletConfig getServletConfig( );//返回对象包含了此 Servlet 的所有初始化参数和 启动设置 public String getServletInfo( ); //返回Servlet 自身的信息,如作者,版本号,版权信息
29

基于JAVA 的WEB 应用开发实训教程

public void init(ServletConfig config); //初始化 Servlet public void service( ServletRequest request,ServletResponse response)//处理从客户端传来的 请求 } ServletRequest 接口: 用来向 Servlet 提供有关客户请求的信息 HttpServletRequest 类继承了该接口,进一步提供与协议有关的数据。 ServletResponse 接口: 用来向客户端传送经过 MIME 编码的数据: 发送文本数据时,使用 getWriter 方法返回 PrintWriter 对象; 发送二进制数据时,使用 getOutputStream 方法返回 ServletOutputStream 对象; 使用上述方法之前,调用 setContentType 方法。 HttpServletResponse 类继承了 ServletResponse 接口,提供进一步与协议相关的数据 ServletResponse 对象是 Service( )方法的参数之一。 SingleThreadModel 接口: 该接口确保 Servlet 在同一时刻只处理一个请求,此接口中没有定义方法。 ServletConfig 接口: 该接口用来存取Servlet 实例的初始化参数。 可以通过 ServletConfig 可以得到 web.xml 中设置的 Servlet 的一些部署信息; 每个 ServletConfig 对象对应着一个唯一的Servlet。 Public abstract interface ServletConfig{ Public String getInitParameter(String name); //返回指定名称的 Servlet 初始化参数的值。无则返回空值 Public Enumeration getInitParameterNames( ); //返回 Servlet 所 有初始化参数的名称,枚举类型。 Public ServletContext getServletContext( );//返回服务器传递给此 Servlet 的运行环境,返回值为 ServletContext 对象。 } web.xml 中Servlet 的定义: ….. <servlet> <servlet-name> RegistrationServlet</servlet-name> <display-name> RegistrationServlet </display-name> <servlet-class> com.ibm.ils.exam.servlet.RegistrationServlet</servlet-class> <init-param> <param-name>MaxTries</param-name> <param-value>4</param-value> </init-param> <init-param> <param-name>AutoSave</param-name> <param-value>false</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping>
30

基于JAVA 的WEB 应用开发实训教程

<servlet-name>RegistrationServlet</servlet-name> <url-pattern>Register</url-pattern> <?servlet-mapping> public void init() { String maxTries; String autoSave; MaxTries=getInitParameter(“MaxTries”); AutoSave=getInitParameter(“AutoSave”); } or public void init() { ServletConfig config=getServletConfig( ); String maxTries; String autoSave; MaxTries=config.getInitParameter(“MaxTries”); AutoSave=config.getInitParameter(“AutoSave”); } ServletContext 接口 接口向Servlet 提供访问其环境所需的方法,并记录一些重要的环境信息 通过调用 ServletConfig.getServletContext( )方法来获得ServletContext 对象。 RequestDispather 接口 定义了一个从客户端接受请求,并能够把请求发送到其他服务器资源的对象; 这些其他资源包括 Servlet,html, jsp 文件。 Public abstract interface RequestDispatcher { void forward( ServletRequest request, ServletResponse response); void include(ServletRequest request , ServletResponse response); } forward (转发)把处理用户请求的控制权转交给其他 WEB 资源; include(包括)执行 inclcude 的组件维持对请求的控制权,只是简单地请求将另一个组件的输 出包括在本页面的某个特定的地方。

Servlet A

Servlet B

Servlet A

Servlet B

31

基于JAVA 的WEB 应用开发实训教程

Forward 和 include 的区 别? 1.Forward 要转发的组件不能设置响应头信息,也不能有内容发送到输出缓冲区,所有与 向客户发送内容直接相关的任务必须由被转发的组件完成。Servlet A 不能设置响应头信 息。由servlet B 完成。 2.Include servlet B 不能设置响应头,也不能有内容发送到输出缓冲区。这些工作由 servlet A 来完成。 共享数据 应用程序的各个 servlet 和 jsp 页面之间可以通过以下几种方式共享数据: 一个 WEB 应用程序有一个独立的 ServletContext 对象,应用程序的任何一个 servlet 都可以 访问这个 ServletContext。通过它的 getAttribute 和 setAttribute 方法来共享数据。 GetRequestDispatcher( ) GetServletContext( ) GetRequestDispatcher(“/pages/showBalance.jsp”).forward(req,res); GetServletContext() GetRequestDispatcher(“/pages/navigation.html”).include(req, res); 类(3个) GenericServlet:已经实现了 javax.servlet.Servlet 接口,定义了一个与协议无关的 Servlet ServletInputStream ServletOutputStream 会话跟踪 5 10 10 10 10 10 10 1 2 3 4 5 会话跟踪的机制 Cookie
URL 重写

5 5 5 5 5

隐藏表单字段 HttpSession 对象

5 10 1 会话跟踪的机制 HTTP 是一个无状态的协议,WEB 服务器将某个页面的每次访问都当作相互无关的访问来 处理。服务器不保留前一次访问的信息。服务器不保留客户机的状态信息。会导致许多困难。 会话状态:WEB 服务器需要以某种形式得到用户的状态信息,我们把用户访问应用程序时 与某一用户相关的应用程序状态称为会话状态。 象购物车里记录的商品这样的临时共享信息称为会话数据。代表了一个用户在访问期间与不 同的程序或 Servlet 的连接状态。会话数据是临时的,和长期保留在数据库中的事务数据不 同。 5 10 2 Cookie 解决会话问题的方式: cookie URL 重写 隐藏表单字段 HttpSession 对象 会话数据可以保存在客户端,也可以保留在服务器端。 Cookie: 是服务器发送给浏览器的体积很小的纯文本信息 保存在客户端。

32

基于JAVA 的WEB 应用开发实训教程

Cookie 是一组名称数值对。定义一组Cookie 的名字,每个名字有相应的数值。 UserType=”expert” Cookie 分为两类:持久的和暂时的。持久的 Cookie 会被存储在客户端文件系统中。暂时的 Cookie 存储在内存中,一旦浏览器关闭,Cookie 就消失。 一般来说,客户端浏览器一般只允许存放 300 个 Cookie,每个站点最多存放 20 个 Cookie, 每个Cookie 的大小限制为4KB,因此Cookie 不会站用太大的空间。

Cookie. API
创建 Cookie Cookie(String name, String value) Cookie 的名字和 Cookie 的值不能包含空白字符,=、[]、“ 将 Cookie 传送给浏览器 HttpServletResponse.addCookie(Cookie aCookie) 读取 Cookie HttpServletRequest.getCookie() 注意:不能请求某一个特定的Cookie,必须读取所有的 Cookie,循环访问该数组的各个元 素,从中找出需要的那一个。 获取 Cookie 的名字 aCookie.getName( ) 获取 Cookie 的值 aCookie.getValue( ); 改变 Cookie 的值 aCookie.setValue( String) 举例: public void doGet(HttpServletRequest request, HttpServletResponse response) { String userType=”notMember”; Cookie[] cookies=req.getCookies(); If(cookies != null) { for(int I=0; I<cookies.length; I++) { if( cookies[I].getName().equals(“userType”)) userType=cookies[I].getValue(); } } if(useType.equals(“isMember”)) … else … }
33

?、?

基于JAVA 的WEB 应用开发实训教程

使用 Cookie 的属性 Cookie 的使用期限 Public int getMax.Age() Public void setMaxAge(int lifetime) 例如: setMaxAge(60*60); 默认值是-1 Cookie 不是持久存储的,临时的 网页浏览器关闭之前有效 设置为0值,表示浏览器删除相应的 Cookie public String getDomain() public void setDomain(String domainPattern) public String getPath() public void setPath(String path)//可以为 Cookie 设置其发送的目录。 10 3 URL 重写

5

在 JSP 文件嵌入如 JAVA 代码; <% response.endcodeURL(“/store/catalog”); %> 纯文本文件中无法使用 URL 编码 用 URL 重写维护会话要求应用程序中的每个 Servlet 必须对<A>标记的每个 HREF 属性使用 URL 编码。 在将URL 发送到输出流之前在 Servlet 中调用 encodeURL()方法 out.println(“<a href=\”/store/catalog\”> catalog </a>”); out.println(“<a href=\””); out.println(response.endcodeURL(“/store/catalog”)); out.println(“\”>catalog</a>”); 重写正在重定向的 URL 调用 encodeRedirectURL()方法 response.sendRedirect(“http://myhost/store/catalog”); response.sendRedirect( response.encodeRedirectURL(“http://myhost/store/catalog”)); 10 4 隐藏表单字段 5

隐藏表单域。 HTML 表单中可以包含下面这样的输入域: <INPUT TYPE="HIDDEN" NAME="session" VALUE="...">。这意味着,当表单被提交时, 隐藏域的名字和数据也被包含到 GET 或 POST 数据里,我们可以利用这一机制来维持会话 信息。然而,这种方法有一个很大的缺点,它要求所有页面都是动态生成的,因为整个问题 的核心就是每个会话都要有一个唯一标识符。 5 10 5 HttpSession 对象 使用 HttpSession 对象

查看当前请求的会话对象 HttpSession session = request.getSession(true); 假定 ShoppingCart 是一个保存已购买商品信息的类 HttpSession session = request.getSession(true); ShoppingCart previousItems = (ShoppingCart)session.getValue("previousItems");
34

基于JAVA 的WEB 应用开发实训教程

if (previousItems != null) { doSomethingWith(previousItems); } else { previousItems = new ShoppingCart(...); doSomethingElseWith(previousItems); }
11 11 11 11 11 11 1 2 3 4 1 Servlet 过滤器 Servlet 过滤器的机制 Servlet 过滤器的接口 创建 Servlet 过滤器 指定 Servlet 过滤器映射 Servlet 过滤器的机制 5 9 9 9 9 9

过滤器是一个 java 程序,在与之相关的 servlet 或 JSP 页面之前运行。 过滤器可附加到一个或多个 servlet 或 JSP 页面上; Servlet 过滤器是可插入的一种 WEB 组件,允许开发人员实现 WEB 应用程序中 的预处理和后期处理逻辑。 Servlet 过滤器的特性 过滤器将对应用程序处理的逻辑封装到单个类文件中。 调用是动态的,过滤器运行是由 servlet 容器调用来拦截和处理请求和响应。 通过 WEB 部署描述符来声明配置。WEB。XML,允许添加和删除过滤器,而无 需改动任何程序或 JSP 页面。 Servlet 过滤器是可重用,可附加到一个或多个 Servlet 或 JSP 页面上。 Servlet 过滤器的用处 包括:日志过滤器 logging filter, 图象转换过滤器 image conversion filter,加密 过滤器 encryption filter, MIME 类型过滤器 mime type filter。 使用过滤器可对不同资源进行批量更改。 过滤器以一种模块化的或可重用的方式封装了公共的行为。

35

基于JAVA 的WEB 应用开发实训教程

11

2

Servlet 过滤器的接口

9

Javax.servlet.Filter Javax.servlet.FilterChain,允许把控制权传递给过滤器链中的下一个资源 Javax.servlet.FilterConfig 该接口对象将由容器提供给过滤器,以允许访问 该过滤器的初始化数据。 三个接口都在 javax.servlet 包中 init(FilterConfig):这是 Servlet 过滤器的初始化方法,Servlet 容器创建 Servlet 过滤器实例后将调用这个方法。 ????可以访问并存储 FilterConfig 对象,以便 doFilter 方法能访问 Servlet 环 境或过滤器名; ????在这个方法中可以读取 web.xml 文件中 Servlet 过滤器的初始化参数 doFilter(ServletRequest, ServletResponse,FilterChain):这个方法完成 实际的过滤操作。当客户请求访问与过滤器关联的 URL 时,Servlet 容器将先 调用过滤器的 doFilter 方法。FilterChain 参数用于访问后续过滤器 destroy():Servlet 容器在销毁过滤器实例前调用该方法,在这个方法中可以 释放 Servlet 过滤器占用的资源
11 3 创建 Servlet 过滤器 9

????首先创建一个 java 类,实现 Filter 接口 ????在 doFilter 方法中实现过滤器逻辑 ????调用 FilterChain 对象,激活下一个相关的过滤器,或 servlet,jsp 页面 ????在部署描述符文件 web.xml,对相应的 servlet 或 jsp 页面注册过滤器
清单 1 展示了一个非常简单的过滤器,它跟踪满足一个客户机的 Web 请求所花的大致时 间 清单 1. 一个过滤器类实现 import javax.servlet.*; import java.util.*; import java.io.*; public class TimeTrackFilter implements Filter { private FilterConfig filterConfig = null; public void init(FilterConfig filterConfig) throws ServletException { this.filterConfig = filterConfig;
}

public void destroy() { this.filterConfig = null;
}

public void doFilter( ServletRequest request, ServletResponse response, FilterChain chain ) throws IOException, ServletException { Date startTime, endTime; double totalTime; startTime = new Date(); // Forward the request to the next resource in the chain chain.doFilter(request, wrapper);
36

基于JAVA 的WEB 应用开发实训教程

// -- Process the response -- \\ // Calculate the difference between the start time and end time endTime = new Date(); totalTime = endTime.getTime() - startTime.getTime(); totalTime = totalTime / 1000; //Convert from milliseconds to seconds StringWriter sw = new StringWriter(); PrintWriter writer = new PrintWriter(sw); writer.println(); writer.println("==============="); writer.println("Total elapsed time is: " + totalTime + " seconds." ); writer.println("==============="); // Log the resulting string writer.flush(); filterConfig.getServletContext(). log(sw.getBuffer().toString());
} }

2. 配置 Servlet 过滤器 过滤器通过 web.xml 文件中的两个 XML 标签来声明。 <filter> 标签定义过滤器的 名称,并且声明实现类和 init() 参数。<filter-mapping> 标签将过滤器与 servlet 或 URL 模式相关联 <filter> <filter-name>Page Request Timer</filter-name> <filter-class>TimeTrackFilter</filter-class> </filter> <filter-mapping> <filter-name>Page Request Timer</filter-name> <servlet-name>Main Servlet</servlet-name> </filter-mapping> <servlet> <servlet-name>Main Servlet</servlet-name> <servlet-class>MainServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Main Servlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> 上面的代码示例声明了一个过滤器("Page Request Timer"),并把它映射到一个 servlet ("Main Servlet")。然后为该 servlet 定义了一个映射,以便把每个请求(由通配符指定) 都发送到该 servlet。这是控制器组件的典型映射声明。您应该注意这些声明的顺序,因为 千万不能背离这些元素的顺序。 对用户的访问认证。如果认证通过,那么 允许访问 指定资源,否则不行。 package eflylab; import javax.servlet.FilterChain; import javax.servlet.ServletRequest;
37

基于JAVA 的WEB 应用开发实训教程

import javax.servlet.ServletResponse; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.ServletException; import javax.servlet.FilterConfig; import javax.servlet.http.HttpSession; public class SignonFilter implements Filter
{

String LOGIN_PAGE="login_signon.jsp"; protected FilterConfig filterConfig; //过滤处理的方法 public void doFilter(final ServletRequest chain)throws IOException,ServletException
{

req,final ServletResponse res,FilterChain

HttpServletRequest hreq = (HttpServletRequest)req; HttpServletResponse hres = (HttpServletResponse)res; HttpSession session = hreq.getSession(); String isLogin=""; try
{

isLogin=(String)session.getAttribute("isLogin"); if(isLogin.equals("true"))
{

System.out.println("在 SignonFilter 中验证通过"); //验证成功,继续处理 chain.doFilter(req,res);
}

else
{

//验证不成功,让用户登录。 hres.sendRedirect(LOGIN_PAGE); System.out.println("被 SignonFilter 拦截一个未认证的请求");
} }

catch(Exception e)
{

e.printStackTrace();
} }

public void setFilterConfig(final FilterConfig filterConfig)
{

this.filterConfig=filterConfig;
38

基于JAVA 的WEB 应用开发实训教程

}

//销毁过滤器 public void destroy()
{

this.filterConfig=null;
}

/** *//** *初始化过滤器,和一般的 Servlet 一样,它也可以获得初始参数。 */ public void init(FilterConfig config) throws ServletException { this.filterConfig = config;
} }

在上面的代码中,首先通过 isLogin = (String)session.getAttribute("isLogin")获得用户是否 登录 的属性。如果 为 真,则可以访问到目标 资源,否则 转向 login_singnon.jsp 配置 <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <listener> <listener-class>eflylab.SessionListener</listener-class> </listener> <filter> <filter-name>encoding</filter-name> <filter-class>eflylab.EncodingFilter</f ilter-class> <init-param> <param-name>encoding</param-name> <param-value>gb2312</param-value> </init-param> </filter> <filter> <filter-name>auth</filter-name> <filter-class>eflylab.SignonFilter</filter-class> </filter> <filter-mapping> <filter-name>encoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping><!-- 表示对于 encoding 任何请求都会进行 该 过滤 --> <filter-mapping> <filter-name>auth</filter-name> <url-pattern>/security/*</url-pattern> </filter-mapping>
39

基于JAVA 的WEB 应用开发实训教程

<filter-mapping> <filter-name>auth</filter-name> <url-pattern>/admin/*</url-pattern> </filter-mapping> </web-app> 11 4 指定 Servlet 过滤器映射 12 12 12 12 12 12 12 12 JSP 的基本应用知识 JSP 的基本知识 Web 页面中的静态动态内容 JSP 样例实战 JSP 的特性 JSP 的基本构成 JSP 的执行原理 JSP 的生命周期

9 5 9 9 9 9 9 9 5 9

1 2 3 4 5 6 7

12 1 JSP 的基本知识 什么是 JSP JAVA Server Page, sun microsystem 公司倡导的动态网页技术标准 12 2 Web 页面中的静态动态内容 静态WEB 页面意味着简单的组织结构。 JSP 页面分离视图和内容 View Control Model 12 3
<%@

9

JSP 样例实战
page contentType="text/html;charset=GB2312" BGCOLOR=cyan> sum=0; %>

9

一个简单的 Jsp 页面:
<HTML><BODY <% int { } %> <h5> <% <h5> </BODY><HTML> 1 到 100 的连续和是: =new new java.util.Date( ) %> <%=sum %> i,

<h3>这是一个简单的 JSP 页面</h3> for(i=1;i<=100;i++) sum=sum+i;

JSP 将普通的、静态的 HTML 与动态生成的 HTML 结合起来。动态的内容是脚本生成 的。 12 9 4 JSP 的特性

分离业务逻辑和表示 编写一次、随处运行:平台无关性

40

基于JAVA 的WEB 应用开发实训教程

服务器端 JAVA 资源的高效利用:是 J2EE 的关键组件 广泛的工具支持 可重用的组件和标签库 12 5 JSP 的基本构成

9

????在传统的 HTML 页面中加入JAVA 程序片段Scriptlet 和JSP 标记,就构成了JSP 页面*.jsp ????WEB 服务器执行 JSP 中的程序片段,然后将执行结果以 HTML 格式返回客户。 ????程序片段完成动态网站所需要的功能,如:访问数据库、重定向网页。 ????所有的操作都在服务器端执行。 ????包括以下组件: ?????JSP 指令: 是JSP 页面被编译成 Servlet 时由 JSP 引擎处理的指令 ?????JSP Action:是在 JSP 页面中使用 XML 语法的一种定义:包含使用 JavaBean 组件, 把用户转发给其他页面等; ?????JSP 脚本:允许将 JAVA 代码插入到将要在JSP 页面中生成的 Servlet 中。 12 6 JSP 的执行原理 9 ????JSP 页面被编译成 Servlet: 通过应用服务器,JSP 页面的动态和静态元素,如 HTML 标记、JSP 标记和脚本被转成 Servlet 代码; Void _jspServlet(HttpServletRequest request,HttpServletResponse response) Throws IOException,ServletException Public void jspInit() Public void jspDestroy() ????通过Servlet 输出流传送页面到浏览器 5 12 7 JSP 的生命周期 同 Servlet 相同 各个阶段 编译: 当浏览器请求访问 JSP 页面时,JSP 引擎查看是否需要编译
41

基于JAVA 的WEB 应用开发实训教程

如果从来没编译过,或上次编译之后又经过修改,那么JSP 引擎就编译该页面 编译过程: 解析 JSP; 将JSP 转化成一个 Servlet;编译 Servlet 装载: 与 servlet 类似,区别在 JSP 的类文件许要重装载,不能完全指望JSP 引擎自动装载所 有需要的类。 初始化: Servlet 初始化,如果要执行特定的 JSP 的初始化,重写 jspInit( ) 执行: JSP 引擎通过调用JSP 的 _jspService 方法来执行用户发出的请求: 清理 13 13 13 13 13 1 2 3 4 JSP 元素 JSP 页面元素的组成 JSP 脚本 JSP 指令(Directive) JSP Action 5 5 1 1 1 5

13 1 JSP 页面元素的组成 除了 HTML 标记外,有以下几种 JSP 元素组成: JSP 脚本:元素将 java 代码插入到 JSP 即将生成 Servlet 中; JSP 指令 是 JSP 被编译成 servlet 时由 JSP 引擎处理的指令 JSP Action JSP Action 是在JSP 中使用 XML 语法的一种定义 13 2 JSP 脚本 三种形式: 表达式 <%=Expression %> 例如:<%=new java.util.Date( ) %> Scriptlet <% code %>形式,插入到 servlet 的_jspService 方法中 <% if(Calendar.getInstance().get(Calendar.AM_PM)==Calendar.AM) {%> How are you this morning? <%} else {%> How are you this afternoon? <% }%> 声明 <%! Code %>形式,插入到 servlet 类中 例如: <%! Int a=500; %> <%! Private String getData(GregorianCalendar.gc1) {…..} %>
42

1

基于JAVA 的WEB 应用开发实训教程

Jsp 脚本的XML语法表示 表达式的 XML 语法 <jsp:expression> ……..</jsp:expression> Scriptlet 的 XML 语法 <jsp:scriptlet>…..</jsp:scriptlet> 声明的XML语法 <jsp:declaration>…..</jsp:declaration> 注释 两种: <!- - comments -- > 发送给客户端的 HTML 注释,能够出现在浏览器的输出流中 <% - - comment - - %> 作为JSP 本身一部分的隐藏注释,不发送到客户端,JSP 容器不处理这些文本。 14 JSP 元素使用示例 14 14 14 14 14 1 2 3 4 5 练习一:使用声明 练习二:使用表达式 练习三:使用 Scriptlet 脚本 练习四:使用 include 指令 练习五:使用<jsp:forward>

9 9 9 9 9 9 9

14 1 练习一:使用声明 <html> <head> </head> <%@ page language=”java” import=”java.util.*”%> <body> <%! Int x, y=10; %> <div align=”left”><font color=blue>x 变量取值:<%=x%> </font></div> <div align=”left”><font color=blue>y 变量取值:<%=y%> </font></div> </body> </html> 14 2 练习二:使用表达式 <html> <head> </head> <%@ page language=”java” import=”java.util.*”%> <body> <%! Date nowDate=new Date();%> <div align=”left”> 当前时间为<%=nowDate %></div> </body> </html> 14 3 练习三:使用 Scriptlet 脚本

9

9

43

基于JAVA 的WEB 应用开发实训教程

14 4 练习四:使用 include 指令 Include.html: <HTML> <H2>这部分使用了 include 指令。</H2> </HTML> Test4include.jsp <HTML> <head> </head> <%@ page language=”java” import=”java.util.*”%> <body> <h1>练习四:使用 include 指令</h1> <hr> <br> <%@ include file=”include.html” %> <%! Date nowDate=new Date();%> <div align=”left”> 当前时间为<%=nowDate %></div> </body> </html> 14 5 练习五:使用<jsp:forward> example2_12.jsp
<%@ <% { %> <jsp:forward </jsp:forward> <% { %> <jsp:forward </jsp:forward> <% %> </BODY></HTML> } page="reverseSide.jsp" > i %>" /> <jsp:param name="number" value="<%= } else page="frontSide.jsp" > value="<%= i %>" /> <jsp:param name="number" page contentType="text/html;charset=GB2312" %> <HTML><BODY> double i=Math.random(); if(i>0.5)

9

9

frontSide.jsp
<%@ <% page contentType="text/html;charset=GB2312" bgcolor=cyan><Font size=3> %>

<HTML><BODY

String s=request.getParameter("number"); out.println("<BR>传递过来的值是"+s);

44

基于JAVA 的WEB 应用开发实训教程 %> <BR><img src=image/a.JPG width=120 height=120 >钱币图像</img>

</FONT></BODY></HTML>

reverseSide.jsp
<%@ <% %> <BR> <img src=image/b.JPG width=120 height=120 >钱币图像</img> </FONT></BODY></HTML> page contentType="text/html;charset=GB2312" bgcolor=cyan><Font size=3> %>

<HTML><BODY

String s=request.getParameter("number"); out.println("传递过来的值是"+s);

15 15 15 15 15 15 1 2 3 4 5

使用 JavaBean JavaBeans 与 JavaBean JavaBeans 的属性 在 JSP 中使用 JavaBean 设置 JavaBean 组件的属性 获得 JavaBean 组件的属性

5 5 5 5 5 5

5 15 1 JavaBeans 与 JavaBean 1.什么是 JavaBeans? JavaBeans 是对java 组件模型规范的称呼,它是一种抽象的技术规范; JavaBean 是根据这种规范创建的具体组件; 2.组件模型的定义: 一种包装过的软件对象,拥有标准化的接口,而且可在多个应用程序中重用。 组件体系结构规定了组件之间如何交互作用,组件遵循一系列命名的规范,使调用者依据这 些规范调用不同的组件,javaBean 就是一种组件。 组件分为可见组件,和不可见组件 3.JavaBean 的特性 ?????用 Java 编写 ?????是标准的 java 类/ 实例 ?????符合 Sun 公司的 JavaBeans 规范; 有一套公开的特性:属性,方法,事件 需要一个零参数的构造函数 ?????实现可序列化接口 ?????JavaBean 拥有的属性:是一系列可以被读取或改写的值,Bean 的一些行为成为方 法;Bean 对自身状态的改变的响应称为事件。 4.为什么使用 Beans ?????可视编程工具的支持 ?????区分 WEB 页面的设计和软件的设计 JSP 都是以 JAVA 代码形式嵌入 HTML 页面,要使 JSP 中的 JAVA 代码尽量减 少,需要把许多应用逻辑和数据访问代码从 JSP 分离出来,包装成JavaBean。JavaBean 是装载从 JSP 中分离出来的 JAVA 代码的容器,可以使用类来包装数据信息,通过 JavaBean 中的 get,set 方法来存取 JavaBean 的属性值,在 JSP 中使用<jsp:useBean>标
45

基于JAVA 的WEB 应用开发实训教程

记来动态的存取属性值。 ?????JSP 的支持 <jsp:useBean id=”order” scope=”request” …/> ?????J2EE 连接器的支持 5.一个简单的属性 例如: name ,类型为字符串 String 直接暴露属性的值违反封装性的原则; 属性通过标准 getter 和 setter 暴露给外界 public void setName( String aName); public String getName( ); 完整代码: package ch4; public class UserBean{ private String Name; private String Num; public UserBean() { } public void setUserName(String name){ Name=name;} public void setUserNum(String num){Num=num;} public String getUserName(){ return Name;} public String getUserNum(){ return Num;} } 6.JavaBean 属性类型 (1) 简单类型:字符串、整数、小数和字符等 (2) 索引类型:包含一组值的属性 (3) 布尔类型:取值为 true ,false 的属性 布尔类型的属性: 有以下形式的 getter: public Boolean isManager( ); //判断是否是经理? 有以下形式的 setter: public void setManager( boolean); 索引类型属性: ?????用于 JavaBean 需要管理一组相同类型的属性时: ?????类似JAVA 的数组 ?????属性的索引必须为整型 ?????Bean 会将索引型属性暴露为数组值。 Public void setDependents( int index, String aDependent); Public String getDependents( int index); Public void setDependents(String[] allDependents); Public String[] getDependents(); Readable 和Writeable 修饰符决定了 Bean 是否拥有公开的 getter,setter 函数 例如:有一个 Bean 私有成员 name,同时加上 Readable 修饰符,则该私有变量只读, Writeable 修饰符表示此变量是可写的。 7.序列化: 将对象的持久性数据转换为二进制输出流 序列化工具定义将 JAVA 对象读写为二进制流的格式。 8.自省机制
46

基于JAVA 的WEB 应用开发实训教程

自省可以让构造工具来分析 Bean 是如何工作的。每个 Bean 都有一个相关的 BeanInfo 类,该类提供了关于 Bean 本身的属性,方法和事件信息。 当引擎遇到一个 JavaBean 组件时,首先会 遍历这个类以及超类,是否 存在对应的 BeanInfo 类,如存在就使用 BeanInfo 类中指明的信息作为此组件的相关细心你,如果没有, 通过默认的设计模式来判断组件的属性、方法和事件。 9.打包 可以将Bean 打包主要基于两种技术:java 对象序列化 可以将多个 Bean 打包 15 3 在 JSP 中使用 JavaBean ,Jar文件(存储java 类的定义) 5

1.JSP 显示页面 在编写JSP 页面时,如要使用 JavaBean,第一件事告诉 JSP 它所使用 JavaBean 的信息 <jsp:userBean id=”data” scope=”page” class=”ch4.UserBean”/> id: Bean 对象名称 scope: 四种范围:page, Request, Session, Application class:类的全名 获取已经存在的 Bean <jsp:useBean id=”customer” scope=”request” type=”com.ibm.ils.domain.Customer”/> 从 request 对象中获取名为 customer 的对象,将得到的对象赋值到本地的同名对象中 <jsp:useBean id=”customer” scope=”session” type=” com.ibm.ils.domain.Customer”/> scope 从何处得到javaBean page PageConext request ServletRequest session HttpSession :常用于一个用户登陆在网站上全过程不同请求之间共享数 据 application ServletContext 常用于同一个程序不同用户访问共享数据 从序列化文件中获得 Bean <jsp:useBean id=”customer” beanName=”serializedCustomer” type=” com.ibm.ils.domain.Customer”/> 将 serializedCustomer 传 输 到 Beans.instantiate() 方 法 中 , 对 象 类 型 为 com.ibm.ils.domain.Customer。 创建Bean 的过程: 当 JSP 执行过程中遇到 useBean 动作时,首先得到id和 Scope 参数的值,根据scope 指明范 围找这个 Bean,如找到了,则取回Bean 对象,如没有找到,则在useBean 中查找 beanName 参数,如指明了 beanName 参数,则根据该参数指明的文件中寻找持久性数据,从持久性数 据中实例化指明的 bean,如没有指明 beanName 参数,JSP 会查询是否指明了 class 参数, 如指明了 class 参数,则会创建一个新的 Bean 实例,反之抛出一个异常。 15 4 设置 JavaBean 组件的属性 5 15 5 获得 JavaBean 组件的属性 5 从 Bean 实例中获取属性的值,并输出到 out 对象中。 语法: <jsp:getProperty name=”beanInstanceName” property=”propertyName”> 设置Bean 实例中属性的值: <jsp:setProperty name=”beanInstanceName” setProperty_prop_expr> property=”*” 或 让当前 request 对象中的变量自动与 Bean 对象的属性匹配
47

基于JAVA 的WEB 应用开发实训教程

property=”propertyName”

param=”paramName”

只有被指明的变量才会被赋到 Bean 兑现的同名属性中 property=”propertyName” value=”propertyValue” 直接指明属性的名称和值 javabean 使用简介 1.Hello.java Package my; Public class Hello{ Public String hello(){ Return "hello"; } } 编译后生成的.class 文件放在 WEB-INF/classes/my 下 WEB-INF/classes/my/Hello.class 如果packagemy01.my02; 则放在 WEB-INF/classes/my01/my02 下 2.jsp 中调用 javabean <% my.Hello h=new my.Hello(); out.println(h.hello()); %> 或 <%@ page import="my.Hello"%> <% Hello h=new Hello(); out.println(h.hello()); %> 16 16 16 16 16 16 16 1 2 3 4 5 6 JSP 自定义标记库 JSP 自定义标记的目的 标记库的构成 标记处理器 标记库描述符 开发和使用 JSP 自定义标记 使用自定义标记的优势 5 5 5 5 5 5 5

5 16 1 JSP 自定义标记的目的 标记TAG: HTML 标记有两种: bodyless 标记:<img src=”images/car.gif”/>可有属性但不包含内容的标记 Body 标记:有开始标记和匹配的结束标记,包含内容(标记体)<b>Chapter 1</b> JSP1.1 支持自定义标记,允许开发人员扩展JSP 标记,建立属于自己的 JSP 标记。可

48

基于JAVA 的WEB 应用开发实训教程

以根据自己的需要,自定义一个标记,标记的属性和标记体说明,然后将集合成标记库,在 其他JSP 文件中使用。 分离页面设计和逻辑设计 赋予开发人员扩展可用于 JSP 页面内部的标记的能力 允许开发人员将一些复杂的服务器端行为以标记处理的形式放到 JSP 页面中。 16 2 标记库的构成 5

?????标记处理器 ?????标记库描述文件 ?????应用程序部署描述符 web.xml 文件 ?????在JSP 页面中的标记库声明 16 3 标记处理器

5

使用 JSP 自定义标记时,是由一个特殊的 JAVA 类来决定怎样处理自定义标记,JAVA 类就 是标记处理器。 它 执行 标 记的 预定 义 的特 定行 为。1、 它需 要实 现某 个 自定 义标 记 接口 TagSupport, BodyTagSupport 类。取决于需要开发的标记类型。处理器有权访问所有的 JSP 资源。 5 16 4 标记库描述符 TLD 文件 是一个XML格式的文件,包含标记库中所有标记的元信息,标记名称、所需包含的属性, 相关联的标记处理器类名等。它由JSP 容器读取并处理 5 16 5 开发和使用 JSP 自定义标记 Web.xml 文件是 Web 应用程序的部署描述符。 要使用 JSP 自定义标记,需在 web.xml 中定义:标记库的名称,要使用的 TLD 文件名称、 路径等。 import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*; import java.io.*; public class HelloWorldTag extends TagSupport{ public int doStartTag() throws JspException{ try{ JspWriter out=pageContext.getOut(); Out.println(“<B>Hello World!</B>”); } catch(IOException ioExc) { throw new JspException(ioExc.toString()); } return SKIP_BODY; } public int doEndTag() { return EVAL_PAGE; } } hello.tld
49

基于JAVA 的WEB 应用开发实训教程

…. <taglib> <tlibverion>1.0</tlibverion> <jspverion>1.0</jspverion> <shortname>hello</shortname> <info>An example for tag Hello world</info> <tag> <name>hello</name> <tagclass>HelloWorldTag</tagclass> </tag> </taglib> web.xml <taglib> <taglib-uri> /URLhello</taglib-uri> <taglib-location>/WEB-INF/tld/hello.tld</taglib-location> </taglib> HelloWorld.jsp <%@ taglib uri=”/URLhello” prefix=”myFirstTag”%> <html> <head> </head> <body> <myFirstTag:hello/> </body> </html> 16 6 使用自定义标记的优势 1、 2、 3、 4、 17 17 17

5

标记可以重用,节省开发和测试时间 标记可以访问 JSP 页面可以使用的所有对象,包括请求对象、响应对象,以及输出变量 标记可以嵌套 标记简化了一个JSP 页面的可读性。 JSP 与 Servlet 交互调用 5 1 2 在 Servlet 和 JSP 页面中调用另一个 JSP 页面 在 JSP 页面中调用 Servlet 和另一个 JSP 页面 5 5

JSP 页面可以被以下方式调用 URL、 Servlet、 JSP JSP 页面可以调用以下对象: Servlet、 另一个 JSP 1、 从 URL 调用 JSP url: http://servername/path/filename.jsp <FORM action=”/MyApp/DateDisplay.jsp”> 2、 从 Servlet 调用 JSP getServletContext().getRequestDispatcher(“/pages/showResult.jsp”).forward(req,res); 3、 在 JSP 中调用 Servlet ?????<FORM method=”POST” action=”/MyApp/servlet/DateDisplayServlet”>
50

基于JAVA 的WEB 应用开发实训教程

?????<jsp:forward page=”/servlet/infoServlet”/> ?????<jsp:include page=”/servlet/DateServlet”/> 4、 在 JSP 中调用 JSP ?????<FORM action=”/MyApp/DateDisplay.jsp”> ?????<a href=”/MyApp/DateDisplay.jsp”> ?????<jsp:forward page=”DateInfo.jsp”> 18 Struts 的基本理论 18 18 18 18 1 2 3 4 Struts 的定义 Struts 与 MVC 架构的对应 Struts 的请求流程 Struts 应用开发工具 WSAD 的使用

1 1 1 1 1

1 18 1 Struts 的定义 Struts 是什么? 是 Apache 软件基金会(ASF)资助的一个开放源代码框架,是用于构建基于 MVC 结构的 WEB 应用程序的开放标准。 目的是便于开发人员基于JAVA Servlet 和 JSP 技术构建 WEB 应用程序。 1 18 2 Struts 与 MVC 架构的对应 ?????WEB 开发的两种模式: JSP Model 1: 浏览器访问 WEB 应用的 JSP,JSP 提供用户界面UI显示,而 javaBean 处理数据库访问 和业务逻辑。 优点:直接、简单,对于小型应用,方便 缺点:业务逻辑和表示逻辑混合在 JSP 页面中,没有抽象和分离,不利于扩展和更新。 JSP Model 2 和JSP Model 1 最大的区别是引入 MVC 模式的概念。C是控制器,Servlet 拦截客户端的 请求,并执行前端处理过程,并决定将控制定向到哪个JSP 页面。 两种方法的主要区别在于 Model 2 体系结构引入了控制器 Servlet,比 Model 1 方法具有更多 的重用性和可扩展性,可以区分业务逻辑和显示输出和请求过程。Model 2 的思想就是 MVC 的思想。 ?????MVC 模式: 模型-视图-控制器 MVC 设计模式: 模型 M,是应用程序的数据和业务规则的集合; 视图 V,是应用程序的用户界面 控制器C定义了应用程序与用户输入及模型进行交互的方式。 ?????Struts 与 MVC Struts 是利用 JAVA 技术开发基于 MVC 模式的WEB 应用的开放标准模式。是一个高度可配 置、高度可扩展的 MVC 框架。核心是一个基于标准技术(java servlets, javaBeans,XML) 的灵活的控制层。 Struts 框架的包 Action: 包括控制器类ActionForm, ActionMessage 等 Actions: 包括现成的 action 类,比如 DispatchAction Config: 包括在 Struts 配置文件内存中表示的配置类 Taglib : 用于 Struts 标记库的标记处理程序类
51

基于JAVA 的WEB 应用开发实训教程

Titles: 包括 Tiles 框架包使用的类 Upload: 从本地文件系统上传和下载文件的类 Util :通用工具类 Validator: 用于验证的类 Plugins: 支持动态插入和加载组件的类 模型 JavaBean

2. 请 求 填 充 Bean

Form

ActionForm

Struts-config.xml 控制器 ActionServlet 1.HTTP 请求 浏览器
6.HTTP 响应

3.将

HTTP

请求分

发至 Aciton 处理

4.调用 JavaBean

Action

5.转发 HTTP 请求

视图 JSP

一个简单的 HelloWorld

以一个简单的 HelloWorld 示例来介绍 Struts 2 给读者带来的体验。 为了使读者能够更清楚地了解示例的编写过程,示例将采用文本编辑器的方式来开发, 这样避免了 IDE 集成编辑器给读者带来的困扰。开发一个 Web 应用,要建立符合规范的目 录结构,上节中已经对 Web 应用目录进行了详细的介绍,为了开发 HelloWorld 应用,读者 应该先建立一个目录。笔者建立的顺序如下: 在 E 盘中建立一个文件夹:E:\myweb。 在此文件夹中建立WEB-INF 文件夹。 建立 E:\myweb\WEB-INF\classes 文件夹。 建立 E:\myweb\WEB-INF\lib 文件夹。 将 Tomcat 默认的web.xml 文件拷贝到E:\myweb\WEB-INF\目录下,web.xml 文件在 Tomcat 安装目录中的 webapps\ROOT\WEB-INF 目录下。 使用文本编辑器建立一个 struts.xml 文件,保存到 E:\myweb\WEB-INF\classes 目录下。

2.2.1

配置 web.xml 文件
web.xml 文件和

完成上述步骤后,一个简单的 Web 目录就完工了,接下来需要修改 struts.xml 文件。web.xml 文件内容如代码 2.4 所示。

代码 2.4

HelloWorld 示例的 web.xml

<?xml version="1.0" encoding="UTF-8"?> <web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

52

基于JAVA 的WEB 应用开发实训教程

xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <filter> <!— 配置 filter-> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filterclass> </filter> <filter-mapping> <!—拦截所有 URL 用户请求 <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!—配置欢迎界面文件-> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> </web-app>

在代码 2.4 所示内容中,相比原来的内容,增加了<filter>和<filter-mapping>。 <filter>指定了需要加载的 Struts 2 核心控制器 org.apache.struts2.dispatcher.FilterDispatcher,而<filter-mapping>使用通配符“/*” 来拦截所有的 URL 请求,保证了用户请求都被 Struts 2 接收处理。 2.2.2 配置 struts.xml 文件

编辑 struts.xml 文件内容,如代码 2.5 所示。

代码 2.5

HelloWorld 示例的 struts.xml

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <!—配置 struts2--> <struts> <!-<!-配置包,名称为 bookcode 配置 Action <!---> -->
53

-->

<package name="bookcode" extends='struts-default'> <action name="HelloWorld" class="ch2.helloworld.HelloWorld"> 配置返回结果

基于JAVA 的WEB 应用开发实训教程

<result name="success">/ch2/helloworld/success.jsp</result> <result name="error">/ch2/helloworld/error.jsp</result> </action> </package> </struts>

在默认情况下,Struts 2 将会自动加载位于 WEB-INF\classes 目录下的 struts.xml 配置文件。<package>定义了一个包空间,可以看到,该文件中只配置 了一个 Action,name 为“HelloWorld”,对应的 class 为“ch2.HelloWorld”,也 就是指定 WEB-INF\classes\ch2 目录下的 HelloWorld.class 类文件,当然现在还没 有这个文件,后面将会编写该文件。 ★ 说明 ★

bookcode 是本书示例的包名称,该包继承Struts 2 框架的默认包 struts-default, 读者在后面章节将会学习使用 extends 属性。
另外一个配置就是 result,即 Action 处理后返回给用户的视图资源,从配置中可以看到 配置了两个 result:success 和error,分别对应E:\myweb\ch2 目录下的 success.jsp 和 error.jsp, 后面也将会建立这两个文件。 本节介绍的 HelloWorld 的思路是用户在客户端输入一个字符串,由 Action 判断输入的 字符串是否为空,如果不为空,则返回给用户 success.jsp 页面,并在控制台打印出该字符串; 如果用户输入为空,则返回 error.jsp 页面给用户,提示输入为空。这个流程可以用图 2.16 来说明。用户输入字符串,发送请求给 Struts 2 框架的核心控制器 FilterDispatcher , FilterDispatcher 根据配置,将请求转发给 Action,Action 是业务控制器,来判断用户输入的 内容进行相应的操作。

图2.16

HelloWorld 的流程图

2.2.3

A ction 业务控制器

如图2.16 所示,HelloWorld 应用中的Action 是业务控制器。通过第1章对 Struts 2 的简 单介绍,读者应该知道,Struts 2 的Action 可以是一个普通的Java 类(POJO),与 Struts 1 有很大的不同,这里的 HelloWorld 内容如代码 2.6 所示。

代码 2.6
public

业务控制器 HelloWord
HelloWorld {

package ch2.helloworld; class //定义 msg 属性
54

基于JAVA 的WEB 应用开发实训教程

private public
}

String msg; String getMsg() { msg;

//msg 的 get 方法 return

//msg 的 set 方法 public void setMsg(String msg) { this.msg = msg;
}

//Action 的 execute()处理方法 public if String execute() { (getMsg().equals("")) { //显示错误信息 System.out.println("no String input!"); //返回错误结果 return
} else {

//判断条件

"error";

//显示用户输入的信息 System.out.println(getMsg()); //返回一个处理成功结果 return
} } }

"success";

(1)如代码 2.6 所示,HelloWorld 没有继承任何类,也没有实现任何接口, 是一个标准的 Java 类。定义了一个 msg 属性,对应用户输入的字符串,并提供了 msg 的 get()、set()方法。execute()方法是实现业务控制器的默认方法,该方法只是 返回一个 String,并没有特别之处。
(2)在 execute()方法中,对 msg 内容进行判断,如果非空,则在控制台打印该字符串, 并返回一个“success”字符串,对应代码 2.5 中的 success.jsp 页面。 (3)如果 msg 为空,则在控制台输出一条警告,并返回“error”,对应 error.jsp 页面。 读者会发现,Struts 2 中的Action 变得简单易懂,很容易对其进行测试。

★ 说明



Struts 2 的业务控制器 Action 是一个普通的 Java 类。 2.2.4 视图资源

到这里为止,该示例只缺少 success.jsp、error.jsp 和一个用户输入界面 HelloWorld.jsp, 读者可以使用文本编辑器建立,也可以使用各种网页编辑器来制作,以提高效率。 (1)HelloWorld.jsp 内容如代码 2.7 所示。

代码 2.7

输入界面 HelloWorld.jsp

55

基于JAVA 的WEB 应用开发实训教程

<%@ page contentType="text/html; charset=gb2312" language="java" import="java.sql.*" errorPage="" %> <!DOCTYPE html PUBLIC "-//W 3C //DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>Hello World!!</title> </head> <body> <!—form 的 action 指向定义的 action 名称 <p>输入信息: <label> <input name="msg" type="text" id="username" /> </label> </p> <p> <label> <input type="submit" name="Submit" value="提交" /> </label> </p> </form> </body> </html> --> <form id="form1" name="form1" method="post" action="HelloWorld.action">

在代码 2.7 所示内容中,form 的 action 指向“HelloWorld”,提交一个 name 为 msg 的字符串,这是一个普通的 JSP 文件。
(2)success.jsp 内容如代码 2.8 所示。

代码 2.8

输出界面 success.jsp

<%@ page language="java" contentType="text/html; charset=gb2312"%> <!DOCTYPE html PUBLIC "-//W 3C //DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>返回界面</title> </head> <body> HelloWorld,Struts 2! </body> </html>

代码 2.8 所示内容很简单,只是输出“HelloWorld,Struts 2!”提示。
56

基于JAVA 的WEB 应用开发实训教程

(3)error.jsp 内容如代码 2.9 所示。

代码 2.9

错误界面 error.jsp

<%@ page language="java" contentType="text/html; charset=gb2312" pageEncoding="gb2312"%> <!DOCTYPE html PUBLIC "-//W 3C //DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>错误界面</title> </head> <body> 您没有输入内容! </body> </html>

error.jsp 也只是提示录入错误信息。 ★ 说明 ★

Struts 2 框架支持多种结果类型,默认类型支持 JSP。 2.2.5 运行 HelloWorld

经过上述编写,第一个 Struts 2 应用已经完成,将 E:\myweb 文件夹复制到 C:\Program Files\Apache Software Foundation\Tomcat 6.0\webapps 目录下,启动 Tomcat,准备运行程序。 在浏览器中输入 http://localhost:8080/bookcode/ch2/helloworld/HelloWorld.jsp,出现如图 2.17 所示界面。

在文本框中输入“Hello World!”,单击“提交”按钮,出现如图 2.18 所 示界面。Tomcat 控制台会输出如下内容:
2007-11-21 21:19:56 com.opensymphony.xwork2.validator.ActionValidatorManagerFactory <clinit> 信息: Detected AnnotationActionValidatorManager, initializing it... Hello World!

如果用户没有输入内容,直接单击“提交”按钮,返回页面如图 2.19 所示。同 时,Tomcat 控制台输出如下内容:
no String input!

57

基于JAVA 的WEB 应用开发实训教程

图 2.17

HelloWorld.jsp 页面

图2.18

success.jsp 页面

图 2.19

error.jsp 页面

58

基于JAVA 的WEB 应用开发实训教程

成功运行这个示例,是了解 Struts 2 的良好开端,这是一个极其简单的示例,并没有完 全展示Struts 2 的所有特点,但给读者带来了一个感性了解 Struts 2 的体验。

★ 说明



Struts 2 框架默认 URL 后缀不再是 Struts 1.X 框架的*.do,而是*.action。 2.2.6 HelloWorld 小结

初次完成一个 Struts 2 的 Hello World 示例,读者将会了解:

??web.xml 中需要加入 Struts 2 的加载配置。 ??在 struts.xml 中定义 Action,其中包含 Action 返回视图的定义。 ??Struts 2 的 Action 是一个简单的 Java 类,没有丝毫特别之处。 ??Action 的 execute()方法只是返回一个 String。
Struts2 框架出来有段时间了,终于开始学习Struts 了,也写点东西记录下自己的历程 此文主要来自 www.blogjava.net/Max 的实例,自己是初学,自己动手实践真的很有趣,有不 对的地方希望大家给有指正。 首先 login.jsp 页面表单: <s:form action="login" method="post"> <s:textfield name="username" label="USERNAME" tooltip="Enter Your UserName"></s:textfield> <s:password name= "password" label="PASSWORD" tooltip="Enter Your PassWord"></s:password> <s:submit label="login"></s:submit> </s:form> struts.xml 文件 action 配置: <action name="login" class="com.bulktree.struts2.LoginAction"> <result name="success">/welcome.jsp</result> <result name="input">/login.jsp</result> </action> 处理表单的 LoginAction.java 类文件: package com.bulktree.struts2; import com.opensymphony.xwork2.ActionSupport; public class LoginAction extends ActionSupport { private String username; private String password; public String getUsername() { System.out.println("******getUsername()*****"); return username; } public void setUsername(String username) { System.out.println("*****setUsername()*****"); this.username = username; } public String getPassword() { System.out.println("******getPassword()*****"); return password;
59

基于JAVA 的WEB 应用开发实训教程

} public void setPassword(String password) { System.out.println("******setPassword******"); this.password = password; } @Override public String execute() throws Exception { System.out.println("*****execute()*****"); return SUCCESS; } @Override public void validate() { System.out.println("******validate******"); if(null == username || username.length() < 5) { this.addFieldError("username","USERNAME ERROR"); } if(null == password || password.length() < 5) { this.addFieldError("password","PASSWORD ERROR"); } } }显示页面 welcome.jsp color="red"><s:property YOUR USERNAME:<FONT size="5" value="username"/></FONT><br> YOUR PASSWORD:<FONT size="5" color="red"><s:property value="password"/></FONT><br>控制台输出信息: ******setPassword****** //set 赋值操作 *****setUsername()***** //set 赋值操作 以上有struts2 框架自动执行 ******validate****** //表单验证 *****execute()***** //业务逻辑 以上有struts2 框架自动执行 ******getUsername()***** //get 方法得到值返回到 welcome.jsp 页面 ******getPassword()***** //get 方法得到值返回到 welcome.jsp 页面 客 户 端 输 入 login.jsp 表 单 传 回 服 务 器 时 action="login" 请 求 转 发 到 struts.xml 配 name="login" class="com.bulktree.struts2.LoginAction" 找到处理请求的 LoginAction 类,进行 自动 set 方法 赋值,赋值后自动的执行 String execute()方法,返回 String 类型,默认为 SUCCESS,(即struts.xml 文件里 action 的 name 属性默认为 success)根据返回的 String 的值, 决定执行哪个页面 <result name="success">/welcome.jsp</result> “/”表示绝对路径



60

基于JAVA 的WEB 应用开发实训教程

61

基于JAVA 的WEB 应用开发实训教程

62

基于JAVA 的WEB 应用开发实训教程

63


《Java Web应用开发》课程标准.doc

Java Web应用开发》课程标准 - 课程标准 所属系部:信息工程系 课程名称:Java Web 应用开发 课程性质:专业必修课 课程学时: 9 6 适用专业:云计算技术与应用...

一个基于Java Web开发应用的教学案例设计与实现.doc

一个基于Java Web开发应用的教学案例设计与实现 1 软件项目的设计环节 1.1 设计思路 以介绍 Servlet、Web 页面技术和 JSP 应用为理论依据,以软件实训网络管 理...

Java Web应用开发技术与案例教程第1章_Java_Web应用开....ppt

Java Web 应用开发技术与案例教程 机械工业出版社 2014年1月 张继军 董卫 编著 课程内容 第1章 Java Web应用开发技术概述 第2章 静态网页开发技术 第3章 动态...

第一章 基于JavaEE的web应用_图文.ppt

第一章 基于JavaEE的web应用 - 第一章 基于JavaEE的 web应用 ? ? ? ? ? ? ? ? ? 课程目标 了解Web的基本应用 了解Web的基本应用框架 理解Web程...

基于JAVA技术的Web应用开发._图文.ppt

基于JAVA技术的Web应用开发. - 基于JAVA技术的Web应用开发 北京睿

《Java Web 开发实训》课程标准.doc

Java Web 开发实训》课程标准 - 《Java Web 开发实训》课程标准 课程编号: 实训周数:2 周 学分: 开设学期: 适用专业:软件技术专业 制定单位:信息工程学院 ...

JAVAWEB实训心得体会.doc

JAVAWEB实训心得体会_韩语学习_外语学习_教育专区。...如果费 了很大的精力,开发一个软件,最 后却不满足...三、实训项目的开发环境和所使用的技术 基于 j2se ...

Java_web_开发教程学习心得.doc

Java_web_开发教程学习心得 - Java web 开发教程学习心得 Java web 课程结束了,在完成了 eclipse 三份实验报告之后我开始总结这门 课程自己究竟学到了什么。 从...

Java Web应用开发项目教程_第二章_图文.ppt

基本语法 2.1 项目概述■E-Store电子商城简介 E-Store电子商城系统是基于Internet网络平台,利用 Web技术、数据库技术、Java技术、面向对象技术等进行 开发的Web应用...

Java_Web应用开发项目教程_第一章_图文.ppt

Java_Web应用开发项目教程_第一章 - 第1章 Java Web应用开发基础 ■本章要点: ★★★ ★★★ ★★ 软件常用体系结构C/S和B/S结构 静态网页和动态网页...

JavaWeb应用开发基础(精)_图文.ppt

孙卫琴.精通Struts:基于MVC的 Java Web设计与开发 电子工业出版 社 ? JSP程序设计类教材 课时安排和成绩评定 ? 总学时:75学时,讲课与实验结合。 30% 平时成绩...

《Java Web应用开发》课程标准.doc

根据开发过程中需要的知识与技能规划教学进度,组织课堂教学,确定学生 实训任务。 ...基于JAVA的WEB应用开发实... 63页 5下载券 Java Web程序设计教程第... ...

Java Web应用开发项目教程_第三章_图文.ppt

Java Web应用开发项目教程_第三章 - Java Web应用开发 计算机与

Java Web 应用开发实用教程 - 部分习题汇总.txt

Java Web 应用开发实用教程 - 部分习题汇总 - 表单要提交数据到指定

JAVA_Web开发教程_图文.ppt

JAVA_Web开发教程_计算机软件应用_IT/计算机_专业资料。JAVA_Web开发教程=绝对...重视上机实践,有效利用宝贵的上机时间,发现上 机时间游戏或上网的,按缺席一次...

基于Java的Web应用开发规范.doc

基于Java的Web应用开发规范 - 基于 Java 的 Web 应用开发规范

Java_Web应用开发项目教程_第一章_图文.ppt

Java_Web应用开发项目教程_第一章 - Java Web应用开发 计算机与软件学院 王俊松 南京信息职业技术学院 课程定位 XML Webservice开发 基于Java的企业级应用...

JAVAWEB开发案例.pdf

JAVAWEB开发案例_电子/电路_工程科技_专业资料。中原工学院软件学院 软件工程实践一设计任务书姓 名 程胜 软件工程(Java 方向)专业 102 班 题目 超市商品管理系统...

Java程序设计实训教程参考答案2.doc

Java程序设计实训教程参考答案2_理学_高等教育_教育专区 暂无评价|0人阅读|0次下载 | 举报文档 Java程序设计实训教程参考答案2_理学_高等教育_教育专区。 ...

Java Web应用开发项目教程_第一章_图文.ppt

孙卫琴.精通Struts:基于MVC的 Java Web设计与开发 电子工业出版 社 ? JSP程序设计类教材 课时安排和成绩评定 ? 总学时:75学时,讲课与实验结合。 30% 平时成绩...