2017-10-04 7 views
0

J'utilise springboot 2x. Notre projet utilise un Custom HttpServeletRequest qui étend HttpServletRequestWrapper et implémente MultipartHttpServletRequest. Tout fonctionne bien. Mais quand je veux travailler pour le téléchargement de fichiers, il ne peut pas initialiser la requête Multipart. Il montre l'erreur:Comment initialiser la requête Multipart pour HttpServeletRequest personnalisé

java.lang.IllegalStateException: Multipart request not initialized 

Ma question est, comment puis-je résoudre cette erreur. Comment la requête Multipart sera initialisée.

Je donne tout le code à ce sujet.

public class XHttpServletRequest extends HttpServletRequestWrapper implements MultipartHttpServletRequest { 

    public XHttpServletRequest (HttpServletRequest request) { 
    super(request); 
    } 

    private MultiValueMap<String, MultipartFile> multipartFiles; 

    private String method; 

    @Override 
    public String getMethod() { 
    if (this.method == null) return super.getMethod(); 
    return this.method; 
    } 

    public void setMethod(String method) { 
    this.method = method; 
    } 

    private Map<String,String[]> parameters = new LinkedHashMap<String,String[]>(); 


    public void setParameter(String name, String value) { 
    parameters.put(name, new String[] {value}); 
    } 

    @Override 
    public String getParameter(String name) { 
    if (parameters.get(name) != null) { 
     return parameters.get(name)[0]; 
    } 
    HttpServletRequest req = (HttpServletRequest) super.getRequest(); 
    return req.getParameter(name); 
    } 

    public Map<String, String[]> getParameterMap() { 
    Map<String, String[]> result = new LinkedHashMap<String, String[]>(); 
    result.putAll(super.getRequest().getParameterMap()); 
    result.putAll(parameters); 
    return Collections.<String, String[]>unmodifiableMap(result); 
    } 

    public Enumeration<String> getParameterNames() { 
    Set<String> result = new LinkedHashSet<String>(Collections.list(super.getRequest().getAttributeNames())); 
    result.addAll(parameters.keySet()); 
    return new Vector<String>(result).elements(); 
    } 

    public String[] getParameterValues(String name) { 
    if (parameters.get(name) != null) { 
     return parameters.get(name); 
    } 
    HttpServletRequest req = (HttpServletRequest) super.getRequest(); 
    return req.getParameterValues(name); 
    } 


    @Override 
    public HttpServletRequest getRequest() { 
     return (HttpServletRequest) super.getRequest(); 
    } 

    @Override 
    public HttpMethod getRequestMethod() { 
     return HttpMethod.resolve(getRequest().getMethod()); 
    } 

    @Override 
    public HttpHeaders getRequestHeaders() { 
     HttpHeaders headers = new HttpHeaders(); 
     Enumeration<String> headerNames = getHeaderNames(); 
     while (headerNames.hasMoreElements()) { 
      String headerName = headerNames.nextElement(); 
      headers.put(headerName, Collections.list(getHeaders(headerName))); 
     } 
     return headers; 
    } 

    @Override 
    public HttpHeaders getMultipartHeaders(String s) { 
    return null; 
    } 

    @Override 
    public Iterator<String> getFileNames() { 
     return getMultipartFiles().keySet().iterator(); 
    } 

    @Override 
    public MultipartFile getFile(String name) { 
     return getMultipartFiles().getFirst(name); 
    } 

    @Override 
    public List<MultipartFile> getFiles(String name) { 
     List<MultipartFile> multipartFiles = getMultipartFiles().get(name); 
     if (multipartFiles != null) { 
      return multipartFiles; 
     } 
     else { 
      return Collections.emptyList(); 
     } 
    } 

    @Override 
    public Map<String, MultipartFile> getFileMap() { 
     return getMultipartFiles().toSingleValueMap(); 
    } 

    @Override 
    public MultiValueMap<String, MultipartFile> getMultiFileMap() { 
     return getMultipartFiles(); 
    } 

    @Override 
    public String getMultipartContentType(String s) { 
    return null; 
    } 


    /** 
    * Set a Map with parameter names as keys and list of MultipartFile objects as values. 
    * To be invoked by subclasses on initialization. 
    */ 
    protected final void setMultipartFiles(MultiValueMap<String, MultipartFile> multipartFiles) { 
     this.multipartFiles = 
       new LinkedMultiValueMap<>(Collections.unmodifiableMap(multipartFiles)); 
    } 

    /** 
    * Obtain the MultipartFile Map for retrieval, 
    * lazily initializing it if necessary. 
    * @see #initializeMultipart() 
    */ 
    protected MultiValueMap<String, MultipartFile> getMultipartFiles() { 
     if (this.multipartFiles == null) { 
      initializeMultipart(); 
     } 
     return this.multipartFiles; 
    } 

    /** 
    * Lazily initialize the multipart request, if possible. 
    * Only called if not already eagerly initialized. 
    */ 
    protected void initializeMultipart() { 
     throw new IllegalStateException("Multipart request not initialized"); 
    } 
} 

Une autre classe étend XHttpServletRequest et c'est au lieu de HttpServeletRequest dans notre projet. Le code suivant:

public class YHttpRequest extends MutableHttpServletRequest { 
    private ByteArrayOutputStream cachedBytes; 

    public YHttpRequest(HttpServletRequest request) { 
    super(request); 
    } 

    @Override 
    public ServletInputStream getInputStream() throws IOException { 
    if (cachedBytes == null) 
     cacheInputStream(); 

    return new CachedServletInputStream(); 
    } 

    @Override 
    public BufferedReader getReader() throws IOException{ 
    return new BufferedReader(new InputStreamReader(getInputStream())); 
    } 

    private void cacheInputStream() throws IOException { 
    /* Cache the inputstream in order to read it multiple times. For 
    * convenience, I use apache.commons IOUtils 
    */ 
    cachedBytes = new ByteArrayOutputStream(); 
    IOUtils.copy(super.getInputStream(), cachedBytes); 
    } 

    public List<Map<String, Object>> getListData() throws RequestException { 

    List<Map<String, Object>> data = new ArrayList<>(); 

    try { 

     ObjectMapper mapper = new ObjectMapper(); 

     data = mapper.readValue(this.getInputStream(), new TypeReference<ArrayList<LinkedHashMap>>(){}); 

     System.out.println(data); 
    } 
    catch (Exception e) { 
//  System.out.println(e.) 
     throw new RequestException("Unable to parse request data", e); 
    } 

    return data; 
    } 

    private Object cachedData = null; 

    public Object getRawData() throws RequestException { 

    Object data = new LinkedHashMap<>(); 

    try { 

     ObjectMapper mapper = new ObjectMapper(); 

//  data = mapper.readValue(this.getInputStream()); 
     try { 
     data = mapper.readValue(this.getInputStream(), new TypeReference<HashMap>() { 
     }); 
     } 
     catch (JsonMappingException e) { 
//  e.printStackTrace(); 
     } 

     try { 
     data = mapper.readValue(this.getInputStream(), new TypeReference<List<HashMap>>() { 
     }); 
     } 
     catch (JsonMappingException e) { 
//  e.printStackTrace(); 
     } 
     System.out.println(data); 
    } 
    catch (Exception e) { 
//  System.out.println(e.) 
     throw new RequestException("Unable to parse request data", e); 
    } 

    return data; 
    } 

    public Object getData() throws RequestException { 
    if (this.cachedData == null) { 
     this.cachedData = this.getRawData(); 
    } 

    return this.cachedData; 
    } 


    /* An inputstream which reads the cached request body */ 
    public class CachedServletInputStream extends ServletInputStream { 
    private ByteArrayInputStream input; 

    public CachedServletInputStream() { 
    /* create a new input stream from the cached request body */ 
     input = new ByteArrayInputStream(cachedBytes.toByteArray()); 
    } 

    @Override 
    public boolean isFinished() { 
     return input.available() == 0; 
    } 

    @Override 
    public boolean isReady() { 
     return true; 
    } 

    @Override 
    public void setReadListener(ReadListener readListener) { 
//  throw new IOException("zubair says: Method not implemented in Cached Servlet Input Stream class"); 
    } 

    @Override 
    public int read() throws IOException { 
     return input.read(); 
    } 
    } 

    // Storage for Path variable 
    private Map<String, Object> pathVariableMap = null; 

    public Map<String, Object> getPathVariableMap() { 
    if (this.pathVariableMap == null) { 
     this.pathVariableMap = new LinkedHashMap<>(); 
     this.pathVariableMap.putAll((Map<? extends String, ?>) this.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE)); 
    } 
    return this.pathVariableMap; 
    } 

    public Object getPathVariable(String key) { 
    return this.getPathVariableMap().get(key); 
    } 

    public FurinaHttpRequest setPathVariable(String key, Object value) { 
    this.getPathVariableMap().put(key, value); 
    return this; 
    } 

    public FurinaHttpRequest clearPathVariableMap() { 
    this.getPathVariableMap().clear(); 
    return this; 
    } 


} 

Le code du contrôleur:

public String handleFileUpload(YHttpRequest request) { 

     if (request.getMethod().equalsIgnoreCase("GET")){ 
      return "{}"; 
     } 

     Map<String, MultipartFile> file= request.getFileMap(); 
     try { 
      for(Map.Entry<String, MultipartFile> entry : file.entrySet()){ 
       storageService.store(entry.getValue()); 
       //model.addAttribute("message", "You successfully uploaded " + entry.getValue().getOriginalFilename() + "!"); 
       files.add(entry.getValue().getOriginalFilename()); 
      } 

     } catch (Exception e) { 
      //model.addAttribute("message", "FAIL to upload !"); 
     } 
     return "{}"; 
    } 
+0

Avez-vous enregistré explicitement MutliPartResolver? Par ailleurs, pourquoi la méthode _initializeMultipart_ renvoie-t-elle une exception à la fois? – Matt

Répondre

0

Cela fonctionne

public String handleFileUpload(YHttpRequest request) { 

      if (request.getMethod().equalsIgnoreCase("GET")){ 
       return "{}"; 
      } 
    StandardMultipartHttpServletRequest standardMultipartHttpServletRequest = new StandardMultipartHttpServletRequest(request); 

      Map<String, MultipartFile> file= request.getFileMap(); 
      try { 
       for(Map.Entry<String, MultipartFile> entry : file.entrySet()){ 
        storageService.store(entry.getValue()); 
        //model.addAttribute("message", "You successfully uploaded " + entry.getValue().getOriginalFilename() + "!"); 
        files.add(entry.getValue().getOriginalFilename()); 
       } 

      } catch (Exception e) { 
       //model.addAttribute("message", "FAIL to upload !"); 
      } 
      return "{}"; 
     }