阅读的目的?我想要从中获得什么?
架构师的思维,当一个框架不符合主流时候是怎么思考的,spring是为解决什么问题出现的?
spring相关的发展历史
- 不符合的原因
- 分析我们真正需要的是什么。
- 替代方案,解决方法
Chapeter 1
Why without ?
EJB存在的问题
- EJB规范中的一些部分已经过时,J2SE1.3引入的动态代理(dynamicproxy)
- EJB和RMI之间那种传统的紧密关系也开始显得有些不合时宜(local 和 remote 的调用?)这一方面是因为webservices 的迅速发展,另一方面是因为人们发现:很多时候 EJB 只需要本地接口
- EJB 最善于实现业务对象分布的体系结构,然而这种体系结构究竟有多大程度的普遍性
- SLSB (无状态session bean)和 MDB 使用较多,整个容器成本高昂
- EJB的复杂性,EJB规范的复杂性 ->开发效率
- TDD流行 ,难以测试
- 对于 EJB 致力解决的中间件问题,面向方面的程序设计(Aspect Oriented Programming,AOP)
EJB 试图解决太多的问题,其中很多问题本不应该由它来解决的。
J2EE还剩下什么
EJB只是J2EE的一种实现框架。因为这些库和框架不仅可以让我们摆脱使用 J2EE 服务的复杂度,而且也不会招致 EJB 所带来的复杂度。
J2EE 都是一个伟大的成功:
- 它成功地在从前没有标准的地方建立了标准;
- 它大大提升了企业级软件的开放程度;
- 并且它得到了整个行业和开发者的广泛认可。
J2EE 在易用性方面存在着严重的问题
Core J2EE Patterns,书中已经开始提倡使 用普通 Java 对象。
以规范为驱动的问题
有状态 session bean,状态的复制带来了很多微妙棘手的问题,所以大多数架构师总是尽量避免使用有状态 session bean。
如果希望开发者遵循 J2EE 规范,那么 J2EE 规范首先必须是一个实用、易用的规范。
J2EE 项目具备架构重构能力的关键
简单、效率、面向对象(思想)、业务需求至上、可测试性
遵循良好的 OO 设计法则,并且始终针对接口编程、而非针对类编程。这是经典图书
Design Patterns 教给我们的基本常识,可惜人们常常忽视了这一点。
将EJB之类的技术隐藏在普通Java对象背后。
利用现有的框架提供这些基础设施服务
spring
基础框架的设计甚至早于Expert One-on-One J2EE Design and Development的写作,
它们来自我过去几个商业项目的经验。
Chapeter 5 EJB的5年间
不应该以规范先行 ,而应该开源引导
EJB出现的背景,制定标准 (好处是 强制接口实现分离 、容器的概念、管理对象,粗粒度)
rmi到Ws (SOAP 是基于 XML 的简易协议,可使应用程序在 HTTP 之上进行信息交换。使用描述语言WSDL)
需要EJB中的什么(从中获取价值,并用简单的方式实现)
- 声明式事务(编程式事务可以解决复杂的事务、 JTA webLogic)
- 远程调用(协议。JMS、 ws)
- 集群(web层、数据访问层、数据库。真正限制是在数据访问 吞吐、并置的应用更有效)
- 线程池(避免jvm垃圾回收、tomcat的线程池)和资源池
- 安全(web层、tomcat filter、springmvc filter)
- 管理业务对象(JNDI、重量级工厂 、ioc抄袭、spring提供基于配置 而不是代码、picoContainer、EJB提供了一个重量级工厂(实现、部署EJB、使用JNDI 应用代码)、消除了接口与实现之间的耦合。)
总结
SLSB、 MDB entity beans 性能、最好设计成哑数据(贫血模型) 不包含业务逻辑
不想要什么
- 容器的锁定
限制应用服务器的选择
只使用一小部分,却要接受其复杂性(不能按需引入)
业务对象会被EJB API浸入
不能在容器之外复用业务逻辑
- 丑陋的结构、泛滥的类
实现一个session bean ,至少需要三个Java源文件home接口 、组件接口 、bean实现类。通常还需要业务接口,来保持bean和组件的同步。
- 部署描述文件的地狱
描述文件冗长,依赖代码生成工具,不可手工维护
- ==类加载器的地狱==
EJB容器与web容器使用的不是一个类加载器
EJB类加载器是WAR类加载器的父亲。 EJB类加载器不能看到WAR类加载器加载的类?
- 测试
依赖容器导致问题
简单的事情变困难
用EJB实现singleton
在EJB容器启动时做一些处理 (servelt listener 、web的listener 或者是bean的初始化后置操作等 、同时提供了依赖关系和顺序的支持)
在EJB之间以及EJB和EJB容器外的对象之间的共享配置
不能自由访问其他Java API 禁止访问一些Java API
EJB3.0(JSR 220 2003年6月)
主要动机是容易使用 降低EJB开发者使用时的复杂度,改良EJB的体系架构
使用源码级元数据 ->废除部署描述文件。
提供一个简单、基于元数据标注的依赖注入机制。
采用新的持久化机制。Hibernate采用的持久化方式
时间太长、不大可能引入AOP方案、还是依赖特定EJB容器。(从最近看webflux的做法,决定减少对servelt的依赖可以看出。不强依赖于Servelt,从而达到不依赖于特定服务器)
YAGNI
Chapter 6 轻量级容器
容器需提供的服务
生命周期,回调
查看服务 容器的核心是工厂
配置管理 统一方法来配置运行其中的对象
依赖管理
增值服务
企业级服务 ,事务管理或其他声明式服务
线程管理
对象池
集群服务
管理 jmx或暴露接口
远程服务 http 多协议
暴露
消费
可定制性和扩展性
EJB容器 管理的是粗粒度的组件(多个对象组合)
IOC
利用DI 消除lookup代码,让容器自动决定对象间的依赖关系
依赖查找 容器管理对象的生命周期,受管对象则负责查找自己的依赖关系 JNDI
依赖注入 让容器全权去负责依赖查询,受管对象暴露Java Bean 的setter 方法或带参数的构造。(或者通过元数据)
设值方法注入 建立在JavaBean规范之上
构造注入(picoContainer团队发明)
可以指定init 和 destroy 方法
注入异常检查
自动装配 通过类型
对于可移植性
减少代码对容器的依赖
企业服务依赖容器,尽量以声明式而非编程式
代码风格
针对接口
优先使用strategy设计模式
明确每个对象责任,不要大而全 (大一统,而是应该职责明确,抽成组件化)
能依靠容器解决的问题,就不要自己编写代码
为什么spring 能从轻量级框架中脱引而出,提供企业级服务的框架紧密合作,允许开发者通过编程方式或声明方式轻松地访问各种企业级服务。(粘合剂作用,例如整合ssh)
Chapter 7 Spring框架介绍
spring不重复造轮子 例如没有logger组件
工厂bean 主要在spring框架内部使用
例如
JndiObjectFactoryBean
ProxyFactoryBean
TransactionProxyFactoryBean
RmiProxyFactoryBean
spring以统一的方式为多种j2ee服务提供了抽象,使得开发者灵活选择各种资源定位策略
最好不要依赖servlet环境,应该尽量使用spring的抽象,因为这样就不会依赖于任何环境
ApplicationContext
ApplicationEvent
MessageResource
ResourceLoader. use Resource
BeanFactoryAware
ApplicationContextAware
ResoureLoaderAware
BeanFactory的后处理
允许在底层bean工厂读取bean声明以后进行后处理,可以覆盖某个属性值,或是为某些属性提供占位值。
参考现成的实现
PropertyOverriderConfigurer
PropertyPlaceholderConfigurer
BeanPostProcessor
可以用于AOP代理
IoC容器强大在于:它几乎可以用于配置任何对象、框架和应用
Chapter 8 基于AOP概念的声明性中间件
为何AOP对J2EE的未来至关重要
为何AOP是J2EE without EJB的关键
OOP 有些时候无法避免代码重复
概念
- aspect 方面
- adivce 增强,拦截器
- Join point 连接点
- Point cut 切入点
历史
一些OOP设计模式已经解决了AOP希望解决的部分问题
Decorator
Observer
Chain of Responsibility
使用OO设计模式,不可能做到既保持被增强方法的强类型性、又不必自己动手为每个方法编写转发代码
拦截器 如 servlet 、EJB 等 ,存在的问题是 它们将被拦截的代码与特点的API或上下文环境绑在一起,大多损失了强类型性。
AOP的实现策略
- J2SE动态代理
java1.3y引入动态代理,调用必要的拦截器链,最后一个拦截器借助反射调用目标对象
好处:标准的语言特征
局限:针对接口
实现:spring
- 动态字节码生成
CGLIB包,被应用在Hibernate 2.x版本中,并被证明是一种成熟的技术
存在的问题,通过继承来实现代理的,所以无法为final方法提供代理
实现:spring、Hibernate
- Java代码生成
OOP设计模式,EJB代码生成策略,预设的方式,由于动态代理和动态字节码生成技术的出现,这种做法逐渐退出
- 使用定制的类加载器
对某个类的所有实例进行增强
风险:偏离了Java标准
实现:JBoss4、AspectWerkz
- 语言扩展
实现:AspectJ
springAOP的缺点
不支持字段拦截,但是封装性考虑是不应该
只有通过SpringIoc容器获取的对象才能进行增强,不能在类装载器层面进行增强
拦截器代码中没有强类型检查
AOP风险
拦截字段的风险 ,破坏封装性
太多的方面,维护
正交性,不依赖顺序,独立
测试 AOP提升可测试性,单元测试专注于业务逻辑
调试
性能 粒度
如果你给细粒度的持久化对象加上AOP增强,在每次操作将会有数百个持久化对象被创建出来,那么才会有开销问题。
一次涉及反射的方法调用需要耗费的时间是毫秒级的
一次数据库只读访问的时间开销通常是数十毫秒
通过浏览器访问web页面的网络延迟则是百毫秒级
AOP设计建议
渐进式、实用至上的方式来使用AOP
将AOP应用于业务对象,最有价值的用途就是在业务方法的粒度上提供通用的企业级服务
典型问题:
调用堆跟踪和性能监控
审计
消息通知(例如当特定的异常抛出时给管理员发送电子邮件)
不建议在非常细粒度的对象(例如持久化对象)进行增强
springAOP
一个可移植的服务层,类似于JTA、JDBC和别的底层API(将声明性服务从EJB容器中解耦出来,J2ee)
一种基于AOP的服务获取机制,基于Java
Chapter 9 事务管理
在一个 web层 、业务对象层 、数据访问层中,事务管理属于业务对象层,通过将数据库切换到手工提交事务的模式。这种模式业务对象层和数据访问层都绑定到了特定的事务处理策略和数据访问策略。
需要分离这些关注点
- 业务对象划分抽象事务,而无需关注事务涉及的数据库资源
- 数据访问对象获取数据库资源,无需关注数据库资源如何加入事务
传统J2EE 事务管理
使用全局容器事务:事务由应用服务器来管理,登记所有参与事务的资源。一旦数据访问对象使用了涉及事务的资源,应用服务器容器将根据需要进行提交或回滚。
底层设施是由容器实现的JTA,全局事务管理使用CMT
J2EE容器作为事务协调器
具备分布式事务的处理能力,应该完整支持遵循X/Open XA规范的两阶段提交协议(2-Phase-Commit)
第一阶段 事务协调器向所有相关资源发布 ‘准备’指令
第二阶段 等所有的资源准备好以后触发实际的提交动作
一、参与事务的资源必须被正确地配置好,例如JDBC,通过javax.sql.XADataSource接口实现类来建立JNDI DataSource
J2EE 1.3 引入参与事务的资源的统一模型 java连接器架构 (Java Connector Architecture)
二、使用特定的服务器特性来获取JTA内置的TransactionManage对象,TransactionManage对象允许数据访问框架注册到实物同步回调接口上
编程式事务管理(使用java代码) 通过JNDI,直接使用JTA UserTransaction (多个受控异常,没有共同父类,事务处理代码污染业务对象)
声明式事务管理(使用xml配置,注解的方式) 组件模型CMT ,建立在JTA基础设施之上的服务(只有EJB才能使用,解决了80%的问题,必须使用全局事务管理,EJB2.0才支持本地接口)
轻量级事务基础设施
提供的功能:
可编程的事务声明和一致的异常处理机制。错误是不可恢复的,所以应该采用非受控异常,并且所有的异常应该继承自一个公共的基础父类
在OPJO上面实现声明式事务,无需绑定重量级组件模型
可插入的事务策略,以及让资源能够自动加入事务的手段
为采用分布式容器事务而需要的JTA
独立的JDBC数据源
独立的JDO PersistenceManagerFactory
独立的Hibernate SessionFactory
不应该依赖J2EE容器提供的服务,例如JNDI数据源。切换事务策略和资源定义应该是可配置的。
Spring Framework的事务管理
事务声明
事务的属性 TransactionDefinition
事务传播类型 required 、supports 、mandatory、 requires new 、not support、 never
隔离级别 default 、ru、 rc、 rr 、serializable
超时
只读
基础设施接口 PlatfromTransactionManager
抽象了实际的具体事务策略,针对一个给定的TransactionDefinition符合一个TransactionStatus对象,并且对这个状态对象触发提交或回滚操作。
TransactionStatus对象代表当前运行中的事务。
setRollbackOnly 不会抛出异常
Invoking this method outside a Spring transactionally advised AOP invocation is a programming error and will result in a runtime exception.
编程式事务处理
直接使用 PlatfromTransactionManager
事务模板 TransactionTemplate
比直接使用JTA简单
声明式事务管理
避免EJB带来的缺陷
通用的 Aop ProxyFactoryBean 和 TransactionInterceptor
由于TransactionInterceptor是通过ThreadLocal来存取事务状态对象的。
一站式 TransactionProxyFactoryBean
优点:
把关联的配置组织在一起
不需要了解整个拦截器链
代理接口通过目标类自动确定,并不需要显示的指定
缺点:
丧失了更强的可配置能力
源代码级别的元数据(注解)
1.2开始支持,基于JDK5
事务管理策略
DataSourceTransactionManager
JtaTransactionManager
JdoTransactionManager
HibernateTransactionManager
Chapter10 持久化
常见持久化策略
持久化策略概览
推荐Martin Fowler在 Patterns of Enterprise Application Architecture (POEAA)
基于SQL 直接操作关系模型,事务脚本(transaction script ),业务逻辑组织在一个过程中,适用于集合查询和批量更新。
基于O/R 映射(对象-关系映射) ,查询相对简单,只需要取出很少的几行数据,并对这些数据进行选择新的更新。这些数据实体通常可以映射到持久化的Java对象,组成了领域模型(domain model),业务逻辑表现为对象之间的交互,而不是直接操作数据库里的表和字段。
一种简单的O/R映射就是active record ,一行记录都由对应的gateway类的一个实例来表现,这个持久化类提供insert、update、delete。每张表通常还有一个finder类。 将持久化操作定义在领域类内部。
而数据映射器(data mapper)的用途则是 在对象与数据库之间传递数据,并且保持这两者以及映射器的独立性。考虑持久化的问题。
透明持久化(transparent persistence)这个词通常就是指这种非侵入性的、提供工作单元(unit-of-work) ,例如Hibernate,session对象,维护状态被当前事务中的业务操作修改过的对象列表 。同时还扮演 identity map角色。
选择持久化映射
何时使用O/R映射
针对领域对象的 ‘加载/编辑/存储’ 流程
批量查询,更新和删除是单独进行
大量对象需要积极地缓存(通常出现在‘读操作对于写操作’的情况,web应用)
在领域对象与数据库表/字段之间有一个相当自然的对应关系
不需要对SQL进行特别优化。
使用O/R映射到好处
不必编写重复的JDBC代码来处理领域对象的实例
透明持久化,JDO使用编译器字节码修改的方式,使得StateManager能够知道对象字段的修改情况。Hibernate和TopLink则使用了快照比较的方式。Hibernate采用了运行期字节码生成,TopLink采用反射的架构,需要将对象注册到工作单元上。
持久化发展史
关系型映射发展史
1996年把 JDBC 加入j2SE1.1之中,将其作为RDBMS资源管理和数据访问的标注低级抽象层。
JDBC 2.0 和JDBC标准扩展(J2SE 1.2)
特性,可滚动结果集(ResultSet对象),新增javax.sql.DataSource接口
JDBC 3.0(J2SE1.4)
将JDBC标准扩展整合到J2SE的核心中,新特征,savePoint 、PreparedStatement
O/R映射发展史
1997-1998 TopLink,CocoBase ODMG
1999-2001 entity bean , JDO
entity bean ,j2ee ejb 1.1的发布,崛起,但是并没有促进O/R映射的发展,反而是阻碍
JDO java Data Objects
2002-2003: TopLink, Hibernate,ibatis数据库层
TopLink Oracle收购,提供类似JDO 的API
Hibernate 在JDBC之上提供一层薄薄的封装,在提供完全透明的持久化机制的同时,又提供尽可能多的灵活性。
ibatis 以SQL映射的形式提供了简单的O/R映射
2004:JDO稳步发展 Hibernate飞黄腾达
Hibernate成为JBoss4.0 CMP引擎的基石
JPA
11 May 2006:
The final release date of the JPA 1.0 specification was 11 May 2006 as part of Java Community Process JSR 220.
10 December 2009
The JPA 2.0 specification was released 10 December 2009 (The Java EE 6 platform requires JPA 2.0[1].)
22 April 2013
The JPA 2.1 specification was released 22 April 2013 (The Java EE 7 platform requires JPA 2.1[2].)
entity bean败笔
与EJB编程模型紧密耦合,CMP,依赖完整J2EE容器
开发部署工作量大
BMP实现麻烦,性能问题
EJB QL能力有限
EJB 2.1开始走向一个可用的O/R映射解决方案。
实践中的数据访问技术
细粒度的领域模型不应该用重量级的EJB组件来建模,而应该使用简单的Java对象-POJO
资源管理
连接工厂:通过它创建连接(DataSource 、SessionFactory)
连接:代表了与特定数据存储介质之间的通信会话(Connection、Session)
连接工厂会维护一个连接池,避免频繁的创建连接。
在哪里定义连接工厂?
在容器中定义一个JDBC DataSource对象,在应用程序定义O/R ,也可以使用JCA连接器在J2EE容器中定义
在哪里初始化连接工厂?
在ServletContextListener中初始化,或者特定J2EE容器产品启动类
如何获得连接工厂?
使用JNDI查找J2EE容器中定义的连接工厂。本地定义工厂,借助一个自制启动类绑定到JNDI
如何在同一条线程的多次方法调用之间复用连接?
使用ServletFilter来查找连接工厂,每次请求开始将一个连接绑定到ThreadLocal对象,当请求处理完成后再取消绑定。
事务与连接之间的关系是什么:事务驱动连接还是相反?
连接驱动事务,在数据访问或ServletFliter中管理
另一种是以J2EE的JTA驱动事务,并对连接工厂进行配置。
当异常发生的时候,如何保证连接正确关闭,而又不会破坏原来的异常?
每段代码前后加上 try/catch/finally。
以上虽然可以解决,但是都与特定环境绑定J2EE容器,Servlet
JDBC
SQL层面上操作关系数据库,JDBC是一个公认、强大的API。主要缺点在于,需要编写很多重复的基础设施代码。(iBATIS 映射和SPringJDBC模板支持,简化编码,整合资源管理与实务管理,并且在事务范围内复用连接)
iBATIS SQL映射
将使用JDBC的细节全部抽象隔离起来,SQL语句在XML文件中定义,并预留参数占位符,在执行时,占位符将被指定的参数值所取代。SQL查询时,结果字段将被映射到对象。
还可以缓存查询结果,缓存模型是针对每个查询语句分别指定的,并且可以指定哪些插入/更新/删除语句应该导致刷新特定缓存。
不提供透明持久化,不会对取出的对象进行任何变更。
与高级透明持久化相比,SQL层面上的映射有以下优点:
保持了SQL的全部能力
可以使用基于数据集的更新和删除高效地处理多行数据
可以毫无限制的使用统计函数(avg、sum、max和count)
可以轻松将领域对象映射到多张表的字段
缺点:
显示更新被修改对象
将应用层面的值转换成数据库兼容的值
没有实现工作单元和身份对应表,它不那么复杂。
JDO
规范
JDOQL java查询API
Hibernate
目标是在JDBC上提供一层薄薄的封装,同时提供完善的透明持久化;为应用程序增加O/R映射的语意,但又不脱离底层的关系数据库。
查询语言HQL提供了连接、统计函数等重要的关系型概念,与SQL不同是,查询是以领域对象熟悉的形式表现出来的。
核心连接接口是net.sf.hibernate.Session
快照对比 变更侦测 借助CGLIB以动态字节码生成的方式为持久对象创建运行时代理,从而降低了快照对比的性能损耗
状态管理
允许将持久对象断开与Session的关联,稍后又可以很容易地重建关联,持久化对象发送到客户端层,对象会暂时从事务中脱离,当用户提交时又回到事务。
好处就是:使得借助版本或时间戳实现跨多个请求、多个Session实例的乐观锁成为可能。
较为放松的状态管理源自 快照比较的变更侦测方式, 刷新数据库的时候将快照与持久对象的当前内容进行比较。从而将需要发出的更新语句减少到最低限度
@org.hibernate.annotations.Entity(dynamicInsert = true, dynamicUpdate = true)
延迟加载
数据访问对象模式
DAO 时最为重要的J2EE模式之一,也是GoF Strategy模式的一种特殊形式。
DAO和透明化持久化
典型的DAO 接口只针对相对简单、细粒度的持久化机制,当对象状态发送改变时,必须显式调用存储操作。他们没有区分一等对象(领域对象)和二等对象(从属性的领域对象,生命周期由父对象控制)。 JDBC
透明持久化解决方案,只需要对一等对象进行持久化操作,从属对象的操作则通过级联更新或删除隐含进行。(persistence by reachability) ps:复杂 不可控
DAO设计中的问题
数据访问操作的粒度
透明持久度和对象状态
事务范围和延迟加载
DAO基础设施的问题
同之前资源处理问题有写关系
组装
参与事务
异常处理
这些问题属于中间层领地,应该由应用框架来提供各种库与组件之间的整合办法。
使用spring框架进行数据访问
bean工厂和上下文容器可以轻松装配
清晰的事务模型
通用的数据库访问异常体系,很好地定义了事务与连接的关系,尤其是如何在事务之间重复使用连接,
对于各种持久化方式,Spring用形式统一的模板机制解决了关闭连接、处理异常等问题
下图是访问异常体系
Chapter11 远程调用
RMI/EJB/JAX-RPC (java)
都是传统RMI模型:服务接口需要继承一个标记接口,并且每个方法都需要声明抛出受控的RemoteException异常。
Webservice(平台无关调用)
WSDL( Web Service Definition Language ) 语言
WSDL is an XML format for describing network services as a set of endpoints operating on messages containing either document-oriented or procedure-oriented information.
SOAP(Simple Object Access Protocol) 协议
SOAP (abbreviation for Simple Object Access Protocol) is a messaging protocol specification for exchanging structured information in the implementation of web services in computer networks. Its purpose is to provide extensibility, neutrality and independence. It uses XML Information Set for its message format, and relies on application layer protocols, most often Hypertext Transfer Protocol (HTTP) or Simple Mail Transfer Protocol (SMTP), for message negotiation and transmission.
对于java远程调用而言,并不是一个令人信服的选择,因为它对方法参数有诸多限制,部署也相当麻烦。
A WSDL is an XML document that describes a web service. It actually stands for Web Services Description Language.
SOAP is an XML-based protocol that lets you exchange info over a particular protocol (can be HTTP or SMTP, for example) between applications. It stands for Simple Object Access Protocol and uses XML for its messaging format to relay the information.
REST is an architectural style of networked systems and stands for Representational State Transfer. It's not a standard itself, but does use standards such as HTTP, URL, XML, etc.
Ws相关子协议
JAX-RPC
EJB端点JSR-109 J2ee 1.4
轻量级远程方案(平台无关调用)
RMI环境配置相当麻烦,并且它使用的网络端口常常被防火墙禁止。
基于WSDL和SOAP 的web services又很难以一种==可移植==的方式导出,并且它们的协议臃肿冗长,会浪费大量带宽。
基于HTTP的轻量级远程调用协议(lightweight HTTP-based remotion protocol)解决了上述两个问题:它们可以在任何标准的servlet容器之上运行,并且可以穿越任何防火墙。
基于HTTP的远程服务有一个特别的好处:它们可以很轻松地利用web服务器提供的权限管理、加密、压缩等能力—可以要求对特定的资源访问进行身份认证,可以使用SSL传输,可以对HTTP应答进行GZIP压缩,等等。
Hessian/burlap 比ws效率高
Hessian :二进制,简约、效率高
burlap的优点在于:基于XML,它传输的消息可以被人读懂,也可以被XML解析器解析。
relationships between http and servlet
A servlet is a 'module' that can be integrated into a server application to respond to client requests. Although a servlet need not use a specific protocol, we will use the HTTP protocol for communication (see figure 21.1). In practice, the term servlet refers to an HTTP servlet.
The classic method of constructing dynamic HTML pages on a server is to use CGI (Common Gateway Interface) commands. These take as argument a URL which can contain data coming from an HTML form. The execution then produces a new HTML page which is sent to the client. The following links describe the HTTP and CGI protocols.
Link : https://caml.inria.fr/pub/docs/oreilly-book/html/book-ora196.html
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 951488791@qq.com