Heim >Web-Frontend >js-Tutorial >Webwork-Implementierung des Datei-Upload- und Download-Codes, detaillierte Erklärung_Javascript-Kenntnisse
In diesem Artikel werden hauptsächlich die Kenntnisse über das Hoch- und Herunterladen von Webwork-Dateien aus drei Aspekten vorgestellt, darunter die folgenden drei Aspekte:
1. Verpackungsanfrage
2. Holen Sie sich die Parsing-Klasse für den Datei-Upload
3. Tatsächliche Projektkonfiguration und -nutzung
Web-Uploads und -Downloads sollten eine sehr häufige Anforderung sein, unabhängig davon, ob es sich um eine kleine Website oder eine Handelswebsite mit großem gleichzeitigem Zugriff handelt. Natürlich bietet WebWork auch einen sehr benutzerfreundlichen Interceptor zum Implementieren des Datei-Uploads, sodass wir uns auf das Design und die Implementierung der Geschäftslogik konzentrieren können. Bei der Implementierung des Uploads und Downloads achten wir auch auf die Implementierung des Framework-Uploads und -Downloads.
1. Verpackungsanfrage
•Jedes Mal, wenn der Client eine Aktion anfordert, wird die Methode ServletDispatcher.service() der WebWork-Versandklasse aufgerufen.
Informationen zum spezifischen Prozess finden Sie unter: Ausführliche Erläuterung der Methode zum Aufrufen von Aktionen in Webwork
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)); } }
Werfen wir zunächst einen Blick darauf, was die Methode „wrapRequest“ bewirkt:
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; }
• Zunächst wird festgestellt, ob die eingehende Anfrage von MultiPartRequestWrapper gekapselt wurde. Wenn ja, wird direkt zurückgegeben.
• Andernfalls stellen Sie fest, ob es sich bei dem ContentType in den Header-Informationen der Anfrage um eine Anfrage mit mehreren Parametern (Multipart/Formdata) handelt. Wenn ja, packen Sie die Anfrage in den WebWork-eigenen MultiPartRequestWrapper-Typ ein, der HttpServletRequestWrapper erbt.
Die Methode MultiPartRequest.isMultiPart() wird wie folgt implementiert:
public static boolean isMultiPart(HttpServletRequest request){ String content_type = request.getHeader("Content-Type"); return content_type != null && content_type.startsWith("multipart/form-data"); }
•Die Konfiguration des temporären Speicherverzeichnisses von Dateien und der maximalen Upload-Größe in webwork.properties kommt zu diesem Zeitpunkt tatsächlich ins Spiel.
•Die beim Erstellen des MultiPartRequestWrapper-Objekts übergebenen Parameter werden von den Methoden getSaveDir() und getMaxSize() abgerufen.
•In der Methode werden die Attribute webwork.multipart.saveDir und webwork.multipart.maxSize in der Konfiguration durchsucht. Wenn sie gefunden werden, wird das durch das Attribut angegebene temporäre Verzeichnis und der maximal hochgeladene Inhalt verwendet Verzeichnis der Umgebung verwendet wird.
Die spezifische Implementierung ist wie folgt:
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. Holen Sie sich die Parsing-Klasse für den Datei-Upload
Sehen wir uns an, wie der Konstruktor von MultiPartRequestWrapper die Anfrage umschließt:
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()); } } }
• Zunächst wird ermittelt, ob die eingehende Anforderung eine Unterklasse der abstrakten Klasse MultiPartRequest ist. Wenn dies der Fall ist, verweist sie über ihre eigene Variable vom Typ MultiPartRequest direkt auf die Anforderung.
• Andernfalls lesen Sie die Eigenschaft webwork.multipart.parser der WebWork-Konfiguration, die bestimmt, was Webwork intern zum Implementieren des Datei-Uploads verwendet. Wenn nicht angegeben, wird standardmäßig die Implementierung von PellMultiPartRequest verwendet.
•Nachdem WebWork die konfigurierte Klasse gefunden hat, erstellt es über Java Reflection eine Instanz dieser Klasse. Alle unterstützten Klassen erben von MultiPartRequest. Nach dem Erstellen der Instanz werden sie nach oben umgewandelt und dem Mitglied multi von MultiPartRequestWrapper zugewiesen.
• Der Datei-Upload von WebWork kapselt mehrere gängige FileUpload-Bibliotheken und ist nicht selbst implementiert.
•Es umfasst drei Implementierungen: Pell, Cos und Apache Common. WebWork kapselt diese drei Pakete und bietet eine gemeinsame Zugriffsschnittstelle MultiPartRequest. Die detaillierten Implementierungen sind PellMultiPartRequest und JakartaMultiPartRequest.
• Jakarta unterstützt mehrere Dateien mit demselben HTTP-Parameternamen. Wenn Sie den FileUpload-Interceptor von WebWork direkt verwenden, wird die Verwendung von Pell empfohlen, da beim Hochladen einer Datei mit einem chinesischen Dateinamen nur das Pell-Paket den chinesischen Dateinamen korrekt erhält und Apache Common den Dateinamen in eine Datei ändert Der Name xxx.tmp und der Name cos werden verstümmelt, sodass unsere einzige Wahl Pell ist.
•Die Funktion von cos ist relativ leistungsfähig, aber durch die Kapselung von WebWork gehen viele Funktionen verloren, die cos zum Festlegen der Zeichenkodierung der Anfrage benötigt. Die Kapselung von WebWork ist nicht festgelegt, was zu dem verstümmelten Problem von cos führt. Wenn Sie cos allein verwenden, werden Sie solche Probleme natürlich vermeiden.
3. Tatsächliche Projektkonfiguration und -nutzung
• Konfigurationsdateien
Aktionskonfiguration:
<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> //拦截栈对应的拦截器 <interceptor name="fileUpload" class="com.opensymphony.webwork.interceptor.FileUploadInterceptor"/> <interceptor name="params" class="com.opensymphony.xwork.interceptor.ParametersInterceptor"/>
•Das Frontend verwendet Ajaxupload, das relativ stabil und leistungsstark ist. Ich werde hier nicht auf Details eingehen. Es gibt eine offizielle Website: jQuery AjaxUpload-Bild-Upload-Code
•Durch die Kapselung der Webwork-Upload-Anfrage und den Erhalt der Parsing-Klasse wurde das gesamte Vorspiel vorbereitet. Die spezifische Implementierung im Upload-Interceptor ist wie folgt:
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; }
•Stellen Sie zunächst fest, ob die aktuelle Anfrage eine Multimedia-Anfrage enthält. Wenn ja, zeichnen Sie das Protokoll auf und führen Sie die Aktion aus.
•Stellen Sie dann fest, ob der MultiPartRequestWrapper während des Datei-Upload-Vorgangs Fehler enthält, geben Sie die Fehlerinformationen an den Client zurück und rufen Sie Action nicht weiter auf.
•Wenn keine der oben genannten Beurteilungsbedingungen erfüllt ist, beginnen Sie mit dem Durchlaufen der Parameter der hochgeladenen Datei in MultiPartRequestWrapper und fügen Sie den Dateinamen und den Dateiinhaltstyp in die Aktionsparameterzuordnung ein, damit nachfolgende Geschäftsklassen ausgeführt werden können.
•In der Datei-Upload-Interceptor-Funktion von WebWork handelt es sich bei der bereitgestellten Datei nur um eine temporäre Datei, die nach Ausführung der Aktion automatisch gelöscht wird. Sie müssen die Speicherung der Datei selbst in der Aktion übernehmen oder sie in ein Verzeichnis schreiben auf dem Server oder in der Datenbank speichern. Wenn Sie planen, in ein Verzeichnis auf dem Server zu schreiben, müssen Sie mit dem Problem konfrontiert werden, dass Sie selbst mit demselben Dateinamen umgehen müssen. Tatsächlich bietet das Paket cos jedoch bereits automatische Umbenennungsregeln für Dateiumbenennungen.
Der obige Code führt Sie in die relevanten Webwork-Kenntnisse zum Hoch- und Herunterladen von Dateien ein. Ich hoffe, er wird Ihnen hilfreich sein.