DWR基础教程及配置.docx_第1页
DWR基础教程及配置.docx_第2页
DWR基础教程及配置.docx_第3页
DWR基础教程及配置.docx_第4页
DWR基础教程及配置.docx_第5页
已阅读5页,还剩46页未读 继续免费阅读

下载本文档

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

文档简介

如何开始用DWR有两种方法开始DWR,简单的方式是下载WAR文件然后看看。但是这不能帮你知道如何轻松的把DWR整合到你的web应用中,所以还是推荐你按照下面的3个步骤做:1. 安装DWR的Jar包下载dwr.jar文件。把它放到你的webapp的WEB-INF/lib目录下。那里可能已经有很多其他的jar文件了。2. 编辑配置文件需要把下面的代码加到WEB-INF/web.xml文件中。那部分需要和其他的在一起,部分也一样。 dwr-invoker DWR Servlet uk.ltd.getahead.dwr.DWRServlet debug true dwr-invoker /dwr/*在WEB-INF目录下的web.xml旁边创建一个dwr.xml文件。可以从最简单的配置开始: DWR配置文件定义了那些DWR会创建提供远程调用的Javascript类。在上面的例子中我们定义了两个类来提供远程调用,并为其提供的Javascript类的名字。在上面我们使用了new创建器,它会调用没有参数的构造函数来创建实例,但是所有JavaBean必须有这一构造函数。还要注意DWR有一些限制: 不要出现Javascript保留关键字;和保留关键字同名的函数指定被排除。多数Javascript的关键字和Java是相同的。所以你不可能有一个方法叫做try()。但是该死delete()对与Javascript有着特殊意义,而对Java则不是。 Javascript方法重载是不支持的,所以尽量不要再Java中使用。 3. 访问下面的URLhttp:/localhost:8080/YOUR-WEBAPP/dwr/你可以看见一个页面,里面有第二步中的类。接着往里点,你会看到所有可以调用的方法列表。这个页面是动态生成用来测试的例子。自己动手试一下!怎么在你的web应用中使用在文档中有很多例子演示如何动态更改页面中的文字、更新列表、操作表单,还有直接更改table中的内容。每一个都有如何实现的介绍。另一种方式是看刚才的页面中提供的代码:到 http:/localhost:8080/YOUR-WEBAPP/dwr/ 页面,点击你的类。查看源码,找到执行方法的那几行,把那些文字粘贴到你的HTML或JSP中。要包括下面这些能产生神奇效果的Javascript文件的链接。你也可以把其中/YOUR-WEBAPP/替换成你的web页面的相对路径。DWR根据dwr.xml生成和Java代码类似的Javascript代码。相对而言Java同步调用,创建与Java代码匹配的Ajax远程调用接口的最大挑战来至与实现Ajax的异步调用特性。DWR通过引入回调函数来解决这个问题,当结果被返回时,DWR会调用这个函数。有两种推荐的方式来使用DWR实现远程方法调用。可以通过把回调函数放在参数列表里,也可以把回调函数放到元数据对象里。当然也可以把回调函数做为第一个参数,但是不建议使用这种方法。因为这种方法在处理自动处理http对象时(查看Alternative Method)上会有问题。这个方法主要是为向下兼容而存在的。简单的回调函数假设你有一个这样的Java方法:public class Remote public String getData(int index) . 我们可以在Javascript中这样使用: .function handleGetData(str) alert(str);Remote.getData(42, handleGetData);42是Java方法getData()的一个参数。此外你也可以使用这种减缩格式:Remote.getData(42, function(str) alert(str); );调用元数据对象(Meta-Data)另外一种语法时使用调用元数据对象来指定回调函数和其他的选项。上面的例子可以写成这样:Remote.getData(42, callback:function(str) alert(str); );这种方法有很多优点:易于阅读,更重要的指定额外的调用选项。超时和错误处理在回调函数的元数据中你可以指定超时和错误的处理方式。例如:Remote.getData(42, callback:function(str) alert(str); , timeout:5000, errorHandler:function(message) alert(Oops: + message); );查找回调函数有些情况下我们很难区分各种回调选项(记住,Javascript是不支持函数重载的)。例如:Remote.method( timeout:3 , errorHandler:somefunc );这两个参数之一是bean的参数,另一个是元数据对象,但是我们不能清楚的告诉DWR哪个是哪个。为了可以跨浏览器,我们假定null = undefined。 所以当前的情况,规则是: 如果第一个或最后一个是一个函数,那么它就是回调函数,没有元数据对象,并且其他参数都是Java的方法参数。 另外,如果最后一个参数是一个对象,这个对象中有一个callback成员,并且它是个函数,那么这个对象就是元数据对象,其他的都是Java方法参数。 另外,如果第一个参数是 null ,我们就假设没有回调函数,并且其他的都是Java方法参数。尽管如此,我们会检查最后一个参数是不是null,如果是就发出警告。 最后如果最后一个参数是null,那么就没有callback函数。 另外,发出错误信号是个糟糕的请求格式。 创造一个与Java对象匹配的Javascript对象假设你有这样的Java方法:public class Remote public void setPerson(Person p) this.person = p; Person对象的结构是这样的:public Person private String name; private int age; private Date appointments; / getters and setters .那么你可以在Javascript中这样写:var p = name:Fred Bloggs, age:42, appointments: new Date(), new Date(1 Jan 2008) ;Remote.setPerson(p);在Javascript没有出现的字段,在Java中就不会被设置。因为setter都是返回void,我们就不需要使用callback函数了。如果你想要一个返回void的服务端方法的完整版,你也可以加上callback函数。很明显DWR不会向它传递任何参数。TransformerFactoryConfigurationError这个问题的现象是在启动有DWR的Web应用时出现如下stack trace:root causejavax.xml.transform.TransformerFactoryConfigurationError: Provider cessor.TransformerFactoryImpl not found javax.xml.transform.TransformerFactory.newInstance(Unknown Source)这个问题和DWR没有什么关系,那是因为Tomcat没有配置好。比较简单的解决办法是下载Xalan替换掉$TOMCAT-HOME/common/lib目录下的xalan.jar文件。DWR2.0能更好的处理这个问题,但是本质的问题还是因为DWR的XML序列化需要有XSLT解析器的支持。如果你用JDK5还是有这个问题的话,你可以增加以下VM参数来使Tomcat正常工作。-Djavax.xml.transform.TransformerFactory= ernal.xsltc.trax.TransformerFactoryImplXML解析错误在刚开始用DWR的时候经常遇到的一个错误就是XML解析错误。其实这和DWR没有多大关系,主要是因为Tomcat里面自带的Xerces的问题,要不是该有的时候没有,要不是不该有的时候有了。 JDK 1.3自身没有XML解析器,所以你需要xercesImpl.jar和xml-apis.jar. JDK 1.4.0 和 JDK 1.4.1 虽然有了XML解析器,但是有很多bug,所以你还是需要把xercesImpl.jar放到tomcatcommonendorsed目录下。 JDK 1.4.2和JDK 5自带的XML解析器工作的很好,你就不需要再加其他的了。另外要提的一点是,不同版本的Tomcat需要的XML解析器不一样。所以要注意检查它和JDK的版本兼容性。 用BEA Weblogic的Classpath问题Weblogic 8.1(有可能其他版本同样)可能找不到DWR的类。这大多出现在dwr.jar放在APP-INF目录下(APP_INF/lib)的情况。在这种情况下DWR依然可以工作,例如debug页面可以看见,但是DWR找不到你的类。解决办法是把dwr.jar放到WEB-INF/lib目录下。没有cookies的情况下用DWR当不能用cookies时,servlet规范通过URL重写来支持HttpSession。DWR 2.x通过它生成的URL来支持这项功能。但是DWR 1.x没有这个功能。你可以通过以下办法让DWR 1.x 也支持cookies: 从dwr.jar中提取engine.js,保存到你的文件系统中,就像jsp文件一样. 修改DWREngine._sendData = function(batch) 方法, 加入一行: statsInfo += ;jsessionid= + 这样就可以让DWR 1.x支持url重写了。DWR 2+默认支持。传递额外的数据到callback函数 通常我们需要传递额外的数据到callback函数,但是因为所有的回调函数都只有一个参数(远程方法的返回结果),这就需要一些小技巧了。 解决方案就是使用Javascript的闭包特性。 例如,你的回调函数原本需要像这个样子: function callbackFunc(dataFromServer, dataFromBrowser) / 用dataFromServer和dataFromBrowser做些事情. 那么你可以像这个组织你的函数: var dataFromBrowser = .; / 定义一个闭包函数来存储dataFromBrowser的引用,并调用dataFromServer var callbackProxy = function(dataFromServer) callbackFunc(dataFromServer, dataFromBrowser); ; var callMetaData = callback:callbackProxy ; Remote.method(params, callMetaData);(调用元数据在脚本介绍中有解释) 换句话说,现在你作为callback函数传递过来的不是一个真正的callback,他只是一个做为代理的闭包,用来传递客户端的数据。 你可以用更简介的形式: var dataFromBrowser = .; Remote.method(params, callback:function(dataFromServer) callbackFunc(dataFromServer, dataFromBrowser); );服务器性能优化CPU瓶颈:经过严格的测试DWR的性能没什么问题。DWR上性能消耗同web服务器和网络比起来可以忽略不计。如果你真的需要提升DWR的性能的话,可以把log级别设置ERROR或FATAL,但是主要还是要看你的编码情况。Network瓶颈: DWR没有管理你的浏览器缓存的功能,所以它会不断的重复读取DWR的javascript文件。这里有一个简单的解决办法,把javascript文件复制到你的web-app中,这样web服务器就可以更好的利用它了。你也可以考虑把所有的javascript文件合并成一个文件,然后用DOJO的压缩程序处理一个来节省流量。我们可以做一个补丁,让DWR在web-app启动的时候用时间做为javascript文件的时间戳,但是这个并不十分重要,因为上面的补丁太简单了而且可以压缩合并Javascript文件。WEB-INF/web.xml 参考手册在web.xml中最简单的配置就是简单加入DWR的servlet,没有这个配置DWR就不会起作用: dwr-invoker uk.ltd.getahead.dwr.DWRServlet dwr-invoker /dwr/*此外还可以加入一些重要和有用的参数。Logging DWR可以工作在JDK1.3上,而JDK1.3不支持java.util.logging,但是我们想强迫任何人使用commons-logging或者log4j,所以当没有logging类的时候DWR就使用HttpServlet.log()方法。尽管如此,如果DWR发现了commons-logging,就是使用它。 Commons-Logging 几乎每一个人都在使用commons-logging,因为大多数的servlet容器在使用它。所以如果你的web应用中没有明显的加入commons-logging包,它也会默认的配置好。 在这种情况下,logging是由java.util.logging或者log4j配置文件控制的。详细配置查看文档。 HttpServlet.log() 如果你用HttpServlet.log(), 下面的配置控制logging: logLevel DEBUG 可用的值有:FATAL, ERROR, WARN (默认), INFO 和 DEBUG。 多个dwr.xml文件 和 J2EE安全 一般来说,你只需要一个dwr.xml文件,并且放置在默认的位置:WEB-INF/dwr.xml。 如果那样的话,你可以不用了解下面的配置。 有三个原因使你希望指定不同位置的dwr.xml文件。 你希望让dwr.xml文件和它能访问到的资源在一起。在这种情况下你需要一个这样的配置: WEB-INF/classes/com/yourco/dwr/dwr.xml 。 你有大量的远程调用类,希望把他们分成多个文件。在这种情况下你需要重复下面的配置几次,每一个中有不同的 param-name,并且以 'config' 开头。DWR会依次把他们都读进来。 DWR可以使用Servlet规范的J2EE的URL安全机制来给不同的用户不同的访问权限。你只需要简单的定义多个dwr servlet,并且制定不同的名字,url和访问权限。 如果你希望使用这一功能,那么语法是这样的: config* WEB-INF/dwr.xml What config file do we use? 在这里config*意思是param-name要以字符串config开头。这个参数可以根据需要使用多次,但是不能相同。 一个使用J2EE的安全机制的例子: dwr-user-invoker uk.ltd.getahead.dwr.DWRServlet config-user WEB-INF/dwr-user.xml dwr-admin-invoker uk.ltd.getahead.dwr.DWRServlet config-admin WEB-INF/dwr-admin.xml dwr-admin-invoker /dwradmin/* dwr-user-invoker /dwruser/* dwr-admin dwr-admin-collection /dwradmin/* admin dwr-user dwr-user-collection /dwruser/* user 使用插件(Plug-in) DWR里的很多部件都是可插入的,所以可以通过替换掉DWR的默认实现类来改变其功能。你可以在 中的 param-name 中指定你要替换的接口,并在 param-value 中指定自己的接口实现类。 可插入点是: uk.ltd.getahead.dwr.AccessControl uk.ltd.getahead.dwr.Configuration uk.ltd.getahead.dwr.ConverterManager uk.ltd.getahead.dwr.CreatorManager uk.ltd.getahead.dwr.Processor uk.ltd.getahead.dwr.ExecutionContext 这些可插入点默认的实现都在uk.ltd.getahead.dwr.impl中。 使用debug/test模式 你可以通过下面的参数让DWR进入debug/test模式: debug true 在debug模式里,DWR会为每一个远程调用类生成一个测试页面。这对于检查DWR是否工作和工作的怎么样是很有用的。这个模式还可以警告你一些存在的问题:javascript保留字问题,或者函数重载问题。 尽管如此,这个模式不应该使用在实际部署环境里面,因为它可以为攻击者提供你的服务的大量信息。如果你的网站设计的好的话,这些信息不会帮助攻击者窥视你的网站内容,但是还是不要给任何人一个找到你错误的机会好。 DWR就是照上面的样子做的,没有任何保证,所以你的网站的安全是你的责任。请小心。配置DWR - dwr.xmldwr.xml是DWR的配置文件。默认情况下,应该把它放到WEB-INF目录(web.xml的目录)下。DTD这里还有一个dwr.xml对应的DTD文档以及一个用DTDDoc生成的参考手册。创建dwr.xml文件dwr.xml文件的结构如下: . 术语这里是一些必须理解的术语 - 参数会被converted,远程Bean会被created。所以如果你有一个叫A的bean,它有一个方法叫A.blah(B) 那么你需要一个A的creator和一个B的converter。allow段落里面定义的试DWR可以创建和转换的类。Creators我们要调用的每个类都需要一个定义。creator有几种。比较通用的是new关键字和Spring。更多的信息可以参见Creaters文档。Converters我们必须保证所有的参数都可以被转换。JDK中的多数类型已经有转换器了,但是你需要给DWR转换你的代码的权利。一般来说JavaBean的参数需要一个定义。默认情况下,如下类型不需要定义就可以转换: 所有的原生类型 boolean,int,double, 等等 原生类型的对象类型 Boolean,Integer,等等 java.lang.String java.util.Date 和SQL中的Date 以上类型组成的数组 以上类型的集合类型 (Lists, Sets, Maps, Iterators, 等) 从DOM, XOM, JDOM 和 DOM4J中的DOM对象 (类似 Element 和 Document) 要了解如何转换你的JavaBean或者其他类型的参数请查看Converters文档。可选的init部分用来声明创造bean的类和转换bean的类。多数情况下你不需要用到他们。如果你需要定义一个新的Creator JavaDoc 和 Converter JavaDoc , 那么你就需要在这里定义他们。但是建议你现检查一下DWR是不是已经支持了。在init部分里有了定义只是告诉DWR这些扩展类的存在,给出了如何使用的信息。这时他们还没有被使用。这中方式很像Java中的import语句。多数类需要在使用前先import一下,但是只有import语句并不表明这个类已经被使用了。每一个creator和converter都用id属性,以便后面使用。DWR使用反射来找出在转换时应该用那种类型。有时类型信息并不明确,这时你可以在这里写下方法的签名来明确类型。详细信息查看Signatures部分。多个dwr.xml文件可以有多个dwr.xml文件(详细信息见web.xml文档)。每个文件中的定义会被加在一起。DWR用这个功能来加载基础配置文件。我们可以看看标准被配置文件来了解dwr.xml的内容。转换器转换器在客户端和服务器之间转换数据.下面这些转换器有单独章节介绍 Array Converter Bean and Object Converters Collection Converter Enum Converter DOM Objects Hibernate整合 Servlet Objects (HttpServletRequest, HttpSession, etc) 基础的转换器原生类型,String,像BigDecimal这样的简单对象的转换器已经有了。你不需要在dwr.xml中部分的中定义。它们默认支持。默认支持的类型包括: boolean, byte, short, int, long, float, double, char, java.lang.Boolean, java.lang.Byte, java.lang.Short, java.lang.Integer, java.lang.Long, java.lang.Float, java.lang.Double, java.lang.Character, java.math.BigInteger, java.math.BigDecimal 和 java.lang.StringDate转换器Date转换器负责在Javascript的Date类型与Java中的Date类型(java.util.Date, java.sql.Date, java.sql.Times or java.sql.Timestamp)之间进行转换。同基础的转换器一样,DateConverter默认是支持的。如果你有一个Javascript的字符串 (例如01 Jan 2010) ,你想把它转换成Java的Date类型有两个办法:在javascript中用Date.parse()把它解析成Date类型,然后用DWR的DateConverter传递给服务器;或者把它作为字符串传递给Server,再用Java中的SimpleDateFormat(或者类似的)来解析。同样,如果你有个Java的Date类型并且希望在HTML使用它。你可以先用SimpleDateFormat把它转换成字符串再使用。也可以直接传Date给Javascript,然后用Javascript格式化。第一种方式简单一些,尽管浪费了你的转换器,而且这样做也会是浏览器上的显示逻辑受到限制。其实后面的方法更好,也有一些工具可以帮你,例如: The Javascript Toolbox Date formatter Web Developers Notes on Date formatting 其他对象其实创建自己的转换器也很简单。Converter接口的Javadoc包含了信息。其实这种需要很少出现。在你写自己的Converter之前先看看BeanConverter,它有可能就是你要的。The Creators 创造器dwr.xml文件中的create元素的结构如下: .这里的多数元素都是可选的 - 你真正必须知道的是指定一个creator和一个javascript名字。creator属性 是必须的 - 它用来指定使用那种创造器。默认情况下DWR1.1有8种创造器。它们是: new: 用Java的new关键字创造对象。 none: 它不创建对象,看下面的原因。 (v1.1+) scripted: 通过BSF使用脚本语言创建对象,例如BeanShell或Groovy。 spring: 通过Spring框架访问Bean。 jsf: 使用JSF的Bean。 (v1.1+) struts: 使用Struts的FormBean。 (v1.1+) pageflow: 访问Beehive或Weblogic的PageFlow。 (v1.1+) 如果你需要写自己的创造器,你必须在init部分注册它。javascript属性 用于指定浏览器中这个被创造出来的对象的名字。你不能使用Javascript的关键字。scope属性 非常类似servlet规范中的scope。 它允许你指定这个bean在什么生命范围。选项有application, session, request 和page。这些值对于Servlet和JSP开发者来说应该相当熟悉了。scope属性是可选的。默认是page。如果要使用session需要cookies。当前的DWR不支持ULR重写。param元素 被用来指定创造器的其他参数,每种构造器各有不同。例如,new创造器需要知道要创建的对象类型是什么。每一个创造器的参数在各自的文档中能找到。请查看上面的链接。include和exclude元素 允许创造器来限制类中方法的访问。一个创造器必须指定include列表或exclude列表之一。如果是include列表则暗示默认的访问策略是拒绝;如果是exclude列表则暗示默认的访问策略是允许。例如要拒绝防范除了setWibble()以外的所有方法,你应该把如下内容添加到dwr.xml中。 对于加入到create元素中的类的所有方法都是默认可见的。auth元素 允许你指定一个J2EE的角色作为将来的访问控制检查: none 创造器none 创造器不创建任何对象 - 它会假设你不需要创建对象。这有可能是对的,有两个原因。你可能在使用的scope不是page(看上面),并在在前面已经把这个对象创建到这个scope中了,这时你就不需要再创建对象了。还有一种情况是要调用的方法是静态的,这时也不需要创建对象。DWR会在调用创建器之前先检查一下这个方法是不是静态的。对于上诉两种情况,你仍然需要class参数,用来告诉DWR它是在操作的对象类型是什么。使用静态方法DWR会在调用创建器之前先检查一下这个方法是不是静态的,如果是那么创造器不会被调用。很显然这个逻辑适用于所有创造器,尽管如此null创造器是最容易配置的。适用单例类对于单例类的创建,最好适用BeanShell和BSF来实例化对象。详细信息参见Scripted创造器其他创造器我么偶尔也需要一些新的创造器,最常见的是一个EjbCreator。讨论新的创造器的好地方是在邮件列表。DWR和HttpSessionBindingListenersDWR1.x中存贮已经创造的Bean的方法需要注意,它在每次请求时都会调用相同的 setAttribute() 方法。就是说,如果一个Bean在dwr.xml中的声明周期设置为session,再每次调用bean中的方法时,DWR都会执行一次 session.setAttribute(yourBean) 。这看上去没有什么危害,但是如果你要使用servlet的事件机制的,就是说用了HttpSessionBindingListener接口,你就会发现valueBound和valueUnbound事件在每次调用时都会发生,而不是你想像的在bean被创建时以及session过期时。DWR2 只在第一次创建对象时调用 setAttribute() 。dwr.xml中的签名(Signatures)signatures段使DWR能确定集合中存放的数据类型。例如下面的定义中我们无法知道list中存放的是什么类型。public class Check public void setLotteryResults(List nos) . signatures段允许我们暗示DWR应该用什么类型去处理。格式对以了解JDK5的泛型的人来说很容易理解。 !CDATA import java.util.List; import com.example.Check; Check.setLotteryResults(List nos); DWR中又一个解析器专门来做这件事,所以即便你的环境时JDK1.3 DWR也能正常工作。解析规则基本上会和你预想规则的一样(有两个例外),所以java.lang下面的类型会被默认import。第一个是DWR1.0中解析器的bug,某些环境下不能返回正确类型。所以你也不用管它了。第二个是这个解析器时阳光(sunny day)解析器。就是说它非常宽松,不想编译器那样严格的保证你一定正确。所以有时它也会允许你丢失import: !CDATA import java.util.List; Check.setLotteryResults(List); 将来的DWR版本会使用一个更正式的解析器,这个编译器会基于官方Java定义,所以你最好不要使用太多这个不严格的东西。signatures段只是用来确定泛型参数中的类型参数。DWR会自己使用反射机制或者运行时类型确定类型,或者假设它是一个String类型。所以:不需要signatures - 没有泛型参数:public void method(String p);public void method(String p);需要signatures - DWR不能通过反射确定:public void method(List p);public void method(Map p);不需要signatures - DWR能正确的猜出:public void method(List p);public void method(Map p);不需要signatures - DWR可以通过运行时类型确定:public List method(String p);没有必要让Javascript中的所有对象的key都是String类型 - 你可以使用其他类型作为key。但是他们在使用之前会被转换成String类型。DWR1.x用Javascript的特性把key转换成String。DWR2.0可能会用toString()方法,在服务段进行这一转换。engine.js Functions engine.js对DWR非常重要,因为它是用来转换来至动态生成的接口的javascript函数调用的,所以只要用到DWR的地方就需要它。 The engine.js file 每一个页面都需要下面这些语句来引入主DWR引擎。 使用选项 下面这些选项可以通过 DWREngine.setX() 函数来设置全局属性。例如: DWREngine.setTimeout(1000);或者在单次调用级别上(假设Remote被DWR暴露出来了): Remote.singleMethod(params, callback:function(data) . , timeout:2000 );远程调用可以批量执行来减少反应时间。endBatch 函数中可以设置选项。 DWREngine.beginBatch(); Remote.methodInBatch1(params, callback1); Remote.methodInBatch2(params, callback2); DWREngine.endBatch( timeout:3000 );可以混合这几种方式,那样的话单次调用或者批量调用级别上的设置可以复写全局设置(就像你希望的那样)。当你在一个批量处理中多次设置了某个选项,DWR会保留最后一个。所以如果 Remote.singleMet

温馨提示

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

评论

0/150

提交评论