2017-10-04 39 views
0

我正在使用springboot 2x。我们的项目使用自定义HttpServeletRequest,它扩展了HttpServletRequestWrapper并实现了MultipartHttpServletRequest。一切正常。但是当我想要上传文件时,它不能初始化Multipart请求。它显示错误:如何初始化自定义HttpServeletRequest的多部分请求

java.lang.IllegalStateException: Multipart request not initialized 

我的问题是,我该如何解决这个错误。多部分请求将如何初始化。

我正在提供有关此的所有代码。

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"); 
    } 
} 

另一个类扩展了XHttpServletRequest,而不是我们的项目中的HttpServeletRequest。下面的代码:

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; 
    } 


} 

控制器代码:

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

你有明确的注册MutliPartResolver?顺便说一句,为什么_initializeMultipart_方法一次抛出异常? – Matt

回答

0

这将工作

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 "{}"; 
     }