Liferay5架构及开发培训.ppt_第1页
Liferay5架构及开发培训.ppt_第2页
Liferay5架构及开发培训.ppt_第3页
Liferay5架构及开发培训.ppt_第4页
Liferay5架构及开发培训.ppt_第5页
已阅读5页,还剩44页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Contents,Liferay介绍,返回上级目录,返回目录,Liferay概述及特点,Liferay是专门为符合PortletAPI(JSR268)的门户单元设计开发的。而且有许多不错的门户单元附加在Lliferay中,包括邮件、文档库、日历、公告板等,它们也可以作为开发学习时的例子使用。LiferayPortal代表了完整的J2EE应用,使用了Web、EJB以及JMS等技术,特别是其前台界面部分使用Struts框架技术,基于XML的portlet配置文件可以自由地动态扩展,使用了WebServices来支持一些远程信息的获取,使用ApahceLucene实现全文检索功能。主要特点:1、提供单一登陆接口,多认证模式(LDAP或SQL);2、管理员能通过用户界面轻松管理用户,组,角色;3、用户能可以根据需要定制个性化的portallayout;4、能够在主流的J2EE应用服务器上运行,如JBoss+Jetty/Tomcat,JOnAS;5、支持主流的数据库,如PostgreSQL,MySQL;6、使用了第三放的开源项目,如Spring,Hibernate,Lucene,Struts;7、支持包括中文在内的多种语言;8、采用最先进的技术Java,EJB,JMS,SOAP,XML;,什么是Portal?,许斌,Portal是基于Web的,以“应用整合”和“消除信息孤岛”为最终目的,提供单点登录、内容聚合、个性化门户定制等功能的综合信息系统。完整的Portal通常由Portal服务器、Portlet容器、Portlet构成。,返回目录,PortletvsServlet开发,开发一个JavaPortlet类似于开发一个基于web应用的Servlet开发相似的地方:Portlet也是Java技术的web组件Portlet也是有特定的container在管理Portlet可以动态产生各种内容Portlet的生命周期由container所管理Portlet和客户端的互动是通过request/response的机制主要的区别在于:Portlet只能生成标记段,不是整个文档,Portal将会连接一些portlets的标记段并且创建一个整个页面返回给用户.接受请求的类必须继承javax.portlet.Portlet而不是javax.servlet.http.HttpServlet.一个portlet请求可能涉及两个状态进程:1.对于大多数的请求来说,一个portlet将会执行一个状态转换操作,这与action状态有关系,并且通过一个方法processAction来实现.并不是需要每一个Action状态.包含一个action状态的请求被注入到ActionURL,与此同时那些只含有renderphase的请求被注入到RenderURL.2.接下来所有与页面有关联的,将要被返回的其他的portlets的render状态可能会在任何将HTML标记段来描述他们自身的请求中来被调用.Portlet通过一个render方法实现这种功能.,返回目录,PortletvsServlet开发,Portlet有一些附加的功能是Servlet所没有的:Portlet能够存取及储存永久配置文件及定制资料。Portlet可以存取使用者数据Portlet具有URL的重写功能在文件中去动态建立连结,允许portalserver不用去知道如何在网页的片段之中建立连结及动作。Portlet可以储存临时性的数据在Portletsession之中,拥有两个不同的范围:application-widescope及Portletprivatescope。Portlet不具有一些功能,但是Servlet却有提供:Servlet具有设置输出的文字编码(charactersetencoding)方式Servlet可以设置HTTP输出的headerServlet才能够接收客户对于portal发出的URL请求,返回目录,Portlet的生命周期,一个Portlet有着良好的生命周期管理,定义了怎样装载,实例化和初始化,怎样响应来自客户端的请求及怎样送出服务。这个Portlet生命周期由Portlet接口的init,processAction,render和destroy方法来表达。载入和实例化:Portlet容器负责载入和实例化Portlet。当Portlet容器运行Portlet应用或者延迟到Portlet需要服务使用者的请求时,Portlet就会被载入并实例化。载入Portlet类后,Portlet类随即被实例化。初始化:Portlet类实例化后,Portlet容器还需要初始化Portlet。以调用Portlet去响应客户端的请求。Portlet容器呼叫Portlet接口中的init方法初始化Portlet。扩展自PortletConfig的类可以取出定义在部署描述文件中的初始化参数,以及ResourceBundle。初始化异常:在Portlet初始化期间,Portlet可能会丟出UnavailableException或PortletException异常。此时,Portlet容器不能把Portlet置入已启动的服务,并且Portlet容器必需释放这个Portlet。destory方法不能被呼叫,因为初始化被认为执行失败。发生失败后,Portlet容器会尝试着重新实例化及初始化Portlet。这个异常处理的规则是:由一个UnavailableException指定一个不能执行的最小时间,当此异常发生时,Portlet容器必需等到指定时间过去后才产生并且初始化一个新的Portlet。在初始化过程中所丟出的RuntimeException异常,被当作PortletException来处理。,返回目录,LiferayPortal工作原理(1),CompanyLogo,Portal系统根据需要由一个或者多个Portal页面组成,每个Portal页面包含零个或者多个的Portlet。每个Portlet呈现自己的信息内容,以此实现内容聚合。通过定义每个Portlet的可用权限,实现个性化的桌面信息定制。,每个Portlet对外表现为一个小窗口,有自己的默认样式和窗口状态。JSR168规范定义了三个Portlet模式:浏览、编辑和帮助。如右图,Portlet有自己的标题,浏览状态下支持编辑、关闭、上移、下移、最大化、最小化功能,编辑状态下支持返回和关闭功能。从各种数据来源提取的信息以Portlet内容的形式呈现在Portal中。同时Portal是可以根据使用者的角色,来决定是要提供(显示)哪几个Portlet模式给使用者操作。,返回目录,LiferayPortal工作原理(2),CompanyLogo,Portal页面创建过程如下:Portlet在Portlet容器内执行Portlet容器将这些内容提交给Portlet服务器,Portlet服务器依照这些内容建立Portal页面,然后将它传给客户端呈现。具体流程如右上图:,Portal页面的请求过程如下:使用者经由客户端设备(例如浏览器)存取Portal,Portal根据接收到的请求决定哪些Portlet需要被执行以满足需求。Portal通过Portlet容器呼叫Portlet,然后由Portlet产生的片段建立Portal页面,再传回客户端呈现给使用者。具体流程如右下图:,Portlet开发完毕后,部署到Portal服务器,由Portal服务器负责组织、权限控制现。,返回目录,JavaPortlet规范(JSR-268)和WSRP,JSR-268:由于Liferay支持Portlet规范(JSR-268).任何基于此规范的Portlet均可正常运行.Java平台提供了一种基于JSR-168的标准,标准化portlets如何与其他portlet容器集成并在不同的portal产品之间来保证兼容性.LiferayPortal提供了一种100%便利的portlet容器来保证任何基于标准规范的portlet将会在Liferay中运行在JSR-268规范中,一个portlet应用可以聚集其他的不同的portlets并且打包成一个WAR文件,就像一个标准的Javaweb应用一样.在WAR文件中,以portlet.xml来定义portlets的应用,portlet.xml文件放在WAR文件中的WEB-INF目录中.JavaPortlet规范包括portlet容器.,WSRP:WSRP是OASISWebServiceforRemotePortlet的缩写。WSRP是WebService的一种新的商业应用,一种新的标准,主要用来简化Portal对于各种资源或者程序整合的复杂度,可以避免编程带来的整合麻烦和问题。而且Portal管理员可以从海量的WSRP服务中选择需要的功能用以整合到目前所用的Portal中。它有三种角色:生产者提供Portlet消费者使用Portlet终端用户最终用户它的特点在于生产者将消费者所需要的信息通过WSRP返回给消费者,这些信息是相对标记片断,例如HTML、XHTML等,可以直接嵌入用户的页面中,而不用像WebService一样开发用户端接口。实现这个规范,Portal可以跟各式各样的数据源打交道,彻底终结信息孤岛的窘境。,返回目录,LiferayPortlet5.2.2开发推荐使用工具,JDK1.5,或者1.5-java开发工具包Jre1.5,或者1.6-java程序运行环境Jikes1.22-Jikes是一个IBM创建的Java编译器,比SunJDK的编译器要快.Ant1.7-一个基于Java的生成工具。Subversion-一个简单的版本控制工具,推荐你将所有的代码和配置文件放在一个版本控制工具中,Subversion是一个免费的开源的版本控制工具。Eclipse3.3+MyEclipse6.0-一个支持J2EE,Java,Web,portlet等开发的IDEMySQL5.0-一个主流的开源数据库Tomcat-5.5-Web服务器具体环境变量里面需要的配置有:JAVA_HOMED:ProgramFilesJavajdk1.5.0_16CLASSPATH.;%JAVA_HOME%libdt.jar;%JAVA_HOME%libtools.jar;%JAVA_HOME%jrelibJIKES_HOME,ANT_HOMEPath:%JAVA_HOME%bin;%JIKES_HOME%bin;%ANT_HOME%bin;,返回目录,LiferayPortlet5.2.2开发简单说明,无论是portal和ext工程,目录都很繁杂,其实我们只要关注3个目录就够了。这就是ext工程对应目录:ext-implsrcext-servicesrcportal-web而portal工程项目里面的3个目录:portal-implsrc和portal-servicesrc是portal工程已经实现的所有portlet的java代码和部分资源文件;portal-web目录是放置网页文件和portal的配置文件。ext工程对应目录ext-implsrc,ext-servicesrc和portal-web跟portal是很类似的。ext-implsrc,ext-servicesrc是放置我们自己开发的portlet的java代码。ext-web是自己开发portlet对应的网页文件和配置文件。,返回目录,Portlets开发介绍流程,ConfigurationPortlet的开发流程采用的也是StrutsPortlet的开发流程,Configuration,简单,复杂,JSPPortlet开发,JSPPortlet开发流程,JSPPortlet是开发中使用频率最高的开发方式,主要原因有两个:(1)当配置好Portlet之后,只需要修改JSP文件。而JSP文件支持hotdeploy,这就会在开发过程中节省好多等待antdeploy和liferaytomcatstartup的时间。(2)开发流程也相对简单。推荐的JSPPortlet推荐开发流程如右图,当然也不用完全按照如下流程来做,只要完成相关配置的修改即可。,在Liferay中创建一个JSPPortlet:,开发流程:1.定义portletportlet-ext.xml定义Portletliferay-portlet-ext.xml配置Portlet实例属性2.国际化配置文件Lperties3.归类PortletLiferay-display.xml分类组织Portlet4.创建JSPview.jsp定义我们需要的页面,开发目录结构:配置文件放在这个目录下:extext-webdocrootWEB-INFJSPs将会放在这个目录下:extext-webdocroothtmlportletext,Liferay如何决定哪个JSP应该被首先显示?对于JSPPortlet,JSP直接指向了从portlet-ext.xml中定义的页面.,定义portlet,My_JSP_PortletJSPPortletcom.liferay.util.bridges.jsp.JSPPortletview-jsp/html/portlet/ext/myjspportlet/view.jsp0text/htmlcom.liferay.portlet.StrutsResourceBundlepower-useruser,配置文件是:extext-webdocrootWEB-INFportlet-ext.xml,注意:1、Portlets是通过,来唯一定义的。因此,你要确保的唯一性。2、要创建JSPPortlet,属性应该设置为com.liferay.util.bridges.jsp.JSPPortlet。3、中的值“view-jsp”不能修改。4.、中的值-指定哪个JSP应该被首先显示,配置Portlet实例属性,分类组织,国际化,My_JSP_Portlettrue/css/test.css/js/test.js,定义Portlet实例属性:配置文件是:extext-webdocrootWEB-INFliferay-portlet-ext.xml,分类组织Portlets:配置文件是:extext-webdocrootWEB-INFliferay-display.xml,注意:这里的元素的值My_JSP_Portlet必须要和portlet-ext.xml中的元素的值一致的。,其中的key值(即javax.portlet.title.My_JSP_Portlet),是“javax.portlet.title”+“portlet名字”(即在portlet-ext.xml中添加的portlet的的值),定义Portlet名称:配置文件是:extext-implsrccontentLperties,javax.portlet.title.My_JSP_Portlet=MyJSPPortlet,JSP开发-创建JSP页面,创建JSP:在extext-webdocroothtmlportletext目录下创建文件目录myjspportlet在新建的myjspportlet目录下,添加一个文件叫init.jsp,在文件中加入下面内容:,现在,再在新建的myjspportlet目录下添加一个文件view.jsp在view.jsp中写下:,问题出来了,portal如何得知怎样加载这些特殊的文件?如果你返回观察添加到portlet-ext.xml中的portlet元素,你将会观察到你初始化了一个view-jsp参数,它的值是/ext/myjspportlet/view.jsp。通过指定这个init-param,你将使得portlet加载一个默认的JSP。,Hello,itsmyfirstjspportlet!,发布、运行和测试,发布:执行ext项目根目录下的build.xml文件antdeploy,部署这些你做的对你的应用的改变,然后重启tomcat服务器。,运行和测试:访问地址:http:/localhost:8080。利用用户名:test;密码:test登录进入系统。在选择应用的窗口中选择我们刚刚添加的PortletMyJSPPortlet,如果在页面上会增加一个Portlet(如下图),显示出你刚刚添加的内容,那么部署就成功了。,添加应用,选中添加,StrutsPortlet开发,StrutsPortlet开发流程,StrutsPortlet推荐的开发流程如下,当然也不用完全按照如下流程来做,只要完成相关配置的修改即可。,为什么用Struts?Struts实现了MVC.虽然有其他框架实现MVC,Struts是最广泛应用和最成熟的技术.什么是MVC?MVC将显示代码从业务逻辑中分离出来.Struts在struts-config.xml中提供了集中的页面流管理.这使得它高度可升级并且使得你模块化代码流程.通过使用struts,你可以使用一些最佳实践,已经集成在框架中.为什么用tiles?一个页面布局是一个使用包含典型声明的设计.如果有100个JSPs并且头和尾都需要改变,所有的100JSPs都需要改变.用tiles,一个简单的模板可以被用于定义页面布局.只要模板改变,所有页面将会依次改变。,在Liferay中创建一个StrutsPortlet:,开发流程:1.定义portletportlet-ext.xml定义Portletliferay-portlet-ext.xml配置Portlet实例属性2.国际化配置文件(定义Portlet名称)Lperties3.归类PortletLiferay-display.xml分类组织Portlet4.定义页面流和布局struts-config.xml定义页面流titles-defs.jsp定义页面布局5.定义ActionClass6.创建JSPview.jsp定义我们需要的页面,开发目录结构:配置文件放在这个目录下:extext-webdocrootWEB-INFJSPs将会放在这个目录下:extext-webdocroothtmlportletextStruts中Action放在这个目录下:extext-implsrccomportlet,注意:Liferay如何决定哪个JSP应该被首先显示?对于JSPPortlet,JSP直接指向了从portlet-ext.xml中定义的页面.对于Strutsportlets,这一系列过程通过tiles-defs.xml来定义.,“struts_action”链接到哪里?链接到struts-config.xml.,定义portlet,EXT_4LibraryPortletcom.liferay.portlet.StrutsPortletview-action/ext/library/add_book0text/htmlcom.liferay.portlet.StrutsResourceBundlepower-useruser,配置文件是:extext-webdocrootWEB-INFportlet-ext.xml,注意:1、Portlets是通过,来唯一定义的。因此,你要确保的唯一性。2、要创建StrutsPortlet,属性应该设置为com.liferay.portlet.StrutsPortlet。3、中的值“view-action”不能修改。4、中的值-struts_action”链接到struts-config.xml中的path属性值,配置Portlet实例属性、分类组织,国际化,EXT_4ext/libraryfalse,定义Portlet实例属性:配置文件是:extext-webdocrootWEB-INFliferay-portlet-ext.xml,分类组织Portlets:配置文件是:extext-webdocrootWEB-INFliferay-display.xml,注意:这里的元素的值EXT_4必须要和portlet-ext.xml中的元素的值一致的。,其中的key值(即javax.portlet.title.EXT_4),是“javax.portlet.title”+“portlet名字”(即在portlet-ext.xml中添加的portlet的的值),定义Portlet名称:配置文件是:extext-implsrccontentLperties,javax.portlet.title.EXT_4=Library,定义Struts页面流、tiles页面布局,定义Struts页面流:配置文件是:extext-webdocrootWEB-INFstruts-config.xml,定义tiles页面布局:配置文件是:extext-webdocrootWEB-INFtiles-defs.xml,注意:这里的path=/ext/library/add_book值就是portlet-ext.xml中对应的view-action的值。,这理portlet.ext.library继承portlet。这意味着portlet.ext.library将会使用portlet.jsp作为它的模板。portlet.ext.library.view继承portlet.ext.library。这意味着portlet.ext.library.viewportlet.ext.library也将会使用portlet.jsp作为它的模板,注意:这里的name=portlet.ext.library.view值就是struts-config.xml中对应的forward=portlet.ext.library.view的值,定义Action,packagecom.ext.portlet.library.action;importjavax.portlet.ActionRequest;importjavax.portlet.ActionResponse;importjavax.portlet.PortletConfig;importjavax.portlet.RenderRequest;importjavax.portlet.RenderResponse;importorg.apache.struts.action.ActionForm;importorg.apache.struts.action.ActionForward;importorg.apache.struts.action.ActionMapping;importcom.liferay.portal.struts.PortletAction;publicclassAddBookActionextendsPortletActionpublicvoidprocessAction(ActionMappingmapping,ActionFormform,PortletConfigconfig,ActionRequestreq,ActionResponseres)throwsExceptionStringbookTitle=req.getParameter(book_title);if(null=bookTitle|.equals(bookTitle)setForward(req,portlet.ext.library.error);elsesetForward(req,portlet.ext.library.success);publicActionForwardrender(ActionMappingmapping,ActionFormform,PortletConfigconfig,RenderRequestreq,RenderResponseres)throwsExceptionif(getForward(req)!=null,添加目录:extext-implsrccomextportletlibraryaction,并在目录下建Action文件,JSP开发-创建JSP页面,在extext-webdocroothtmlportletext目录下创建文件目录liberay在新建的liberay目录下,添加文件init.jsp,view.jsp,success.jsp,error.jspInit.jsp里面写下面代码,AddabookentrytotheLibrary:method=postname=fmBookTitle:book_titlesize=20type=textvalue=fm);,view.jsp里面写入下面的代码,其中,这将会让我们使用在上一步这定义的init.jsp,其中实际对应目录是:portalportal-webdocroothtmlcommoninit.jsp。这将会让我们使用Liferay标签库,JSP开发-创建JSP页面,在liberay目录下面创建文件error.jsp和success.jsp。如果添加书成功,则返回success.jsp页面,显示书名;如果添加书失败,则返回error.jsp,提示添加失败。,BookTitle:,error.jsp里面写入下面的代码:,Itsfailedtoaddabook!,success.jsp里面写入下面的代码:,发布、运行和测试,发布:执行ext项目根目录下的build.xml文件antdeploy,部署这些你做的对你的应用的改变,然后重启tomcat服务器。,运行和测试:访问地址:http:/localhost:8080。利用用户名:test;密码:test登录进入系统。在选择应用的窗口中选择我们刚刚添加的PortletLibrary,如果在页面上会增加一个Portlet(如下图),显示出你刚刚添加的内容,那么部署就成功了。,添加应用,选中添加,SturtsPortlet小结,高度总览一个URL或Uri通过控制器传送.控制器决定哪个页面应该被显示出来.我们开始页面指向portlet-ext.xml的view-action控制器MainServlet.java,详细视图:,Liferay如何决定哪个JSP应该被首先显示?,SturtsPortlet小结,对于JSPPortlet,JSP直接指向了从portlet-ext.xml中定义的页面.对于Strutsportlets,这一系列过程通过tiles-defs.xml来定义.,SturtsPortlet小结,Liferay将会检查struts-path来检查是否一个用户有访问这个portlet的权限.注意:当你看到错误(error)信息后:你没有足够的权限来访问这个portlet.那么:1.检查你是否在portlet-ext.xml中有正确的定义用户权限.2.检查来观察是否定义正确.,ConfigurationPortlet开发,SSHPortlet开发,SSHPortlet开发流程,在Liferay中创建一个SSHPortlet:,开发目录结构:配置文件放在这个目录下:extext-webdocrootWEB-INFJSPs将会放在这个目录下:extext-webdocroothtmlportletextStruts中Action放在这个目录下:extext-implsrccomportletSrc文件夹名放在这个目录下:extext-implsrccomextportlet例如library模块,就在extext-implsrccomextportlet下建目录libraryService.xml放在这个目录下extext-implsrccomextportletlibrary推荐:一个模块的实体表对应放在各自模块下同一个service.xml中ext-implsrc,ext-servicesrc是放置我们自己开发的portlet的java代码。ext-web是自己开发portlet对应的网页文件和配置文件。开发SSH,目地来新建一个自己portlet。这里我们采用portal里面代码规范生成机制。对于持久化层和服务层的类都可以自动产生。,在Liferay中创建一个SSHPortlet:,开发流程:1.建立业务数据表2.建立service.xml文件3.修改ant文件,增加ant任务在extext-impl根目录下的build-parent.xml文件添加build-service任务4.生成实体类和持久化类执行extext-impl根目录下的build.xml文件build具体的任务,生成hibernate的实体类和持久化类6.在实体类和持久化类,增加自己需要的业务操作7.自定义portlet及配置Portlet属性portlet-ext.xml定义Portletliferay-portlet-ext.xml配置Portlet实例属性8.国际化配置文件Lperties9.归类PortletLiferay-display.xml分类组织Portlet10.定义页面流和布局struts-config.xml定义页面流titles-defs.jsp定义页面布局11.定义Action12.创建JSP定义我们需要的页面,建立业务数据表和代码模板配置文件,首先、建立业务数据表,在数据库里面新建一个表UsersEntry,字段userid,username,password.并往表中插入几个条数据。,接下来,建立代码模板配置文件建立service.xml文件:在ext-implsrccomextportlet新建一个目录users,在目录下建立一个service.xml文件,文件内容为:,UsersUsersEntry,修改ant文件,增加ant任务,并执行ant任务,建好service.xml文件后,我们在ext-impl目录下打开build-perent.xml在.的下面添加任务:,然后在MyEclipse的ant视图里面打开ext-impl目录下的build.xml执行build-service-portlet-user任务。,之后,我们会发现在ext-implsrccomextportletusers,和ext-servicesrccomextportletusers下面多了几个目录和文件。这是都是系统自动产生的hibernate的实体类和持久化类。如果我们再细心些也可发现在ext-implsrcMETA-INF目录下配置文件都多些内容。这些都是系统已经自动将对应的实体类、持久化类、工具类等配置为相应的javabean、util、service等。这样做无疑节省了很多时间,而且减少我们人工配置的错误。,业务实现编码,现在我们要实现一个查询功能,将数据库中表名users中所有记录的username,password查询出来,并显示在前台。,(1)打开ext-servicesrccomextportletusersservice下UsersEntryService文件,建立一个名为getAllUsers的抽象方法;publicListgetAllUsers()throwsSystemException;(2)然后在ext-implsrccomextportletusersserviceimplUsersEntryServiceImpl.java中实现上面的接口UsersEntryService.即加上如下方法:publicListgetAllUsers()throwsSystemExceptionreturnUsersEntryUtil.findAll();(3)同样spring的service层也是通过辅助类作为对外唯一入口,所以在UsersEntryServiceUtil里面增加一个方法getAllUsers作为service层的方法getAllUsers的入口。如下:publicstaticListgetAllUsers()throwsSystemExceptionreturn_service.getAllUsers();需要注意的是service层接口对应具体实现是由工厂类指定。他们捆绑关系可以查看spring配置文件信息。,定义Action-完成响应客户端请求,在srccomextportletusersaction目录下建立一个ViewUserAction.java文件,packagecom.ext.portlet.users.actio

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论