国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

Webwork 實現(xiàn)文件上傳下載代碼詳解

2019-11-20 10:37:55
字體:
供稿:網(wǎng)友

本文主要從三個方面給大家介紹webwork文件上傳下載知識,包括以下三個方面:

1. 包裝 Request 請求
2. 獲取文件上傳的解析類
3. 項目實戰(zhàn)配置和使用

Web上傳和下載應(yīng)該是很普遍的一個需求,無論是小型網(wǎng)站還是大并發(fā)訪問的交易網(wǎng)站。WebWork 當(dāng)然也提供了很友好的攔截器來實現(xiàn)對文件的上傳,讓我們可以專注與業(yè)務(wù)邏輯的設(shè)計和實現(xiàn),在實現(xiàn)上傳和下載時順便關(guān)注了下框架上傳下載的實現(xiàn)。

1. 包裝 Request 請求

•每次客戶端請求 Action 時,都會調(diào)用 WebWork 調(diào)度類 ServletDispatcher.service()方法。

具體過程請參照:詳解Webwork中Action 調(diào)用的方法

public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException {try {if (encoding != null) {try {request.setCharacterEncoding(encoding);} catch (Exception localException) {}}if (locale != null) {response.setLocale(locale);}if (this.paramsWorkaroundEnabled) {request.getParameter("foo");}request = wrapRequest(request); //封裝 request請求serviceAction(request, response, getNameSpace(request), getActionName(request), getRequestMap(request), getParameterMap(request), getSessionMap(request), getApplicationMap());} catch (IOException e) {String message = "Could not wrap servlet request with MultipartRequestWrapper!";log.error(message, e);sendError(request, response, 500, new ServletException(message, e));}} 

先來看看 wrapRequest 方法做了什么:

protected HttpServletRequest wrapRequest(HttpServletRequest request) throws IOException {if ((request instanceof MultiPartRequestWrapper)) {return request;}if (MultiPartRequest.isMultiPart(request)) {request = new MultiPartRequestWrapper(request, getSaveDir(), getMaxSize());}return request;}

• 首先判斷了傳進來的 request 是不是已經(jīng)被封裝好的 MultiPartRequestWrapper,如果是就直接返回。
• 否則再判斷 request 的頭信息里面的 Content­Type 是不是多類型參數(shù) (multipart/form­data)的請求,如果是就把 request 包裝成 WebWork 自己的 MultiPartRequestWrapper 類型,該類型繼承HttpServletRequestWrapper 。

MultiPartRequest.isMultiPart() 方法實現(xiàn)如下:

public static boolean isMultiPart(HttpServletRequest request){String content_type = request.getHeader("Content-Type");return content_type != null && content_type.startsWith("multipart/form-data");}

•在 webwork.properties 里面配置文件的臨時存儲目錄、還有最大上傳大小,其實就是在這個時候起到作用的。
•創(chuàng)建 MultiPartRequestWrapper 對象的時候傳入的參數(shù)是由 getSaveDir() 和 getMaxSize() 方 法 獲 得 的 。
•在方法里會查找配置里面的 webwork.multipart.saveDir、 webwork.multipart.maxSize 屬性,找到則使用該屬性指定的臨時目錄和上傳的最大內(nèi)容,沒找到就使用環(huán)境的臨時目錄。

具體實現(xiàn)如下:

protected String getSaveDir() {String saveDir = Configuration.getString("webwork.multipart.saveDir").trim();if (saveDir.equals("")) {File tempdir = (File) getServletConfig().getServletContext().getAttribute("javax.servlet.context.tempdir");log.info("Unable to find 'webwork.multipart.saveDir' property setting. Defaulting to javax.servlet.context.tempdir");if (tempdir != null) {saveDir = tempdir.toString();}} else {File multipartSaveDir = new File(saveDir);if (!multipartSaveDir.exists()) {multipartSaveDir.mkdir();}}if (log.isDebugEnabled()) {log.debug("saveDir=" + saveDir);}return saveDir;}

2. 獲取文件上傳的解析類

再來看一下 MultiPartRequestWrapper 的構(gòu)造函數(shù)使如何包裝 request 的:

public MultiPartRequestWrapper(HttpServletRequest request, String saveDir, int maxSize) throws IOException {super(request);if ((request instanceof MultiPartRequest)) {this.multi = ((MultiPartRequest) request);} else {String parser = "";parser = Configuration.getString("webwork.multipart.parser");if (parser.equals("")) {log.warn("Property webwork.multipart.parser not set. Using com.opensymphony.webwork.dispatcher.multipart.PellMultiPartRequest");parser = "com.opensymphony.webwork.dispatcher.multipart.PellMultiPartRequest";} else if (parser.equals("pell")) {parser = "com.opensymphony.webwork.dispatcher.multipart.PellMultiPartRequest";} else if (parser.equals("cos")) {parser = "com.opensymphony.webwork.dispatcher.multipart.CosMultiPartRequest";} else if (parser.equals("jakarta")) {parser = "com.opensymphony.webwork.dispatcher.multipart.JakartaMultiPartRequest";}try {Class baseClazz = MultiPartRequest.class;Class clazz = Class.forName(parser);if (!baseClazz.isAssignableFrom(clazz)) {addError("Class '" + parser + "' does not extend MultiPartRequest");return;}Constructor ctor = clazz.getDeclaredConstructor(new Class[] { Class.forName("javax.servlet.http.HttpServletRequest"), String.class, Integer.TYPE });Object[] parms = { request, saveDir, new Integer(maxSize) };this.multi = ((MultiPartRequest) ctor.newInstance(parms));} catch (ClassNotFoundException e) {addError("Class: " + parser + " not found.");} catch (NoSuchMethodException e) {addError("Constructor error for " + parser + ": " + e);} catch (InstantiationException e) {addError("Error instantiating " + parser + ": " + e);} catch (IllegalAccessException e) {addError("Access errror for " + parser + ": " + e);} catch (InvocationTargetException e) {addError(e.getTargetException().toString());}}}

• 首先它判斷了傳入的 request 是不是 MultiPartRequest 抽象類的子類,如果是就直接把自身的 MultiPartRequest 類型的變量引用 request。

• 否則讀取 WebWork 配置 的webwork.multipart.parser 屬性,該屬性決定 Webwork 內(nèi)部用什么實現(xiàn)文件上傳。 如果沒有指定,則默認(rèn)使用 PellMultiPartRequest 的實現(xiàn)。

•找到配置的類后,WebWork 通過 Java 反射創(chuàng)建該類的實例。所有支持的類都是從 MultiPartRequest 繼承而來,創(chuàng)建該實例后向上轉(zhuǎn)型,并賦予 MultiPartRequestWrapper 的成員multi。

• WebWork 的文件上傳封裝了幾種通用的 FileUpload lib,并不是自己實現(xiàn)的。

•它包括了pell,cos,apache common 三種實現(xiàn),WebWork 對這三個包進行封裝,提供了一 個通用的訪問接口 MultiPartRequest,細(xì)節(jié)實現(xiàn)分別是 PellMultiPartRequest、 CosMultiPartRequest 、JakartaMultiPartRequest 。

• jakarta 支持多個文件使用同一個HTTP參數(shù)名。如果直接使用 WebWork 的 FileUpload 攔截器,推薦使用pell,因為當(dāng)你上傳中文文件名稱的文件的時候,只有pell 包會正確的獲得中文文件名稱,apache common會將文件名稱改為xxx.tmp這樣的文件名,而cos會亂碼, 因此我們唯一的選擇只有 pell。

•cos 的功能比較強大,WebWork 的封裝卻使它喪失了很多的功能,cos 需要設(shè)置 request 的character encoding。WebWork的封裝沒有設(shè)置,所以就導(dǎo)致了cos的亂碼問題,當(dāng)然如果你單獨 使用cos,則會避免此類問題。

3. 項目實戰(zhàn)配置和使用

• 配置文件

action 配置:

<action name="uploadAttach" class=".....attach.action.uploadAttach" caption="上傳附件"><result name="success" type="dispatcher"><param name="location">/result.jsp</param></result><result name="error" type="dispatcher"><param name="location">/result.jsp</param></result> <interceptor-ref name="defaultStack" /> <interceptor-ref name="fileUploadStack" /> //webwok 上傳所需要的攔截棧</action>//攔截棧的定義<interceptor-stack name="fileUploadStack"><interceptor-ref name="fileUpload"/> <interceptor-ref name="params"/></interceptor-stack>//攔截棧對應(yīng)的攔截器<interceptor name="fileUpload" class="com.opensymphony.webwork.interceptor.FileUploadInterceptor"/><interceptor name="params" class="com.opensymphony.xwork.interceptor.ParametersInterceptor"/> 

•前端使用比較穩(wěn)定、功能比較強大的 Ajaxupload這里就不多說了,有官方網(wǎng)址:jQuery AjaxUpload 上傳圖片代碼

•通過對 Webwork 上傳請求的封裝和解析類的獲取,所有的前戲都已經(jīng)準(zhǔn)備妥當(dāng),上傳攔截器里面具體實現(xiàn)如下:

public String intercept(ActionInvocation invocation) throws Exception {if (!(ServletActionContext.getRequest() instanceof MultiPartRequestWrapper)) {if (log.isDebugEnabled()) {log.debug("bypass " + invocation.getProxy().getNamespace() + "/" + invocation.getProxy().getActionName());}return invocation.invoke();}Action action = invocation.getAction();ValidationAware validation = null;if ((action instanceof ValidationAware)) {validation = (ValidationAware) action;}MultiPartRequestWrapper multiWrapper = (MultiPartRequestWrapper) ServletActionContext.getRequest();if (multiWrapper.hasErrors()) {Collection errors = multiWrapper.getErrors();Iterator i = errors.iterator();while (i.hasNext()) {String error = (String) i.next();if (validation != null) {validation.addActionError(error);}log.error(error);}}Enumeration e = multiWrapper.getFileParameterNames();while ((e != null) && (e.hasMoreElements())) {String inputName = (String) e.nextElement();String[] contentType = multiWrapper.getContentTypes(inputName);String[] fileName = multiWrapper.getFileNames(inputName);File[] file = multiWrapper.getFiles(inputName);if (file != null) {for (int i = 0; i < file.length; i++) {log.info("file " + inputName + " " + contentType[i] + " " + fileName[i] + " " + file[i]);}}if (file == null) {if (validation != null) {validation.addFieldError(inputName, "Could not upload file(s). Perhaps it is too large?");}log.error("Error uploading: " + fileName);} else {invocation.getInvocationContext().getParameters().put(inputName, file);invocation.getInvocationContext().getParameters().put(inputName + "ContentType", contentType);invocation.getInvocationContext().getParameters().put(inputName + "FileName", fileName);}}String result = invocation.invoke();for (Enumeration e1 = multiWrapper.getFileParameterNames(); e1 != null && e1.hasMoreElements();) {String inputValue = (String) e1.nextElement();File file[] = multiWrapper.getFiles(inputValue);for (int i = 0; i < file.length; i++) {File f = file[i];log.info("removing file " + inputValue + " " + f);if (f != null && f.isFile())f.delete();}}return result;}

•首先判斷當(dāng)前請求是否為 包含多媒體請求,如果是則記錄日志,并執(zhí)行 Action。
•然后判斷在文件上傳過程 MultiPartRequestWrapper 是否含有錯誤,將錯誤信息,返回給客戶端,不在繼續(xù)調(diào)用 Action。
•如果上面的判斷條件都沒有進行,開始遍歷 MultiPartRequestWrapper 中的上傳文件的參數(shù),并將其中的文件名、文件內(nèi)容類型放入Action 參數(shù) map 中,供后面的業(yè)務(wù)類進行操作。
•在 WebWork 的 fileupload 攔截器功能中,它提供的 File只 是一個臨時文件,Action 執(zhí)行之后就會被自動刪除,你必須在 Action中自己處理文件的存儲問題,或者寫到服務(wù)器的某個目錄,或者保存到數(shù)據(jù)庫中。如果你準(zhǔn)備寫到服務(wù)器的某個目錄下面的話,你必須自己面臨著處理文件同名的問題,但是實際上cos包已經(jīng)提供了 文件重名的自動重命名規(guī)則。

通過以上代碼給大家介紹了Webwork 實現(xiàn)文件上傳下載的相關(guān)知識,希望對大家有所幫助。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 新巴尔虎左旗| 青冈县| 新安县| 三穗县| 安义县| 大埔区| 偏关县| 喜德县| 青龙| 吉林市| 石棉县| 壤塘县| 左贡县| 井陉县| 临颍县| 拉孜县| 濮阳县| 北票市| 兰州市| 饶平县| 馆陶县| 曲靖市| 沽源县| 湖南省| 滦平县| 石门县| 平江县| 应用必备| 崇阳县| 乌苏市| 清河县| 镇康县| 靖江市| 昭觉县| 于田县| 边坝县| 迁西县| 淄博市| 北川| 磐石市| 桦川县|