Codename One中的多部分图片上传问题

问题描述:

我正在使用此代码上传图片。它工作在模拟器,但总是在Android设备上失败(OS 6.0)Codename One中的多部分图片上传问题

我的代码是

`private void uploadImage3(final String imagePath, String id){ 
     final Hashtable htArg = new Hashtable(); 
     htArg.put("pk1value", id); 
     htArg.put("pk2value", ""); 
     htArg.put("pk3value", ""); 
     htArg.put("datatype", "6"); 
     htArg.put("module", ""); 
     htArg.put("action", ""); 
     try { 
      htArg.put("thefile", FileSystemStorage.getInstance().openInputStream(imagePath)); 
     } catch (IOException ex) { 
      Log.p("imgRequest.Error = " + ex.toString()); 
     } 
     htArg.put("submit", "Submit"); 


     final String boundary = "-----------------------------"; 

     MultipartRequest request = new MultipartRequest(){ 
      @Override 
      protected void buildRequestBody(OutputStream os) throws IOException { 
       Writer writer = null; 
       writer = new OutputStreamWriter(os, "UTF-8"); 
       String CRLF = "\r\n"; 
       boolean canFlushStream = true; 

       Enumeration e = htArg.keys(); 

       while(e.hasMoreElements()) { 
        if (shouldStop()) { 
          break; 
        } 
        String key = (String)e.nextElement(); 
        Object value = htArg.get(key); 

        writer.write("--"); 
        writer.write(boundary); 
        writer.write(CRLF); 

        if(value instanceof String) { 
         writer.write("Content-Disposition: form-data; name=\""+key+"\""); 
         writer.write(CRLF); 
         writer.write(CRLF); 
         writer.write(CRLF); 
         if(canFlushStream){ 
          writer.flush(); 
         }     
         writer.write(Util.encodeBody((String)value)); 

         if(canFlushStream){ 
          writer.flush(); 
         } 
        }else { 
         writer.write("Content-Disposition: form-data; name=\"" + key + "\"; filename=\"" + key +"\""); 
         writer.write(CRLF); 
         writer.write("Content-Type: "); 
         writer.write("image/jpeg"); 
         writer.write(CRLF); 
         writer.write("Content-Transfer-Encoding: binary"); 
         writer.write(CRLF); 
         writer.write(CRLF); 
         if(canFlushStream){ 
          writer.flush(); 
         } 
         InputStream i; 
         if (value instanceof InputStream) { 
          i = (InputStream)value; 
          byte[] buffer = new byte[8192]; 
          int s = i.read(buffer); 
          while(s > -1) { 
            os.write(buffer, 0, s); 
            if(canFlushStream){ 
             writer.flush(); 
            } 
            s = i.read(buffer); 
          } 
          // (when passed by stream, leave for caller to clean up). 
          if (!(value instanceof InputStream)) { 
            Util.cleanup(i); 
          } 
         } else { 
           os.write((byte[])value); 
         } 
         value = null; 
         if(canFlushStream){ 
          writer.flush(); 
         } 
        } 
        writer.write(CRLF); 
        if(canFlushStream){ 
         writer.flush(); 
        } 
       } 
       writer.write("--" + boundary + "--"); 
       writer.write(CRLF); 
       if(canFlushStream){ 
        writer.flush(); 
       } 
       writer.close(); 
      } 

      @Override 
      protected void readResponse(InputStream input) { 
       try { 
        Result result = Result.fromContent(input, Result.XML); 

        Log.p("imgRequest response: " + result.toString()); 
       } catch (Exception ex) { 
        Log.p("imgRequest.Error = " + ex.toString()); 
        ex.printStackTrace(); 
       } 
      } 

      @Override 
      protected void handleErrorResponseCode(int code, String message) { 
       Log.p("handleErrorResponseCode = "+code + ":" + message); 
      } 

      @Override 
      protected void handleException(Exception err) { 
       Log.p("handleException = "+err.toString()); 
       err.printStackTrace(); 
      } 
     }; 


     String theURL = Application.getCurrentConnection().get("URL").toString() + "/W1Servlet"; 
     request.setUrl(theURL+"/uploadfiledebug"); 
     request.setBoundary(boundary); 
     request.setPost(true); 

     try { 
      //need to keep this code as it will calculate file size internally 
      // and also have to add thefile separately in myArgHashTable 
      request.addData("thefile", imagePath, "image/jpeg"); 
      request.setFilename("thefile", "img.jpeg"); 

     } catch (Exception ex) { 
     } 

     InfiniteProgress prog = new InfiniteProgress(); 
     Dialog dlg = prog.showInifiniteBlocking(); 
     request.setDisposeOnCompletion(dlg); 
     NetworkManager.getInstance().addToQueueAndWait(request); 
    }` 

真实设备的跟踪误差,

`java.net.ProtocolException: exceeded content-length limit of 11076 bytes 
at com.android.okhttp.internal.http.RetryableSink.write(RetryableSink.java:58) 
at com.android.okhttp.okio.RealBufferedSink.close(RealBufferedSink.java:234) 
at com.android.okhttp.okio.RealBufferedSink$1.close(RealBufferedSink.java:209) 
at com.codename1.impl.CodenameOneImplementation.cleanup(CodenameOneImplementation.java:4385) 
at com.codename1.impl.android.AndroidImplementation.cleanup(AndroidImplementation.java:4579) 
at com.codename1.io.Util.cleanup(Util.java:149) 
at com.codename1.io.BufferedOutputStream.close(BufferedOutputStream.java:287) 
at com.codename1.impl.CodenameOneImplementation.cleanup(CodenameOneImplementation.java:4385) 
at com.codename1.impl.android.AndroidImplementation.cleanup(AndroidImplementation.java:4579) 
at com.codename1.io.ConnectionRequest.performOperation(ConnectionRequest.java:804) 
at com.codename1.io.NetworkManager$NetworkThread.run(NetworkManager.java:282) 
at com.codename1.impl.CodenameOneThread$1.run(CodenameOneThread.java:60) 
at java.lang.Thread.run(Thread.java:818)` 

我不知道我是什么失踪。

请有人可以帮助我。

感谢

更新的代码

`private void uploadImage4(final String imagePath, String id){ 
     MultipartRequest request = new MultipartRequest(){ 
      @Override 
      protected void readResponse(InputStream input) throws IOException { 
       try { 
        Result result = Result.fromContent(input, Result.XML); 
        if(isDebugOn){ 
         Application.writeInDebugFile(debugFileName, 
          "result.toString(): "+ result.toString()); 
        } 
        Log.p("imgRequest response: " + result.toString()); 
       } catch (Exception ex) { 
        Log.p("imgRequest.Error = " + ex.toString()); 
        ex.printStackTrace(); 
        if(isDebugOn){ 
         Application.writeInDebugFile(debugFileName, 
          "readResponse.Exception: "+ex.toString()); 
        } 
       } 
      } 
     }; 
     String theURL = Application.getCurrentConnection().get("URL").toString() + "/W1Servlet"; 
     request.setUrl(theURL+"/uploadfiledebug"); 

     request.addArgument("entityname", "RCV_HEADERS"); 
     request.addArgument("category", "37"); 
     request.addArgument("description", "Uploaded by More4Apps Mobile App"); 
     request.addArgument("pk1value", id);//this is used as a primary key 
     request.addArgument("pk2value", ""); 
     request.addArgument("pk3value", ""); 
     request.addArgument("datatype", "6"); 
     request.addArgument("module", ""); 
     request.addArgument("action", ""); 

     request.addArgument("submit", "Submit"); 

     try { 
      //add the data image 
      request.addData("thefile", imagePath, "image/jpeg"); 
      request.setFilename("thefile", "img.jpeg"); 
     } catch (IOException ex) { 
      Log.p("Error:"+ ex.toString()); 
     } 

     request.setPriority(ConnectionRequest.PRIORITY_CRITICAL); 
     NetworkManager.getInstance().addToQueue(request); 
    }` 

而且新的错误是:

`<ERROR_MESSAGE>IO Error:com.more4apps.mobile.ActionUploadFileoracle.ord.im.OrdHttpUploadException: IMW-00106: the end-of-headers delimiter (CR-LF) was not present 
IMW-00112: additional error information: Content-Type: text/plain; charset=UTF-8IMW-00106: the end-of-headers delimiter (CR-LF) was not present 
IMW-00112: additional error information: Content-Type: text/plain; charset=UTF-8 
oracle.ord.im.OrdMultipartParser.doParse(OrdMultipartParser.java:312) 
oracle.ord.im.OrdMultipartParser.parseFormData(OrdMultipartParser.java:150) 
oracle.ord.im.OrdHttpUploadFormData.parseFormData(OrdHttpUploadFormData.java:532) 
com.more4apps.mobile.ActionUploadFile.performAction(ActionUploadFile.java:39) 
com.more4apps.mobile.W1Servlet.processAction(W1Servlet.java:449) 
com.more4apps.mobile.W1Servlet.doPost(W1Servlet.java:248) 
javax.servlet.http.HttpServlet.service(HttpServlet.java:763) 
javax.servlet.http.HttpServlet.service(HttpServlet.java:856) 
com.evermind.server.http.ResourceFilterChain.doFilter(ResourceFilterChain.java:64) 
oracle.apps.jtf.base.session.ReleaseResFilter.doFilter(ReleaseResFilter.java:26) 
com.evermind.server.http.EvermindFilterChain.doFilter(EvermindFilterChain.java:15) 
oracle.apps.fnd.security.AppsServletFilter.doFilter(AppsServletFilter.java:318) 
com.evermind.server.http.ServletRequestDispatcher.invoke(ServletRequestDispatcher.java:642) 
com.evermind.server.http.ServletRequestDispatcher.forwardInternal(ServletRequestDispatcher.java:391) 
com.evermind.server.http.HttpRequestHandler.doProcessRequest(HttpRequestHandler.java:908) 
com.evermind.server.http.HttpRequestHandler.processRequest(HttpRequestHandler.java:458) 
com.evermind.server.http.AJPRequestHandler.run(AJPRequestHandler.java:313) 
com.evermind.server.http.AJPRequestHandler.run(AJPRequestHandler.java:199) 
oracle.oc4j.network.ServerSocketReadHandler$SafeRunnable.run(ServerSocketReadHandler.java:260) 
com.evermind.util.ReleasableResourcePooledExecutor$MyWorker.run(ReleasableResourcePooledExecutor.java:303) 
java.lang.Thread.run(Thread.java:682)</ERROR_MESSAGE>` 

如果你在一个多要求覆盖buildRequestBody将有效地禁用它的功能...

所有这些代码都是不正确的,不应该在那里。默认情况下,Multipart将适用于大文件。

+0

我尝试了你建议的方式,但现在它给出了另一个错误。我已经更新了这个问题。 –

+0

你可以看看通过网络传递的数据吗?我没有看到这种情况可能发生在多部分源代码中:https://github.com/codenameone/CodenameOne/blob/b21f7ae1d78538554c2c188cbab139102bd4a47c/CodenameOne/src/com/codename1/io/MultipartRequest.java#L292 –

+0

好的我把它整理好了。谢谢。 –