2014-12-07 14 views
9

Przeczytałem kilka podobnych pytań na temat StackOverflow, ale jeszcze nie znalazłem rozwiązania tego problemu.Jak mogę przesłać pole tekstowe w żądaniu POST, które przesyła blob do Blobstore i pobiera go w procedurze ładowania dla obiektu blob?

Przesyłam blob od Androida do blobstore App Engine za pośrednictwem HTTPPost do URL-a wysyłania wygenerowanego przez usługę Blobstore. Chcę móc wysyłać niektóre tekstowe metadane z tą prośbą, która identyfikuje ten obiekt typu blob. Chcę pobrać te informacje wraz z kluczem typu blob w servlecie obsługi przesyłania, który jest wywoływany po przesłaniu obiektu blob.

Problem polega na tym, że obiekt typu blob jest przesyłany przy użyciu kodowania wieloczęściowego, a App Engine nie obsługuje standardu Servlet v3.0, więc nie można użyć polecenia req.getPart() w celu pobrania części tekstowej. (Sam blob jest zwracany przez usługę Blobstore, więc część żądania została już dla nas przeanalizowana.)

Jak mogę obejść ten problem, przekazując tylko jeden parametr tekstowy wraz z plikiem przesłanym do Blobstore i pobrać go w apletu, który jest wywoływany po przesłaniu obiektu blob?

Dziękuję bardzo za pomoc! Całkiem utknąłem na tym!

Oto kod, który używam do HttpPost na Androida:

 File file = new File(filePath); 
     MultipartEntityBuilder entityBuilder = MultipartEntityBuilder 
       .create(); 
     entityBuilder.addBinaryBody("file", file);   
     DefaultHttpClient httpClient = new DefaultHttpClient(); 
     HttpPost httpPost = new HttpPost(blobUploadURL); 
     httpPost.setEntity(entityBuilder.build()); 
     try { 
      HttpResponse response = httpClient.execute(httpPost); 
      statusCode = response.getStatusLine().getStatusCode(); 
     } 

UPDATE (08 grudnia, '14):

dodałem text-ciało budowniczego jednostki przed budową wieloczęściowej podmiot na wniosek HttpPost co następuje:

 String param="value"; 
     entityBuilder.addTextBody("param", param); 

dla serwletu, który obsługuje wywołania zwrotnego w Blobstore po blob dodał, użyłem metody opisanej przez Google do analizowania żądania HttpPost na App Engine w this tutorialu jak podano poniżej:

@Override 
protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
     throws ServletException, IOException { 

    String paramNames="default"; 

    try { 
     ServletFileUpload upload=new ServletFileUpload(); 
     FileItemIterator iterator=upload.getItemIterator(req); 
     while(iterator.hasNext()){ 
      FileItemStream item=iterator.next(); 
      InputStream stream=item.openStream(); 
      if(item.isFormField()){ 
       paramNames+=item.getFieldName() + ", "; 
      } 
     } 
    } catch (FileUploadException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
     paramNames="error"; 
    } 

    //save the paramNames variable in the Datastore for debugging later 
    saveParamNamesInDatastore(paramNames); 
} 

Jednak, kiedy sprawdzić zmienną paramNames w magazynie danych po tej operacji, jej szczątki wartości "domyślna". Oznacza to, że nie znaleziono pola formularza w przepisanym żądaniu POST, które Blobstore przekazał do serwletu obsługującego przesyłanie. Gdzie iść?

Odpowiedz

2

Istnieje sposób, aby opublikować metadanych z blob z informacjami, które nie byłyby reprezentowane przez blobkey:

  1. w formularzu wysyłania, to w ten sposób:

    method="post" enctype="multipart/form-data" 
    
  2. teraz można dodać ukryte pola:

    <input type="hidden" name="myName" value="<%= myName %>"/> 
    
  3. lub można dodać pola wejściowe:

    <input type="text" name="myText" size="50" value="Enter your text"/> 
    
  4. W swojej serwletu, upewnij się, że funkcja obsługi po odczytuje metadane

    String userName = req.getParameter("myName"); 
    
  5. Teraz masz Upload formularz z wszystkimi informacjami.

  6. Po minięciu informacje służyć blob, można użyć

    &blobkey=daffedafdfe&myName=Blah 
    

Tak więc, nie są dokładnie przechowywanie informacji w samej kropelka, ale można umieścić go w przesłać formularz.

+0

Dzięki za sugestię! Wierzę, że request.setParameter() nie działa z kodowaniem wieloczęściowym. Czy możesz potwierdzić, czy to działa? Jeśli tak, bardzo pomocne byłoby zobaczenie kodu Java dla żądania przesłania i procedury obsługi przesyłania blob. – Price

+0

Dlaczego potrzebujesz .setParameter na obiekcie żądania? Wielokrotny formularz powinien wysłać wiadomość do obsługi, która zawiera wszystkie pola (w tym metadane podane w formularzu). Tak więc w module obsługi Postletu apletu, po prostu użyj .getParameter ("parameterName") i wyodrębnij meta-dane, które chcesz z Blobem. –

+0

Dzięki! Przetestuję metodę request.getParameter ("paramName") w servlecie obsługi przesyłania, ale wątpię, czy zadziała. Czy próbowałeś już tego wcześniej? – Price

0

Z tego, co wiem, MultiPartEntityBuilder jest odpowiedzialny za wyśmiewanie "formularza" HTML typu enctype = "multipart/form-data", a następnie, gdy dojdziesz do linii DefaultHttpClient, po prostu wysyłasz wniosek z tego formularza za pośrednictwem POST. Powinieneś zajrzeć do dokumentu documentaiton dla twórcy obiektu. Ma funkcję dodawania pól tekstowych do "formularza" [1].

[1] - http://hc.apache.org/httpcomponents-client-ga/httpmime/apidocs/org/apache/http/entity/mime/MultipartEntityBuilder.html#addTextBody(java.lang.String,%20java.lang.String)

+0

Dzięki! Poszedłem za twoją sugestią i zaktualizowałem moje pytanie, aby odzwierciedlić wyniki tego procesu. Czy możesz rzucić okiem i zaproponować kolejne kroki? – Price

0

Na wszelki wypadek warto określić

entityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);

po utworzeniu obiektu.

Jeśli to nie działa, to może być wskazane, aby umieścić przed requestbin zobaczyć dokładnie to, co otrzymujesz

+0

Dzięki Javier! Ustawienie trybu zgodnego przeglądarki nie pomogło. Opubliko wanie w przypadku requestbin potwierdziło, że żądanie zawiera parametr "param" jako "parametr formularza/postu". – Price

Powiązane problemy