Como posso enviar um campo de texto na solicitação POST que envia um blob ao Blobstore e o recupera no manipulador de upload do blob?

9

Li várias questões semelhantes no StackOverflow, mas ainda não encontrei uma solução para esse problema.

Estou fazendo o upload de um blob do Android para o Blobstore do Google App Engine por meio de um HTTPPost para o URL de upload gerado pelo serviço do Blobstore. Quero poder enviar alguns metadados textuais com essa solicitação que identifique esse blob. Eu quero recuperar essa informação junto com a chave blob no servlet do manipulador de upload que é chamado depois que o blob é carregado.

O problema é que o blob é carregado usando a codificação multiparte e o App Engine não suporta o padrão Servlet v3.0, portanto não posso usar req.getPart () para obter a parte textual. (O blob em si é retornado pelo serviço do Blobstore, de modo que parte da solicitação já foi analisada para nós.)

Como posso contornar este problema passando apenas um parâmetro de texto junto com o arquivo que é enviado para o Blobstore e recuperá-lo no servlet que é chamado após o upload do blob?

Muito obrigado pela sua ajuda! Muito preso a este!

Aqui está o código que eu uso para o HttpPost no Android:

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

ATUALIZAÇÃO (8 de dezembro de 2014):

Eu adicionei um corpo de texto ao construtor de entidade antes de criar a multipart-entity para a solicitação HttpPost da seguinte forma:

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

Para o servlet que lida com o retorno de chamada do Blobstore depois que o blob é carregado, usei o método descrito pelo Google para analisar uma solicitação HttpPost no Google App Engine em este tutorial como dado abaixo:

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

No entanto, quando verifico a variável paramNames no armazenamento de dados após essa operação, seu valor permanece "padrão". Isso significa que nenhum campo de formulário foi encontrado na solicitação POST reescrita que o Blobstore passou para o servlet do manipulador de upload. Para onde ir a partir daqui?

    
por Price 07.12.2014 в 07:27
fonte

3 respostas

2

Existe uma maneira de postar metadados com seu blob com as informações que não seriam representadas por um blobkey:

  1. No seu formulário de envio, inclua isto:

    method="post" enctype="multipart/form-data"
    
  2. Agora você pode adicionar campos ocultos:

    <input type="hidden" name="myName" value="<%= myName %>"/>
    
  3. Ou você pode adicionar campos de entrada:

    <input type="text" name="myText" size="50" value="Enter your text"/>
    
  4. Em seu servlet, verifique se o manipulador de postagem lê os metadados

    String userName = req.getParameter("myName");
    
  5. Agora você tem o formulário de upload com todas as informações.

  6. Quando você está passando as informações para servir o blob, você pode usar

    &blobkey=daffedafdfe&myName=Blah
    

Então, você não está exatamente armazenando as informações no próprio blob, mas pode incluí-las no formulário de upload.

    
por Ying Li 14.12.2014 / 18:32
fonte
0

Pelo que eu posso dizer, o MultiPartEntityBuilder é respsonsible para criar um "formulário" HTML de enctype="multipart / form-data" e, quando você chega às linhas DefaultHttpClient, está apenas enviando a solicitação deste formulário via POST. Você deve examinar a documentação do construtor de entidades. Tem a função de adicionar campos de texto ao "formulário" [1].

[1] - link

    
por DT Rush 07.12.2014 / 21:48
fonte
0

Apenas no caso, você pode querer especificar

entityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);

depois de criar o objeto.

Se isso não funcionar, pode ser aconselhável postar requestbin para ver exatamente o que você está recebendo

    
por Javier Ramirez 10.12.2014 / 14:42
fonte