




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、.第四章 InterceptorInterceptor(攔截器)顧名思義就是在某個事件發(fā)生之前將其攔截,并插入相應(yīng)的處理過程。從這點(diǎn)上來看,攔截器類似于在Servelet規(guī)范中定義的Filter,但是Struts2的攔截器完全獨(dú)立于Servelet的Filter,而且兩者有著截然不同的實(shí)現(xiàn)。Interceptor將很多通用的功能從Action中獨(dú)立出來,大大減少了Action中重復(fù)的代碼量,通過組裝Interceptor可以使得通用的邏輯按照順序執(zhí)行,并且當(dāng)業(yè)務(wù)邏輯順序發(fā)生變化的時候也不需要重新編寫代碼,只需重新組裝Interceptor即可,從而降低web應(yīng)用的耦合性。在開發(fā)Web應(yīng)用的過程
2、中,會碰到很多可以復(fù)用的模塊,如果不采取任何策略,無疑會增加應(yīng)用的重復(fù)代碼量。Interceptor就是Struts2對這些可復(fù)用的應(yīng)用模塊加以管理的策略。通過Interceptor可以把通用的模塊從Action中提取出來,供應(yīng)用中的其它Action應(yīng)用,甚至是供其它項(xiàng)目復(fù)用。4.1 Interceotor基礎(chǔ)對于攔截器而言,最主要就是要清楚攔截器在什么時候開始被調(diào)用,以及Struts2中是如何實(shí)現(xiàn)攔截器,最后還要清楚Struts2中自帶的攔截器有哪些,只有了解這些,才可以為以后使用攔截器打下基礎(chǔ)。4.1.1 Interceptor何時調(diào)用讓我們來看看Interceptor到底在什么時候被調(diào)用
3、,又是如何被調(diào)用。首先讓我們來分析com.opensymphony.xwork2.DefaultActionInvocation源代碼看看一般的Action調(diào)用流程,注意下面的代碼片斷。DefaultActionInvoation.java/*省略其他方法*/ public String invoke() throws Exception if (executed) throw new IllegalStateException(Action has already executed); if (interceptors.hasNext() InterceptorMapping interce
4、ptor = (InterceptorMapping) interceptors.next(); resultCode = interceptor.getInterceptor().intercept(this); else resultCode = invokeActionOnly(); /*省略語句*/ 在執(zhí)行Action之前,Struts2會檢查Action是否配置有攔截器,如果有,遍歷所有攔截器并且執(zhí)行之,如果對應(yīng)的Action沒有配置攔截器,那么Struts2將只執(zhí)行Action。但是似乎并沒有看到Action和Interceptor的執(zhí)行的先后次序,別著急,讓我們看看其它的代碼里有
5、沒有關(guān)于Interceptor的執(zhí)行先后次序。Xwork的攔截器都必須實(shí)現(xiàn)Interceptor接口,但是實(shí)際上大部分的攔截器都是通過繼承抽象類AbstractInterceptor實(shí)現(xiàn)攔截器的功能。下面來了解下AbstractInterceptor類的具體代碼。AbstractInterceptor.javapackage erceptor;import com.opensymphony.xwork2.ActionInvocation;public abstract class AbstractInterceptor implements
6、 Interceptor public void init() public void destroy() public abstract String intercept(ActionInvocation invocation) throws Exception;在這個抽象類中沒有實(shí)現(xiàn)任何方法,就是一個簡單Interceptor接口的實(shí)現(xiàn)。那么攔截器要在Action之前執(zhí)行,那么只有在繼承這個類時,通過實(shí)現(xiàn)它的抽象方法intercept()來完成攔擊器的功能。也就是說在intercept()方法中會先執(zhí)行攔截器想要完成的任務(wù),然后再轉(zhuǎn)向Action執(zhí)行,一般函數(shù)最后會加上這句代碼:Strin
7、g result = invocation.invoke();通過上面的介紹,不難發(fā)現(xiàn),Interceptor的本質(zhì)也是一個Action,畢竟其產(chǎn)生的目的就是為了提高Action代碼的復(fù)用性,降低Action的耦合性。但是Interceptor又是一種特殊的Action,因?yàn)槠鋱?zhí)行于指定Action或之前,或之后完成可復(fù)用的模塊化業(yè)務(wù)邏輯。Interceptor能夠攔截Action的執(zhí)行,它的出現(xiàn)使得開發(fā)者能夠在Action執(zhí)行之前或者之后執(zhí)行一段業(yè)務(wù)邏輯。它們同時也可以阻止Action的執(zhí)行,使得開發(fā)者對一段通用的業(yè)務(wù)邏輯進(jìn)行封裝,然后用在其它地方。下面通過對Interceptor的源代碼中
8、的類和接口的展示,希望能夠使讀者對Interceptor的本質(zhì)有更深一層次的認(rèn)識。4.1.2 Interceptor接口攔截器是一個Struts2框架很好的特性,它的使用十分靈活,同時框架為了滿足特定的需要實(shí)現(xiàn)了一些特定的API,用戶可以根據(jù)自己的需要選用。表4-1 Interceptor提供的預(yù)定義接口Interceptor定義的接口描述Interceptorinterceptor 是采用 interceptor 模式的一種無狀態(tài)類NoParameters這個接口通常由不需要參數(shù)附加的Action實(shí)現(xiàn)ParameterNameAware這個接口通常由需要參數(shù)附加的Action實(shí)現(xiàn)PreRes
9、ultListener實(shí)現(xiàn)這個接口可以獲得一個在Action之后但是結(jié)果之前的回調(diào)n Interceptor:是所有攔截器必須實(shí)現(xiàn)的一個接口。n NoParameters:這個標(biāo)記接口應(yīng)該由那些不想要任何參數(shù)附加的Action來實(shí)現(xiàn),這種情況通常是這樣的,用戶在使用Action標(biāo)簽,不想框架附加任何參數(shù)給次Action,而是想要手動的來設(shè)置這些參數(shù)。n ParameterNameAware:這個接口通常由那些需要參數(shù)附加的Action實(shí)現(xiàn),通常和ParametersInterceptor配合起來實(shí)現(xiàn)參數(shù)的附加,例如Action可能有這樣一份參數(shù)的白名單和黑名單,前者列出的參數(shù)是允許用戶設(shè)置的,
10、而后者列出的則拒絕用戶的設(shè)置。n PreResultListener:實(shí)現(xiàn)這個接口的Action可以獲得一個在Action執(zhí)行之后但是結(jié)果執(zhí)行之前的回調(diào)。4.1.3 Interceptor相關(guān)類在進(jìn)行Interceptor編寫的時候,同Action的編寫一樣,Struts2也提供了一些框架支持的類,這些類的使用,可以大大便利我們進(jìn)行相關(guān)的攔截器的開發(fā)。讀者可以在實(shí)際的應(yīng)用中根據(jù)自己需要使用這些類。表4-2 Interceptor 提供的相關(guān)類類描述AbstractLifecycleInterceptor提供了before(),after() 以及result之前的攔截AliasIntercep
11、tor為類似的Action 的類似參數(shù)提供別名服務(wù)AroundInterceptor提供了before(),after() 攔截ChainingInterceptor將值棧中所有的對象拷貝到當(dāng)前對象,當(dāng)前對象實(shí)現(xiàn)unchainable()接口的除外ConversionErrorInterceptor如果Action執(zhí)行了ValidationAware()接口,那么將所有轉(zhuǎn)換錯誤添加到域錯誤表DefaultWorkflowInterceptor在允許ActionChain繼續(xù)執(zhí)行之前完成一些基本的操作如校驗(yàn)ExceptionHolder對Exception的簡單封裝,方便使用ExceptionM
12、appingInterceptor次攔截器是異常處理的核心I18nInterceptor設(shè)置ActionRequest國際化的本地信息LoggingInterceptor記錄Action執(zhí)行的日志攔截器MethodFilterInterceptor可以包含和排除一些方法執(zhí)行的攔截器ModelDrivenInterceptor觀察modelDriven的Action執(zhí)行情況并將其添加到值棧ParameterFilterInterceptor參數(shù)過濾的攔截器ParametersInterceptor將所有參數(shù)設(shè)置到值棧PrefixMethodInvocationUtil一個執(zhí)行一些固定方法的工具類
13、PrepareInterceptor調(diào)用實(shí)現(xiàn)了preparable接口方法的Action的prepare()方法TimerInterceptor記錄以秒為單位的時間日志仔細(xì)的分析這些類可以發(fā)現(xiàn),其涉及了Struts2 Interceptor的全部。類的功能涉及了Action執(zhí)行的方方面面。幾乎在Action執(zhí)行的任何時刻,都可以找到適合的攔截器截斷Action的執(zhí)行。使其完成想要的業(yè)務(wù)邏輯功能。靈活的運(yùn)用這些類,那么我們幾乎就掌握了Action執(zhí)行的每一個方面,就能夠?qū)ction的執(zhí)行進(jìn)行精準(zhǔn)的控制。4.2使用預(yù)定義的InterceptorStruts2預(yù)先設(shè)計(jì)了很多通用性很強(qiáng)的Interc
14、eptor供用戶使用。靈活的使用這些攔截器,不僅可以更好的設(shè)計(jì)更具通用性的業(yè)務(wù)模塊,而且可以增加Web應(yīng)用的可測試性,使得Web應(yīng)用的開發(fā)和維護(hù)變得更為便捷。4.2.1預(yù)定義Interceptor類攔截器的使用,可以抽取系統(tǒng)的各個方面的可復(fù)用代碼。當(dāng)然在實(shí)際的開發(fā)中可能有一些模塊是經(jīng)常使用到的,或者說是每一個進(jìn)行Web應(yīng)用開發(fā)的程序員都要使用到的,Struts2考慮到了這樣的情況,并且預(yù)先抽取了這些復(fù)用性很強(qiáng)的模塊。那么Struts2自帶的攔截器的配置在struts-default.xml都有配置,在struts-2.0.9-all.zip壓縮包的src目錄下。通過搜索,在路徑struts-2
15、.0.9-allstruts-2.0.9srccoresrcmainresources下可以找到這個文件,打開之后下面是其關(guān)于攔截器配置部分的代碼:struts-default.xml/*省略其他配置語句*/ /*省略其他配置語句*/配置文件中指出了每個自帶攔截器對應(yīng)的類以及它們的名字,那么它們具體的功能可以通過閱讀類的源代碼知道,表4-3中提供一些常用攔截器實(shí)現(xiàn)的功能表4-3 Struts2框架預(yù)定義的攔截器名稱描述chain將參數(shù)從一個Action復(fù)制到另一個Actioncomponent為Action應(yīng)用IoC的邏輯處理conversionError如果出現(xiàn)類型轉(zhuǎn)換錯誤,則增加對應(yīng)字段錯
16、誤execAndWait生成一個獨(dú)立的線程來執(zhí)行ActionfileUpload設(shè)置上傳文件為Action文件logger記錄Action執(zhí)行的起始時間model-driven將Action模型壓入值棧params將HTTP參數(shù)應(yīng)用于Actionprepare調(diào)用Action的prepare()方法servlet-config提供對通用HTTP對象的訪問static-params將Action映射設(shè)定的參數(shù)應(yīng)用到Action實(shí)例中timer控制Action的定時執(zhí)行token防止表單重復(fù)提交的基本實(shí)現(xiàn)token-session防止表單重復(fù)提交的高級實(shí)現(xiàn)validation校驗(yàn)Action中的字
17、段值workflow如果發(fā)生錯誤則自動返回INPUT這個返回類型例如校驗(yàn)攔截器validation這個攔截器就對表單的校驗(yàn)提供了極大的便利,這一點(diǎn)在以后的章節(jié)中,將繼續(xù)講解。為了方便初學(xué)者的使用,Struts2框架還預(yù)定義了若干攔截器棧,所謂的攔截器棧就是將攔截器一個接一個的組裝起來,這些裝配好的攔截器棧往往有著特殊的用途,讓我們大致了解一下這些棧??纯催@些組合在一起的攔截器又將為開發(fā)帶來什么樣的便捷特性。攔截器棧的相關(guān)配置也是在struts-default.xml實(shí)現(xiàn)的,下面是這個文件中關(guān)于攔截器棧的配置部分。struts-default.xml/*省略其他配置語句*/ /*省略其他配置語句
18、*/上面的攔截器棧的配置只是所有攔截器棧的一部分,讀者可以自己找到這個文件,找出所有棧的配置。表4-4中列出部分常用攔截器棧的功能。表4-4 Struts2 框架預(yù)定義的攔截器棧名稱描述defaultStack基本的攔截器棧validationWorkflowStack配置了validation和workflow攔截的棧fileUploadStack配置了fileupload的攔截器棧componentStack配置了反轉(zhuǎn)控制的攔截器棧modelDrivenStack配置了modelDriven的攔截器棧chainStack配置了chain的攔截器棧execAndWaitStack配置了exe
19、cAndWait的攔截器棧completeStack配置了所有攔截器的攔截器棧這里面的攔截棧其實(shí)是在實(shí)際的開發(fā)過程中經(jīng)常要用到的,例如文件上傳攔截棧,這個攔截棧的定義,使得在開發(fā)有關(guān)文件上傳的組件的時候,就不必考慮文件上傳的細(xì)節(jié)了,而是可以把精力集中在業(yè)務(wù)邏輯上,又如攔截棧,這個框架定義的攔截棧,是用戶在使用框架定義的攔截器,不可或缺的一個部分。4.2.2 LoggingInterceptor示例這一節(jié)我們使用框架為我們定義的日志攔截器(LoggingInterceptor)為我們的Action記錄日志??蚣軐?shí)現(xiàn)的這個攔截器的功能很簡單,下面讓首先來看看這個例子。LoggingAction.j
20、avapackage example;import com.opensymphony.xwork2.Action;public class LoggingAction implements Actionpublic String execute()delay();return SUCCESS;private void delay()for ( int i=0;i10000;i+);這個Action簡單的做一個延遲,(后面為了計(jì)算Action的執(zhí)行時間),然后轉(zhuǎn)向success頁面。它的確是夠簡單,因?yàn)檫@里要重點(diǎn)演示的是Interceptor。struts.xml 在這個文件里面,我們配置了一個
21、Struts2框架預(yù)定義的日志攔截器,名稱為logger然后在action里面引用了這個攔截器,指示這個攔截器和這個Action裝配,對這個Action起作用。這樣當(dāng)Struts2框架發(fā)現(xiàn)了這個裝配的攔截器之后,在調(diào)用Action之前就會去調(diào)用這個攔截器,從而達(dá)到預(yù)期的目的。這個例子的目錄圖如圖4-1所示:圖4-1例子的完整目錄如果配置正確的話,部署到Tomcat下,然后在瀏覽器地址欄輸入:http:/localhost:8080/Logging/logging.action頁面會有一個“result null not found”的信息,是因?yàn)槲覀儧]有配置返回頁面,但是可以在控制臺得到這樣的
22、輸出:圖4-2 LoggingAction的對應(yīng)輸出可以看到,在控制器執(zhí)行的前后,日志攔截器分別截獲了控制器的執(zhí)行,并輸出了對應(yīng)的日志新日,如“/logging”這個Interceptor好像完成的工作也并不是很多,讓我們看看它到底是如何工作的。該文件在erceptor.LoggingInterceptor中。LoggingInterceptor.java/省略導(dǎo)入包public class LoggingInterceptor extends AbstractInterceptor private static final Log log
23、 = LogFactory.getLog(LoggingInterceptor.class); private static final String FINISH_MESSAGE = Finishing execution stack for action ; private static final String START_MESSAGE = Starting execution stack for action ; public String intercept(ActionInvocation invocation) throws Exception logMessage(invoc
24、ation, FINISH_MESSAGE); /記錄結(jié)束信息 String result = invocation.invoke(); logMessage(invocation, START_MESSAGE);/記錄開始信息 return result; private void logMessage(ActionInvocation invocation, String baseMessage) if (log.isInfoEnabled() StringBuffer message = new StringBuffer(baseMessage); String namespace =
25、invocation.getProxy().getNamespace(); if (namespace != null) & (namespace.trim().length() 0) message.append(namespace).append(/); message.append(invocation.getProxy().getActionName(); (message.toString(); 這個是框架實(shí)現(xiàn)的一個日志攔截器,通過對源代碼的分析,用戶可以在編寫自己的模塊的時候可以參考Struts2的源代碼,比如下面的記時攔截器就是參考了這里的日志攔截器。通過對源代碼
26、的分析,我們還可以了解到攔截器的具體實(shí)現(xiàn)方式,并編寫自己的攔截器去實(shí)現(xiàn)Interceptor接口。參考源代碼,發(fā)現(xiàn)原來也可以通過繼承這樣的基類AbstractInterceptor來實(shí)現(xiàn)interceptor接口從而實(shí)現(xiàn)自己的攔截器,同時這樣做一個好處就是代碼的邏輯很清楚,在執(zhí)行Action之前,首先執(zhí)行l(wèi)ogMessage()函數(shù)在控制臺有一個輸出,在Action執(zhí)行結(jié)束后又有一個信息輸出,在兩個信息輸出之間通過ActionInvocation類可以獲得當(dāng)前要執(zhí)行的Action有關(guān)的信息,然后執(zhí)行Action相關(guān)操作。掌握了攔截器的這幾個方面那么用戶就可以對攔截器的執(zhí)行進(jìn)行粒度很小的控制。4
27、.3使用自定義的Interceptor閱讀了框架的Logging攔截器的源代碼,可以發(fā)現(xiàn)一個攔截器的實(shí)現(xiàn)也很簡單,下面模仿框架的日志攔截器設(shè)計(jì)一個記時攔截器,這個攔截器不僅記錄Action的執(zhí)行時間,而且同時還輸出執(zhí)行日志。大致可以分為一下幾個步驟:1. 定義自己的攔截器邏輯2. 配置自己的攔截器3. 將自定義的攔截器裝配到對應(yīng)的控制器進(jìn)行攔截4. 運(yùn)行實(shí)例查看效果4.3.1自定義Interceptor的配置Interceptor的配置大同小異,注意struts.xml中的粗體顯示的片斷。struts.xml 這些地方就是用戶在框架中配置攔截器的地方。從上面的配置文件的代碼我們也可以看出,首先
28、我們是先定義了一個自定義的攔截器,然后在對應(yīng)的要使用的控制器中使用了這個攔截器,通過這樣的配置,攔截器和控制器的裝配工作就完成了,下面看看這個攔截器的具體內(nèi)容。4.3.2實(shí)現(xiàn)自己的Interceptor本小節(jié)使用一個自定義的Interceptor,對Action執(zhí)行前和執(zhí)行后進(jìn)行計(jì)時,并且在Action執(zhí)行結(jié)束后向控制臺輸出對應(yīng)的日志信息。同時在Action執(zhí)行完成之后使用這兩個時間計(jì)算出整個Action的運(yùn)行時間。LogAndTime.javapackage example;import mons.logging.Log;import mons.logging.LogFactory;impo
29、rt com.opensymphony.xwork2.ActionInvocation;import erceptor.AbstractInterceptor;SuppressWarnings(serial)public class LogAndTime extends AbstractInterceptor private static final Log log = LogFactory.getLog(LogAndTime.class); private static final String FINISH_MESSAGE = Syst
30、em Administrator Finishing execution stack for action ; private static final String START_MESSAGE = System Administrator Starting execution stack for action ; /設(shè)定了一些輸出信息字符串 private long startTime; /聲明了開始時間 private long executeTime; / 聲明了執(zhí)行時間 private void logMessage(ActionInvocation invocation, Strin
31、g baseMessage) if (log.isInfoEnabled() StringBuffer message = new StringBuffer(baseMessage); String namespace = invocation.getProxy().getNamespace(); if (namespace != null) & (namespace.trim().length() 0) message.append(namespace).append(/); message.append(invocation.getProxy().getActionName(); log.
32、info(message.toString(); /記錄日志信息 Overridepublic String intercept(ActionInvocation invocation) throws Exception logMessage(invocation, START_MESSAGE); startTime = System.currentTimeMillis(); String result = invocation.invoke(); logMessage(invocation, FINISH_MESSAGE); executeTime = System.currentTimeM
33、illis() - startTime; /執(zhí)行時間,等于當(dāng)前時間-開始時間。當(dāng)前時間是控制器的Execute()方法執(zhí)行后 String TIMESTRING=The Action: +invocation.getProxy().getActionName()+has executed +executeTime+ MilliSeconds;/設(shè)定時間信息 System.out.println(TIMESTRING); /獲得當(dāng)前的執(zhí)行時間付給開始執(zhí)行時間return result;在這個interceptor的實(shí)現(xiàn)里面,使用了框架對Interceptor的支持類。使用這些支持類的好處是:這樣
34、可以更加方便,便捷的構(gòu)建自己想要的攔截器。在這個例子中在Action執(zhí)行的前后都對Action進(jìn)行了攔截,在Action執(zhí)行前,將其攔截,記錄下此時的時間,然后輸出一行控制信息到控制臺,表明已經(jīng)執(zhí)行到Action之前。然后Interceptor會喚醒Action繼續(xù)執(zhí)行,執(zhí)行完之后,Interceptor會繼續(xù)將Action捕獲,獲得此時的時刻,和執(zhí)行開始前的一比較,便得出了整個Action執(zhí)行所耗費(fèi)的時間,同時向控制臺輸出信息表明已經(jīng)執(zhí)行完這個Action了。那么再看下這個例子的目錄,如圖4-3所示:圖4-3例子的完整目錄如果配置無誤,在瀏覽器地址欄輸入:http:/localhost:80
35、80/Logging/logging.action 那么將得到下面的結(jié)果:圖4-4自定義攔截器的輸出結(jié)果首先要注意的一點(diǎn)就是這里的所有的控制信息都是在標(biāo)準(zhǔn)輸出(控制臺)輸出的,而不是在相應(yīng)的頁面。本例中的結(jié)果是輸出在eclipse的控制臺的。從輸出的結(jié)果可以看出編寫的攔截器成功的執(zhí)行了,首先在Action執(zhí)行前,攔截器記錄當(dāng)前的時間并輸出日志”.starting execution.”然后在Action執(zhí)行之后,又輸出日志信息”.fininshing execution.”同時記錄當(dāng)前的執(zhí)行時間,并計(jì)算除整個Action的執(zhí)行時間(執(zhí)行后-執(zhí)行前)。輸出執(zhí)行時間。4.4 Interceptor
36、應(yīng)用實(shí)例在前面學(xué)習(xí)的知識,在這一節(jié)將完成一個綜合的Interceptor例子。這個例子中既會用到自定義的攔截器也會使用Struts2提供的預(yù)定義的攔截器。完成頁面等待的效果,由于某個Action要執(zhí)行較長的一段時間,在頁面跳轉(zhuǎn)到另一個頁面之前,先會進(jìn)入一個等待的頁面,等待頁面裝載。其實(shí)在互聯(lián)網(wǎng)上這種頁面等待的效果會經(jīng)常被用到,現(xiàn)在就借用Struts2的攔截器來實(shí)現(xiàn)這個功能。自定義攔截器部分將會使用第二章最后小節(jié)的自定義攔截器,即GreetingInterceptor。為了達(dá)到頁面等待的效果,要借助Struts2提供execAndWait攔截器,這個攔截器的功能在前面的表中可以查到,就是生成一個獨(dú)立的線程來執(zhí)行Action。為什么選擇這個攔截器,將會在下面的源碼分析部分詳細(xì)解釋。有了這兩個攔截器就可以完成這個實(shí)例。整個流程是這樣的:輸入訪問地址之后,首先會出現(xiàn)一個等待的頁面,大概等待10秒之后,跳入一個輸入頁面,用戶輸入姓名提交之后,根據(jù)當(dāng)前的時間生成特定的問候語。為了讓讀者能夠正確阿使用Struts2提供e
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 空氣動力學(xué)與飛行原理 課件 1.3-1.4 通航空器及其分類
- 豐田思考法分享
- 空氣動力學(xué)與飛行原理 課件 5.1 主旋翼
- 丙型肝炎防治指南更新解讀
- 瓣膜功能損傷機(jī)制
- 頒獎典禮主持詞5篇
- 安全生產(chǎn)月安全知識競賽試題
- 安全應(yīng)急預(yù)案方案【7篇】
- 老年癡呆護(hù)理指南
- 臨潭縣第一中學(xué)2024-2025學(xué)年度第二學(xué)期高三期中考試數(shù)學(xué)試卷
- 2025年自然資源管理基本知識考試題目及答案
- 可信數(shù)據(jù)空間解決方案星環(huán)科技
- 2025-2030IVD原酶料市場發(fā)展態(tài)勢剖析及未來需求趨勢預(yù)測研究報告
- 基于單片機(jī)的智能臺燈控制系統(tǒng)的設(shè)計(jì)14000字【論文】
- (高清版)DB13(J)∕T 8557-2023 建設(shè)工程消耗量標(biāo)準(zhǔn)及計(jì)算規(guī)則(房屋修繕建筑工程)
- 2024云南省曲靖市陸良縣城鄉(xiāng)公交服務(wù)有限公司招聘(17人)筆試參考題庫附帶答案詳解
- 2025-2030年中國智能眼鏡行業(yè)市場市場現(xiàn)狀供需分析及投資評估規(guī)劃分析研究報告
- 2025年全國高考物理試題及答案
- 無人機(jī)飛行器編程基本知識試題及答案
- 國有企業(yè)違法犯罪課件
- 鉗工安全測試題及答案
評論
0/150
提交評論