J2EE概述
J2EE的产生 J2EE的背景 随着Internet的飞快发展和企业信息电子化的速度加快,应用对新语言,新标准,新模式的需求越来越强烈。1995年Java语言应运而生了,Sun推出的这个专注于网络计算的语言在网络分布式应用中如鱼得水,并且取得了举足轻重的作用。 回顾计算机技术在网络中的应用: 最初我们在网络中所用的计算机主要是为了解决单机模式的天生缺陷,单机模式下计算机之间最大的问题就是共享非常困难,基本上资源的共享,应用的协同工作无法进行,于是我们所熟知的C/S(Client/Server)模式就产生了。虽然它解决了数据与资源的共享,但是协同工作并没有解决,并且产生了其他的新问题,比如系统的维护与升级变得非常困难; 随之产生的就是与C/S模式的胖客户端对应的瘦客户端,由于1994年Web技术的兴起,基于浏览器的B/S(Browser/Server)瘦客户端,代替了C/S模式,这种模式解决了前面所提到的问题,但是由于企业应用的推广,电子商务功能的复杂性,以及提出的各种非功能性和性能,安全方面的要求,B/S模式也随之面临被替代的命运; 接下来这个阶段是网络应用非常复杂,也是新技术涌现的年代。由于基于Web技术的服务器(我们称之为Web服务器),承担各种角色,也承载了各种非功能性的,以及业务流方面的工作,直接导致Web服务器成为了整个框架性能的最终瓶颈。于是我们常提到的中间层(业务流层)就被分离出来了,由原来的两层结构进化成了现在的多层结构。 在这里需要提出的是,中间件技术在对非功能性和性能,安全方面的管理起到了非常重要的作用,中间件作为与OS(Operating System),DBS(Database System)齐名的三大软件支柱,发展历史非常长,早在上世纪八十年代就已经出现了,在接下来的十年由于Web技术的诞生,中间件的作用更是异乎寻常的得到无论是企业还是科研机构的重视。中间件由开始的RPC(Remote Procedure Call)中间件,发展到消息中间件,对象中间件等等。 J2EE就是在这样的环境之下,于1999年底Sun推出了Java2技术为基础的J2EE规范,这个规范提供了平台无关的,可移植的,安全的并且完全基于Java技术的服务器端中间件标准。J2EE的推出,使得中间件市场走向成熟,从中间件本身的角度来看,实现了J2EE规范的应用服务器是对象中间件;从整体架构来看,应用服务器涵盖了Web服务器,以及其他的服务器。 什么是J2EE 正如上面提到的,J2EE的核心是一组规范与指南,定义了开发企业应用系统的标准平台,由J2EE应用服务器的供应商来确保不同J2EE平台之间的兼容。 Java 2平台有三个版本,标准版本(J2SE),企业版本(J2EE)和微版本(J2ME)。 这里首先介绍J2SE,因为J2EE是建立在J2SE(Java 2 Platform Standard Edition)。J2SE主要适用GUI的客户端程序,也就是通常所说的桌面应用,并且为我们提供了Java编程常用到的核心包; J2EE的主要组成部分有J2EE平台,J2EE规范(Platform Specification),参考实现(Reference Implementation),兼容性测试套件(Compatibility Test Suite)和J2EE蓝图(J2EE BluePrints)。 J2EE平台主要就是利用Java2平台的标准版来为当前的企业级应用提供解决方案的设计,开发,装配和部署,并定义了一组核心API标准的接口。 J2EE规范,有相应的技术规范并对API进行了解释; 参考实现则是关于J2EE平台语法的正确范例; 兼容性测试套件可以使不同J2EE版本的产品可以运行的程序; J2EE蓝图则是提供了基于J2EE多层应用的实例与文档,主要参考PetStore,Adventure Builder。 J2EE的发展 1997年Servlet技术的产生以及紧接着JSP的产生,为Java对抗PHP,ASP等等服务器端语言带来了筹码。1998年,Sun发布了EJB1.0标准,至此J2EE平台的三个核心技术都已经出现。于是,1999年,Sun正式发布了J2EE的第一个版本。并与1999年底发布了J2EE1.2,在2001年发布了J2EE1.3,在前年年底也就是2003年发布了J2EE1.4。 J2EE1.3 以下就是J2EE1.3的架构图,其中主要包含了Applet容器,Application Client容器,Web容器和EJB容器,并且包含了Web Component,EJB Component,Application Client Component,以JMS,JAAS,JAXP,JDBC,JAF,JavaMail,JTA等等技术做为基础。 1.3中引入了几个值得注意的功能:Java消息服务(定义了JMS的一组API),J2EE连接器技术(定义了扩展J2EE服务到非J2EE应用程序的标准),XML解析器的一组Java API,Servlet2.3,JSP1.2也都进行了性能扩展与优化,全新的CMP组件模型和MDB(消息Bean)。 J2EE1.4 J2EE1.4大体上的框架和J2EE1.3是一致的,1.4增加了对Web服务的支持,主要是Web Service,JAX-RPC,SAAJ,JAXR,还对EJB的消息传递机制进行了完善(EJB2.1),部署与管理工具的增强(JMX),以及新版本的Servlet2.4和JSP2.0使得Web应用更加容易。 J2EE基础与关键技术 J2EE相关的几个概念 J2EE框架是两个重要的概念之上,组件与容器。 组件是一个可以重复利用的单元,这里的组件不同与一般(我们常说的)组件,这是J2EE组件,也就是说组件属于Web组件,EJB组件,客户端组件,或者是应用组件其中的一种。每个组件都需要被打包,分别会打包成.war,.jar,.jar,.ear,每个组件由特定格式的xml描述符文件进行描述,而且服务器端的组件都需要被部署到应用服务器上面才能够被使用。 容器在应用服务器中就扮演了中间件的角色, 比如说Web容器就是为JSP,Servlet提供一个环境,使之不用关注系统问题; EJB容器则是为EJB组件提供各种系统级别的服务,比如事务管理,安全管理,并且对EJB组件进行高效的管理。 J2EE基础 Java Java语言是J2EE的基础,整个体系架构都是通过Java语言来描述的,而且所有的J2EE应用服务器都是通过Java语言来实现的。所以在J2EE的产品中Java无所不在。 Http(Hyper Text Transfer Protocol),SSL3.0(Secure Socket Layer) Http(超文本传输协议)用于在Web服务器与本地浏览器之间进行文本的传输,保证文本传输的正确性,但是由于安全性方面的考虑,在J2EE的应用中使用了SSL协议与Http协议的结合,SSL(安全套接层协议)主要是通过X.509数字证书技术保护信息传输的机密性和完整性,适用于Web Server的点到点方式传输。 从J2EE的体系架构图中可看出客户端,无论是Applet容器还是Client Application容器都是通过Http,SSL协议经由网络来与Web容器,EJB容器中的组件进行交互的。若考虑多台应用服务器的集群,那么Web容器,EJB容器之间也将会通过Http,SSL协议进行交互。 Xml(eXtensible Marker Language) XML是一种可扩展的标记语言,其主要的用途体现在其良好的数据表示能力和数据传输能力,通过DTD或者是XSD对数据元素进行描述,也可以通过XSLT将XML与HTML,WML等等进行匹配。 在J2EE中的应用主要集中在组件描述符文件和Web服务上面,通过描述符文件对各个组件进行非功能性或者安全方面的控制,以及管理。所以可以说XML是J2EE中最基本的技术之一。 J2EE框架的组成 基本上通过J2EE框架图可以大致看出层次的分解情况来,我们把J2EE整个框架分为客户端,表示(Web)层,业务逻辑(EJB)层,企业信息(EIS)层; 客户端:就是需求方,可以是Browser,也可以是一般的Application Client; 表示层:主要就是通过Servlet,JSP等技术进行服务器端的Web组件的编程,并且协调与客户端之间,与业务逻辑层之间的数据传递; 业务逻辑层:主要是通过EJB,JMS来实现比较复杂的业务逻辑以及数据库存储工作,并且可以通过容器来进行管理事务,安全问题,并且可以对业务逻辑层的组件进行生命周期的管理; 企业信息层:主要是指企业信息系统软件,包括企业基础设施系统,如ERP(企业资源计划),CRM(客户关系管理),DBS(数据库系统)和企业遗留系统。从J2EE1.3开始,就有Connector架构标准化了J2EE平台连接到EIS上的API。
关键技术
关于J2EE的技术,规范之多,难以全部一下子谈清楚,接下来将抓住几个关键的技术进行说明。 Servlet,JSP,EJB,JMS,JavaMail,JDBC JTA,JNDI,RMI-IIOP, JAXP,JAX-RPC,SAAJ,JAXR, J2EE Connector Architecture,Management,Deployment JACC(Java Authorization Service Provider Contract for Container) 核心技术 这里主要谈的就是Servlet,JSP,EJB三大核心技术和JMS技术。 Servlet与JSP基于请求相应的工作方式,共同工作于Web层,其作用就是我们通常所说的表示层功能,但是他们的全部功能并不止如此: Servlet技术作为Web服务器功能的增强器,其功能涵盖了从客户端请求相应生动态生成文档到保证会话安全,访问后台DBS等等,但是由于整体框架的需求Web程序员所面对的Servlet编程都是其一小部分,比如说页面之间简单的逻辑控制等等。 Servlet一般作为Servlet容器或者Web容器中的组件进行管理,有其自己的生命周期,每个Servlet都需要实现Servlet接口,有init()和destroy()来进行生命周期的管理,其主要的逻辑将集中在service()中,特殊的,对于基于HTTP的HttpServlet,主要逻辑集中在doGet()和doPost()中。需要指出的是,为了便于编程,以及其他的原因Servlet被设置成为单线程的。 从API可以看出,Servlet的核心主要集中在javax.servlet和javax.servlet.http两个包中,两个包分别定义了关于Servlet与Servlet容器之间的接口,以及对Servlet自身的一些支持,比如过滤,请求相应,会话以及Cookie的支持。 JSP作为Servlet技术的扩展,简化动态Web内容的传输,由四个关键的组件组成:指令,动作,脚本和标签库。指令是指Web程序员通过编程方式通知支持JSP的Web容器进行定制,比如说错误网页或者是定制的标签库或者其他资源;动作则是对网页的动态包含资源或者插件,提交转发,使用JavaBean实例等等进行定义与操作;脚本则是支持Java语言的逻辑流,通过特定的标记隔离;标签库包括标准标签库和定制标签库,主要是用于对Web内容显示的一种组件方式的定制,标签库的定义主要由标签句柄类和标签库描述文档组成,句柄类对定制标签的内容进行定义的一个类,一般要实现Tag这个接口,标签库描述符则是对标签库进行描述,并且与某个句柄类进行相关联。 这里需要顺带提到的是JSF(Java Server Faces)这个技术主要是集中在Web内容的显示方面,其作用是J2SE中简化的Swing或者是SWT,JSF有其自身的组件及其事件处理机制和Validate技术。同时JSF也定义了一组JSP的定制标签库,使其作为JSP的一个扩展技术。 Servlet和JSP最新的版本是Servlet2.4和JSP2.0,Servlet增加了对XSD(Xml Schema Definition)的支持,增加了ServletRequest相关的Listener机制,增强了RequestDispatcher和Filter的结合功能,使得RequestDispatcher的功能更加容易;JSP则引入了EL(表达式语言),也增加了SimpleTag的实现,方便了编程。 EJB(Enterprise JavaBean)是自从98年发布了第一个版本以来就不断的进行修改与完善,由原来的EJB1.x,EJB2.0,到现在的2.1,甚至即将发布的3.0,EJB技术在面临各种挑战的同时,正在朝着更加成熟,自我完善的方向发展。 EJB组件作为EJB容器中的一个管理单元,EJB组件提供商可以选择由容器来管理EJB组件的事务,安全,资源连接问题等等。 EJB主要是由三种Bean组成,会话Bean,实体Bean和消息Bean,EJB2.0开始实体Bean就以全新的模型出现,而消息Bean也是在EJB2.0才引入的。 会话Bean主要有有状态与无状态之分,两者的区别仅仅在会话状态的维护上面,会话Bean可以作为客户端的状态来理解,客户端是操作与状态的集合;实体Bean就是对持久化的管理,当然实体Bean可以分为BMP(Bean Managed Persistence)和CMP(Container Managed Persistence),其分歧也就在对持久化的管理方面,这两种实体Bean各有各的好处,BMP在于其灵活性,直接对底层数据库进行持久化操作,虽然编码的代价比较高,但是正是由于这一点才给了开发者以更多的开发空间;而CMP则是通过EJB2.0中引入的EJB QL提供标准接口,屏蔽掉了JDBC驱动的操作,以此通过EJB容器来对持久化进行管理。 EJB的调用过程大致上来说是分为以下几步: 根据传入的属性,初始化上下文InitialContext; 获取远程的,或者本地的Home接口; 然后进行Home.create(),获取远程EJB对象; 通过EJB对象调用业务方法,这些业务方法会被EJB实现。 消息Bean是可以接受JMS消息的EJB,并且通过特定固有的方式对JMS消息进行处理。这个Bean没有复杂的Home,或者是EJBObject接口。 从J2EE的API看来,这部分主要集中在javax.ejb中,这个包主要定义了各类的编程接口。 JMS(Java Message Service)作为一种消息传递的标准,出现的时机是在消息中间件(MOM)私有发展的年代,正式由于JMS的标准化,使得开发人员无需学习新的消息机制的API,甚至其机制,只需要了解提供的JMS规范即可。 JMS的消息传递机制分为两种,发布订阅式(P/S)和点对点式(P2P): 两种消息的传递机制都实现了异步传递模式,其区别就在于前者通过Topic的形式,是的多个Consumer都可以使用,主要是进行了Subscribe;后者则是通过Queue的形式,将Consumer和Producer之间进行了安全连接,使得消息传递只在这两者之间进行。 基础技术 这里所提到的基础技术主要集中在JDBC,JNDI,RMI-IIOP ,JTA等技术的讨论。 JDBC是DB引擎与开发人员的JDBC程序之间的接口,JDBC提供了操作DB的规范,故而经常称JDBC为JDBC驱动。我们常用的JDBC驱动程序大致可以分为四种: JDBC驱动程序是对另外一种数据访问的映射,如果ODBC,即ODBC-JDBC,这种驱动依赖于本地库文件,不易移植; JDBC驱动程序部分由Java编写,部分由本地代码实现,依赖于特定的数据库端库文件; JDBC驱动程序全部采用Java实现,是所谓的网络桥,通过独立于数据库的协议与服务器进行通信; JDBC驱动程序全部采用Java实现,实现针对某一特定数据源的通信协议,直接与数据源通信。 JNDI(Java Naming and Directory Interface)作为J2EE规范的一部分,为定位用户,资源与服务提供了一个标准的接口。JNDI其中包括了命名与目录服务,命名服务随处可见,比如我们的文件系统中的命名服务,DNS中的命名服务等等,目录服务就是命名服务的扩展,将各个被命名的信元组成树状的目录,便于查找,挂载卸载以及其他操作。JNDI作为客户端与命名和目录服务的访问接口,屏蔽了各种命名和目录服务的细节,使得开发人员可以在各种服务之间进行访问。JNDI由两个部分组成客户端接口API和服务提供商接口SPI,API面向开发人员,SPI则面向不同的命名和目录服务提供者。 在J2EE中,正如我们前面在EJB和JMS中讨论那样,如果需要查找某个EJB或者是JMS驱动程序,都可以通过JNDI来获得,只要我们在EJB描述符中进行描述,并且部署了EJB就可以找到。 JNDI的API主要由javax.naming,javax.naming.directory,javax.naming.event,javax.naming.ldap; JNDI的SPI在javax.naming.spi中; javax.naming提供了访问命名服务的接口,比如Context接口,javax.naming.directory提供了对目录服务的接口,javax.naming.event则是对服务的事件机制的支持。 RMI-IIOP(Remote Method Invocation to Internet Inter-ORB Protocol) 是J2EE执行远程调用的一种方法。 事实上,Java也有另外一种方式RMI(远程方法调用),RMI使得对象可以在多个VM(虚拟机)之间进行传递,通过RMIRegistry提供命名服务使用Naming进行交互。RMI的交互方式是Stub和一个远程对象进行直接的调用,Stub被下载到客户端用来通信,在Java1.2之前,会产生一个Skeleton来与Stub对应。 RMI-IIOP与RMI的主要区别仅仅在于RMI-IIOP实现了与CORBA的互操作性,实现仅支持Java的RMI也可以对其他语言实现基于CORBA的远程方法进行的调用。 JTA(Java Transaction API)是J2EE架构中性能保证的一个基本技术。正如在DB中,事务保证了操作的ACID(Atoming,Consitency,Isolation,Duration)性,J2EE的事务服务在各种容器中,为EJB提供了良好性能的保证。 J2EE的事务分为两个大部分:JTS(Java事务服务)和JTA(Java事务API)。JTS完成了到CORBA OTS事务监控的基本实现,并且规定了事务管理器的实现方式。JTA则是由事务管理器在高层进行支持的,并且实现了OTS规范的Java映像。JTS事务管理器为资源管理器,应用程序提供了事务服务。 这里顺带提出一下OTS(对象事务服务),这是个基于CORBA模型并定义了一系列跨越多个CORBA对象完成事务处理的接口。 Web服务相关技术 对Web服务的支持是在J2EE1.4中开始引入的,主要对JAX-RPC,JAXR,SAAJ等规范进行了定义, 接下来对Web服务及其在J2EE中的应用进行讨论,主要集中在SOAP,UDDI,WSAD,JAXP,JAX-RPC,SAAJ,JAXR。 首先对Web服务的几个基本技术进行介绍: SOAP(Simple Object Access Protocol)是基于XML来交换信息的轻便协议,通常由soap-envelope,soap-encodingStyle,soap-rpc三部分组成,soap-envelope定义了消息的总体框架,表示其中有什么信息,谁来处理,并且可以确定是否是强制性的;soap-encodingStyle主要用来定义交换的数据类型,也就是通常所说的串行化机制,默认值是 http://schemas.xmlsoap.org/soap/encoding/;soap-rpc则是用于远程调用与应答。 WSDL(WebService Description Language)是用来对每个Web服务进行描述的.wsdl文件,客户端使用某个Web服务时,必须先下载其描述文件,这样才能够对Web服务发出请求,WSDL是XML的一种变体,描述了Web服务的操作,协议,以及服务所在的URL地址。 UDDI(Universal Description,Discovery,Integration)提供了发现,描述,集成Web服务的规范。UDDI注册中心为我们提供了注册自己的Web服务的空间,一般而言注册中心的数据被分为三个部分: 白页:包含注册Web服务的单位的基本信息,其中包括单位的唯一标准符; 黄页:主要通过不同的方式对注册的Web服务进行分类,便于查找; 绿页:主要是对某个单位的Web服务进行技术细节,位置细节的描述。 接下来介绍Web Service在J2EE架构中的应用: Web Service for J2EE是J2EE平台台下Web服务的总规范,定义了基于J2EE的应用服务器如何支持Web服务,即定义了客户端模型,服务器端模型,部署模型WSDL绑定和安全相关规范。并且通过JAX-RPC(JSR101)进行构建,只要是满足JSR109的Web服务。另外在J2EE中Web服务可以基于两种方式的实现: 基于Servlet的服务,由Web容器提供运行环境; 基于无状态会话Bean的服务,但是需要注意的是,只有EJB2.1以上的版本才提供Web服务的包装。 基于XML相关的Java API:JAXP,JAXB JAXP(Java API for Xml Processing)通过基于模型的DOM和基于事件处理的SAX对XML进行处理的API,JAXP屏蔽了底层使用的XML解析器,同时也支持对XSLT的支持,通过JAXP的接口对XML进行转换至其他的格式如HTML,WMl等; JAXB(Java API for Xml Data-binding)主要用于Xml文档模型与Java对象之间的绑定; 基于Web服务相的Java API:JAX-RPC,SAAJ,JAXR JAX-RPC是Web服务在J2EE中的核心技术,基于远程过程调用,类似于RMI,在JAX-RPC的调用过程中,用的是SOAP作为底层的传输协议进行通信。JAX-RPC提供了RPC的运行时环境,定义了服务器端编程模型,和客户端编程模型,还定义了WSDL与Java之间的映射,包括了类型的映射,端口类型,服务,绑定到Java类和接口的映射。 SAAJ(SOAP with Attatchment API for Java)为传递SOAP提供了简洁,统一的的API,以便支持SOAP附带附件。 JAXR提供了UDDI在J2EE中的实现,是Web服务注册和发布相关的API标准,为所有的Web服务提供访问的接口,也就是为访问注册中心提供一个编程接口。 其他技术 JCA(J2EE Connector Architecture)使得J2EE组件比如EJB组件,可以与EIS比如,ERP,CRM,大型事务处理系统等等进行交互。JCA中非常重要的一个概念就是Resource Adapter(资源适配器),连接到EIS上去需要把RA部署到服务器上去,RA一般都是以Resource Adapter Archive(RAR)的格式进行存储部署。然后通过CCI(Common Client Interface)编程接口对EIS进行操作。 Resource Adapter定义了两种约束,应用约束和系统约束。这两种约束分别对应J2EE组件访问EIS的规则,系统约束则是提供了服务器管理的重要服务:事务管理,安全管理和连接管理,建立与RA之间的规则。 J2EE的应用现状 上个世纪八十年代末,中间件思想的提出与发展为新事物的产生提供了架构上的准备,九十年代初,Internet的兴起为新事物产生提供了生长的环境,Java语言诞生为其提供了肥沃的土壤,加上企业应用的日益增加,中间件的进一步成熟,终于应用服务器在J2EE规范发布之后,如同雨后春笋般出现。应用服务器综合了各种中间件技术的优点,为新一代的企业开发提供系统架构,提供了分布对象的服务,事务处理服务,安全访问服务等等。 这个世纪初,国内的应用服务器研究也组件追上国外,比如金蝶的Apusic是国内第一个基于J2EE标准提出来的应用服务器,ONCE则是国内第一家基于J2EE1.4规范并通过其兼容性验证(CTS)的应用服务器。虽然从时间上来看落后,但是在技术上都可以看是很成熟的。 BEA WebLogic Server8.1 BEA公司的WebLogic Server发展至今日,从其产品和技术的角度来看,都已经非常成熟。其Server版本大致可以分为Express(入门级)和Enterprise。WebLogic Server有基于其私有的JRockit VM,并且集成了IDE(Workshop),方便了开发。 IBM WebSphere Application Server5.0.1 WebSphere Application Server是IBM所推出来的一款基于J2EE规范的应用服务器,WAS是基于Java Servlet引擎的,直接将Web Server扩展为基于Java的应用服务器。除了完全符合J2EE规范的EJB容器,Web容器等等之外,还有其自身的WebSphere MQ子系统,MQ为WAS提供了嵌入式JMS消息处理能力。 J2EE的前景 在开源日益受欢迎,竞争激烈的时代,J2EE无论在整体的框架还是在某些具体的技术上面都面临了巨大的挑战,整体框架上面临.NET的挑战,而在Web层,已经比较成熟的Struts在各种应用服务器以及其整合的IDE中都提供了Struts的支持,Struts主要是通过MVC的思想把Servlet的任务更加明确地作为Controller部分,JSP则只需要承担View这部分的工作,另外把业务层提供的Bean组件或者其他组件作为Model,这样就在整体的架构上又提取出来一个三层结构;EntityBean作为EJB的核心,而EJB又是J2EE平台的核心技术,在开源的攻击之下,疲于招架,轻量级Hibernate的持久化框架已经逐渐占据这块市场,而且大部分的应用服务器都已经对Hibernate提供了支持,而EJB面临的主要挑战还是来自其自身,由于其编程的复杂性而吓走了一部分的用户,另外就是其饱受批评的持久化性能,但是在接下来随着J2SE5 Tiger的发布,其新特性Annotation的推出,将为其争回这部分的市场带来了法码,首先,Annotation的提出大大降低了编程的复杂性,降低了代码的编写量;其次Annotation本身的学习代价比较低;再次EJB的架构从本质上来说并非非常困难的,甚至可以说是简单的,易于学习的,通过简化结构之后使得开发人员的任务变得更加的清晰,结构层次的学习也变得非常容易。 就像任何生物不可能在真空中生存一下,任何的技术都不可能在没有竞争的环境之下发展,J2EE架构很大程度上的发展都来自于这些开源项目的思想。JCP的专家们就需要在业界选择最好的,最有利的框架加以利用。 规范与规范的实现两者存在的是一种促进的关系,开源的JBoss应用服务器的快速发展,以及其微内核,基于JMX的可查拔插件方式给人一种新鲜感,就如同现在如火如荼的Eclipse平台一样,其插件方式是否能够给J2EE带来新感觉?AOP思想的出现,JBoss的行动总是那么的迅速,在国内还没有多少人知道AOP什么东西的时候,它已经开始了JBoss AOP的开发,这许多许多的东西是否可以给我们带来新的感觉呢?还是专家们觉得技术不够成熟? |
J2EE标准(转)
最新推荐文章于 2024-09-03 20:17:53 发布