2012-12-28 67 views
0

我一直致力於谷歌應用引擎3天后,最後遇到這個問題,我無法解決..很多研究,但可以找到任何有說服力的。 M通過Android上傳文件到GAE

設置我的Google app Engine帳戶後,當我打電話給我的應用程序url「my-app-id.appspot.com/myservlet」時,GAE上的簡單Servlet就能夠在Google bucket中寫入.txt文件。對於相同的代碼片段是在這裏:

fetchurl.java 

      DefaultHttpClient hc=new DefaultHttpClient(); 
      ResponseHandler <String> res=new BasicResponseHandler(); 
      HttpGet postMethod=new HttpGet("http://my-app-id.appspot.com/uploadservlet"); 

      String response=hc.execute(postMethod,res); 

uploadservlet.java

An example @ Complete Sample App at this link: 
    https://developers.google.com/appengine/docs/java/googlestorage/overview 

現在我的問題是,當我使用多部貫穿POST方法來發送一些文件,Servlet的@應用程序引擎不工作,並在eclipse中我收到錯誤消息「Filenotfound」。在Android的側

urlString = "http://my-app-id.appspot.com/uploadservlet"; 
    URL url = new URL(urlString); 

      // Open a HTTP connection to the URL 
      conn = (HttpURLConnection) url.openConnection(); 
      conn.setConnectTimeout(90000); 

      // Allow Inputs 
      conn.setDoInput(true); 

      // Allow Outputs 
      conn.setDoOutput(true); 

      // Don't use a cached copy. 
      conn.setUseCaches(false); 

      // Use a post method. 
      conn.setRequestMethod("POST"); 

      isOK = true; 

      conn.setRequestProperty("Connection", "Keep-Alive"); 

      conn.setRequestProperty("Content-Type", 
        "multipart/form-data;boundary=" + boundary); 

      DataOutputStream dos = new DataOutputStream(conn.getOutputStream()); 


      dos.writeBytes(twoHyphens + boundary + lineEnd); 
      dos.writeBytes("Content-Disposition: form-data; name=param1;filename=" 
          + param1 + "" + lineEnd); 
      dos.writeBytes(lineEnd); 
      dos.writeBytes(twoHyphens + boundary + lineEnd); 
      Log.e(Tag, "Param1 are written"); 

      dos.writeBytes(twoHyphens + boundary + lineEnd); 
      dos.writeBytes("Content-Disposition: form-data; name=param2;filename=" 
          + param2 + "" + lineEnd); 
      dos.writeBytes(lineEnd); 
      dos.writeBytes(twoHyphens + boundary + lineEnd); 
      Log.e(Tag, "Param2 are written"); 



      FileInputStream fileInputStream = new FileInputStream(new File(
        path)); 
      dos.writeBytes(twoHyphens + boundary + lineEnd); 
      dos.writeBytes("Content-Disposition: form-data; name=uploadedfile;filename=" 
         + path + "" + lineEnd); 
      dos.writeBytes(lineEnd); 

      Log.e(Tag, "Headers are written"); 

      // create a buffer of maximum size 

      int bytesAvailable = fileInputStream.available(); 
      int maxBufferSize = 1000; 
      // int bufferSize = Math.min(bytesAvailable, maxBufferSize); 
      byte[] buffer = new byte[bytesAvailable]; 

      // read file and write it into form... 

      int bytesRead = fileInputStream.read(buffer, 0, bytesAvailable); 

      while (bytesRead > 0) 
      { 
       dos.write(buffer, 0, bytesAvailable); 
       bytesAvailable = fileInputStream.available(); 
       bytesAvailable = Math.min(bytesAvailable, maxBufferSize); 
       bytesRead = fileInputStream.read(buffer, 0, bytesAvailable); 
      } 

      // send multipart form data necesssary after file data... 
      //dos.writeBytes(lineEnd); 
      dos.writeBytes(twoHyphens + boundary + lineEnd); 
      dos.writeBytes(lineEnd); 
      dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd); 

java文件,我想知道,如果這種做法是正確的,甚至。如果不是什麼是另一種解決方案..我也看着blobstorage,但它也是這樣做的,寫文件桶不上傳..請幫助我們......任何事情都會很棒,很感謝!

Servlet code to handle file upload and save to Google storage-- 

@MultipartConfig 
@SuppressWarnings("serial") 
    public class SecondtrygoogleServlet extends HttpServlet 
    { 
public static String BUCKETNAME = "androidbucket"; 
public static String FILENAME = "shikhatry.txt"; 

private static final long serialVersionUID = 1L; 


private static final int THRESHOLD_SIZE = 1024 * 1024 * 3; // 3MB 
private static final int MAX_FILE_SIZE = 1024 * 1024 * 40; // 40MB 
private static final int REQUEST_SIZE = 1024 * 1024 * 50; // 50MB 



public void doPost(HttpServletRequest request, HttpServletResponse response) 
     throws ServletException, IOException 
{ 
    // checks if the request actually contains upload file 
    if (!ServletFileUpload.isMultipartContent(request)) { 
     // if not, we stop here 
     return; 
    } 

    response.setContentType("text/plain"); 
    response.getWriter().println("Hello, test1 world"); 

    // configures some settings 
    DiskFileItemFactory factory = new DiskFileItemFactory(); 
    factory.setSizeThreshold(THRESHOLD_SIZE); 
    factory.setRepository(new File(System.getProperty("java.io.tmpdir"))); 

    ServletFileUpload upload = new ServletFileUpload(factory); 
    upload.setFileSizeMax(MAX_FILE_SIZE); 
    upload.setSizeMax(REQUEST_SIZE); 
    java.io.PrintWriter out = response.getWriter(); 

    try { 
      // parses the request's content to extract file data 
      List<?> formItems = upload.parseRequest(request); 
      out.println("Number of fields: " + formItems.size()); 
      Iterator<?> iter = formItems.iterator(); 


      // iterates over form's fields 
      while (iter.hasNext()) 
      { 
       out.println("Inside while loop"); 
       FileItem item = (FileItem) iter.next(); 
       // processes only fields that are not form fields 
       if (!item.isFormField()) 
       { 

        String temp = item.getFieldName(); 
        out.println("Parameter Name"+temp); 

        if(temp.equals("uploadedfile")) 
        { 
         String fileName = new File(item.getName()).getName(); 
         FILENAME = fileName+".txt"; 
         out.println("Filename"+fileName); 


         FileService fileService = FileServiceFactory.getFileService(); 
         GSFileOptionsBuilder optionsBuilder = new GSFileOptionsBuilder() 
         .setBucket(BUCKETNAME) 
         .setKey(FILENAME) 
         .setMimeType("text/html") //audio/mp3 text/html 
         .setAcl("public_read") 
         .addUserMetadata("myfield1", "my field value"); 


        AppEngineFile writableFile = 
         fileService.createNewGSFile(optionsBuilder.build()); 

        // Open a channel to write to it 
        boolean lock = false; 
        FileWriteChannel writeChannel = 
         fileService.openWriteChannel(writableFile, lock); 


        // Different standard Java ways of writing to the channel 
        // are possible. Here we use a PrintWriter: 

        InputStream inputStream = item.getInputStream(); 
        int readBytes = 0; 
        byte[] buffer = new byte[10000]; 



        while ((readBytes = inputStream.read(buffer, 0, 10000)) != -1) 
        { 
         writeChannel.write(ByteBuffer.wrap(buffer)); 

        } 

        inputStream.close(); 

        writeChannel.closeFinally(); 
        response.getWriter().println("Done writing..."); 

       } 
       else if(temp.equals("param1")) 
       { 
        out.println("Inside param1"); 
        //String param1Val = new File(item.getName()).getName();       
        //BUCKETNAME = param1Val; 
       } 
       else if(temp.equals("param2")) 
       { 
        out.println("Inside param2"); 
        //String param2Val = new File(item.getName()).getName(); 

        //BUCKETNAME = param2Val; 


       } 
      } 
     } 
     request.setAttribute("message", "Upload has been done successfully!"); 
    } catch (Exception ex) { 
     request.setAttribute("message", "There was an error: " + ex.getMessage()); 
    } 


} 
+0

此外,我試圖上傳文件在Amazon Bucket S3和Windows Azure上,他們提供了直接的方式來做同樣的事情。我正在最困難的時間在Google上弄明白這一點。 –

回答

1

選項包括:

一個。使用createUploadURL以表格上傳大文件,或

b。使用你的方法,然後解碼解析上傳並寫入到servlet中的blobstore(文件需要小於32MB),或者

c。使用Google Cloud Storage API直接寫入GCS,然後將上傳的文件名發佈到您的應用程序。

+0

感謝您的回覆@ Stuart ..我不能去選擇a。因爲我無法在我的應用程序中形成..B。我有我自己的方法來解析上傳文件...我用它之前..但問題是我的servelt駐留在Appengine沒有收到任何文件,當我做HttpURLConnetion(上面描述的方法)... C.Yeah我也讀了關於它,我不知道如何使用這個API ...你能給我任何鏈接,有一些使用API​​的例子??任何幫助將是偉大的..我真的需要這個! –

+0

我也編輯了我的問題:我添加了B選項的servlet代碼。 –

+0

請注意,您不需要使用選項A的表單 - 您只需將MIME多部分消息發佈到從createUploadURL返回的URL即可。 –