Frage

Ich möchte Bilder in einen Ordner auf dem Server hochladen.

Aus irgendeinem Grund kann ich nicht.Ich verstehe nicht, warum mein Filter nicht ausgelöst wird und warum die Datei nicht hochgeladen wird.Könnte sich jemand meinen Code ansehen und mir helfen, den Grund herauszufinden, warum die Dateien nicht hochgeladen werden?

Ich werde alles einfügen, was ich bisher gemacht habe, damit Sie mir helfen können, den Fehler zu finden:

1. Commons-fileupload-1.2.1.jar und commons-io-1.4.jar zum lib-Ordner hinzugefügt (werden automatisch zum Klassenpfad hinzugefügt)

enter image description here

2.Erstellte eine XML-Datei, die die Tag-Bibliothek verfügbar macht (diese wird im WEB-INF-Ordner abgelegt).

<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib version="2.0"
   xmlns="http://java.sun.com/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
   http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd">
   <namespace>http://corejsf.com</namespace>
   <tag>
      <tag-name>upload</tag-name>
      <component>
         <component-type>javax.faces.Input</component-type>
         <renderer-type>com.corejsf.Upload</renderer-type>
      </component>
   </tag>
</facelet-taglib>

3. Erstellen Sie ein Paket für die Implementierung des Tags und platzieren Sie es in einem neuen Paket namens com.corejsf.

enter image description here

Hier ist die Quelle:

package com.corejsf;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import javax.el.ValueExpression;
import javax.faces.FacesException;
import javax.faces.component.EditableValueHolder;
import javax.faces.component.UIComponent;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.render.FacesRenderer;
import javax.faces.render.Renderer;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.fileupload.FileItem;

@FacesRenderer(componentFamily="javax.faces.Input",
   rendererType="com.corejsf.Upload")
public class UploadRenderer extends Renderer {
   public void encodeBegin(FacesContext context, UIComponent component)  
      throws IOException {
      if (!component.isRendered()) return;
      ResponseWriter writer = context.getResponseWriter();

      String clientId = component.getClientId(context);

      writer.startElement("input", component);
      writer.writeAttribute("type", "file", "type");
      writer.writeAttribute("name", clientId, "clientId");
      writer.endElement("input");
      writer.flush();
   }

   public void decode(FacesContext context, UIComponent component) {
      ExternalContext external = context.getExternalContext(); 
      HttpServletRequest request = (HttpServletRequest) external.getRequest();
      String clientId = component.getClientId(context);
      FileItem item = (FileItem) request.getAttribute(clientId);

      Object newValue;
      ValueExpression valueExpr = component.getValueExpression("value");
      if (valueExpr != null) {
         Class<?> valueType = valueExpr.getType(context.getELContext());
         if (valueType == byte[].class) {
            newValue = item.get();
         }
         else if (valueType == InputStream.class) {
            try {
               newValue = item.getInputStream();
            } catch (IOException ex) {
               throw new FacesException(ex);
            }
         }
         else {
            String encoding = request.getCharacterEncoding();
            if (encoding != null)
               try {
                  newValue = item.getString(encoding);
               } catch (UnsupportedEncodingException ex) {
                  newValue = item.getString(); 
               }
            else 
               newValue = item.getString(); 
         }
         ((EditableValueHolder) component).setSubmittedValue(newValue);  
         ((EditableValueHolder) component).setValid(true);  
      }

      Object target = component.getAttributes().get("target");

      if (target != null) {
         File file;
         if (target instanceof File)
            file = (File) target;
         else {
            ServletContext servletContext 
               = (ServletContext) external.getContext();
            String realPath = servletContext.getRealPath(target.toString());
            file = new File(realPath); 
         }

         try { // ugh--write is declared with "throws Exception"
            item.write(file);
         } catch (Exception ex) { 
            throw new FacesException(ex);
         }
      }
   }   
}

4. Dann habe ich einen Servlet-Filter hinzugefügt, um die Anforderungen zu unterscheiden und abzufangen, und ihn im selben Paket wie die benutzerdefinierte Tag-Implementierung platziert

enter image description here

Dies ist seine Quelle:

package com.corejsf;

import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

public class UploadFilter implements Filter {
   private int sizeThreshold = -1;
   private String repositoryPath;

   public void init(FilterConfig config) throws ServletException {
      repositoryPath = config.getInitParameter(
         "com.corejsf.UploadFilter.repositoryPath");
      try {
         String paramValue = config.getInitParameter(
            "com.corejsf.UploadFilter.sizeThreshold");
         if (paramValue != null) 
            sizeThreshold = Integer.parseInt(paramValue);
      }
      catch (NumberFormatException ex) {
         ServletException servletEx = new ServletException();
         servletEx.initCause(ex);
         throw servletEx;
      }
   }

   public void destroy() {
   }

   public void doFilter(ServletRequest request, 
      ServletResponse response, FilterChain chain) 
      throws IOException, ServletException {

      if (!(request instanceof HttpServletRequest)) {
         chain.doFilter(request, response);
         return;
      }

      HttpServletRequest httpRequest = (HttpServletRequest) request;

      boolean isMultipartContent 
         = ServletFileUpload.isMultipartContent(httpRequest);
      if (!isMultipartContent) {
         chain.doFilter(request, response);
         return;
      }

      DiskFileItemFactory factory = new DiskFileItemFactory();
      if (sizeThreshold >= 0)
         factory.setSizeThreshold(sizeThreshold);
      if (repositoryPath != null) 
         factory.setRepository(new File(repositoryPath));
      ServletFileUpload upload = new ServletFileUpload(factory);

      try {
         @SuppressWarnings("unchecked") List<FileItem> items 
            = (List<FileItem>) upload.parseRequest(httpRequest);
         final Map<String, String[]> map = new HashMap<String, String[]>();
         for (FileItem item : items) {
            String str = item.getString();
            if (item.isFormField())
               map.put(item.getFieldName(), new String[] { str });
            else
               httpRequest.setAttribute(item.getFieldName(), item);
         }

         chain.doFilter(new 
            HttpServletRequestWrapper(httpRequest) {
               public Map<String, String[]> getParameterMap() {
                  return map;
               }                   
               // busywork follows ... should have been part of the wrapper
               public String[] getParameterValues(String name) {
                  Map<String, String[]> map = getParameterMap();
                  return (String[]) map.get(name);
               }
               public String getParameter(String name) {
                  String[] params = getParameterValues(name);
                  if (params == null) return null;
                  return params[0];
               }
               public Enumeration<String> getParameterNames() {
                  Map<String, String[]> map = getParameterMap();
                  return Collections.enumeration(map.keySet());
               }
            }, response);
      } catch (FileUploadException ex) {
         ServletException servletEx = new ServletException();
         servletEx.initCause(ex);
         throw servletEx;
      }      
   }   
}

5.Dann habe ich den Filter in der web.xml registriert.(Ich wollte eine Annotation verwenden, aber ich wusste nicht, wie, weiß ich, wie ich das mit einer Annotation tun kann?) Auch die corejsf.taglib.xml fügte hinzu

<!-- NEEDED FOR FILE UPLOAD -->
<filter>
      <filter-name>Upload Filter</filter-name>
      <filter-class>com.corejsf.UploadFilter</filter-class>
      <init-param>
         <param-name>sizeThreshold</param-name>
         <param-value>1024</param-value>
      </init-param>
</filter>

   <filter-mapping>
      <filter-name>Upload Filter</filter-name>
      <url-pattern>/faces/upload/*</url-pattern>
   </filter-mapping> 

    <context-param>
      <param-name>javax.faces.PROJECT_STAGE</param-name>
      <param-value>Development</param-value>
   </context-param>
   <context-param>
      <param-name>facelets.LIBRARIES</param-name>
      <param-value>/WEB-INF/corejsf.taglib.xml</param-value>
   </context-param>   

6. In meinem WebContent-Ordner habe ich einen Unterordner namens „upload“ (Ziel der hochgeladenen Dateien) erstellt.

enter image description here

7.Innerhalb einer JSF-Seite verwende ich das Tag zum Hochladen und Senden und verwende außerdem eine Managed-Bean-Methode, um die Dateinamen zu erstellen:

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:corejsf="http://corejsf.com">
            ....
    <h:form enctype="multipart/form-data">

     <corejsf:upload target="upload/#{placeAddController.prepareUniqueIdentifier}" />

         ....

        <h:commandButton value="Dalje" style=" font-weight: bold;  font-size:150%; action="/submittedImage" />  

    ...

    </h:form>

Und die Java ManagedBean:

@ManagedBean
@RequestScoped
public class PlaceAddControler {
…
public String prepareUniqueIdentifier() {
        return UUID.randomUUID().toString()+"png";
    }   

-Alles scheint in Ordnung zu sein, aber etwas fehlt oder ist falsch.Was denkst du, warum wird nicht hochgeladen?

War es hilfreich?

Lösung

Der Filter wurde offenbar nicht aufgerufen.Setzen Sie Debug-Haltepunkte auf dem doFilter() Methode oder fügen Sie Logger-Anweisungen oder die des armen Mannes hinzu System.out.println() Anweisungen, um zu erfahren, welcher Code genau ausgeführt wird und welcher nicht und welche Variablen genau festgelegt wurden.

Der Filter wird nur aufgerufen, wenn die Anforderungs-URL mit der des Filters übereinstimmt <url-pattern>.Es muss mit dem URL-Muster der Anforderungs-URL übereinstimmen, wie Sie es in der Browser-Adressleiste der JSF-Seite mit dem Upload-Formular sehen.Nachdem Sie das URL-Muster konfiguriert haben, /faces/upload/*, wird es nur aufgerufen, wenn die Anforderungs-URL etwa so aussieht

http://localhost:8080/contextname/faces/upload/form.xhtml

Für die Frage, wie der Filter mit Anmerkungen versehen werden soll, verwenden Sie @WebFilter.

@WebFilter(urlPatterns={"/faces/upload/*"})
public class UploadFilter implements Filter {
    // ...
}

Ohne Zusammenhang Zu dem Problem gibt es einige Fehler im Code (ja, ich weiß, der Großteil liegt nicht bei Ihnen, ich möchte Sie nur warnen):

  1. Dieser Filter unterstützt keine Anforderungsparameter mit mehreren Werten wie foo=val1&foo=val2&foo=val3 wie Sie erhalten können, wenn in den Formularen Mehrfachauswahl oder Mehrfach-Kontrollkästchen verwendet werden.Auf diese Weise landet nur der zuletzt ausgewählte/überprüfte Wert in der Parameterzuordnung.Ich würde empfehlen, den Filtercode entsprechend zu korrigieren.

  2. Das Speichern hochgeladener Dateien im Webcontent-Ordner ist nicht sinnvoll, wenn Sie eine dauerhafte Speicherung wünschen.Wenn Sie die WAR/EAR-Datei der Webanwendung erneut bereitstellen, wird der ursprünglich erweiterte Webanwendungsordner verwendet komplett gelöscht, einschließlich der Dateien, die während der Laufzeit der Webanwendung hinzugefügt wurden.Der Webserver behält die Änderungen im frisch erweiterten Webapp-Ordner nicht bei.Wenn Sie eine dauerhaftere Speicherung wünschen, sollten Sie die Dateien außerhalb des Webapp-Ordners speichern, vorzugsweise in einem absoluten Pfad.Z.B. /var/webapp/upload.

Siehe auch:

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top