não consegui testar aqui (a versão do meu plugin do gae tá desatualizada)
mas testa isso:
- remova o AppEngineMultipartInterceptor do vraptor-gae.jar
 
- remova os jars commons-fileupload e commons-io
 
- troque os jars do pico pelos do spring
 
isso deveria funcionar
         
        
          
        
           
           
           
         
         
            
            
          
       
      
        
        
          [quote=Lucas Cavalcanti]não consegui testar aqui (a versão do meu plugin do gae tá desatualizada)
mas testa isso:
- remova o AppEngineMultipartInterceptor do vraptor-gae.jar
 
- remova os jars commons-fileupload e commons-io
 
- troque os jars do pico pelos do spring
 
isso deveria funcionar[/quote]
só trocando pelo pico esta funcionando tudo como deveria … o request não chega mais null se precisar …e o vraptor voltou a popular corretamente a entidade…é algo com o spring mesmo que ta fazendo o request ficar null …e assim atrapalhando o vraptor a popular automatico a entidade…
public void saveOrUpdate(Explicacao explicacao) throws IOException  {			
			Map<String, BlobKey> blobs = blobStoreService.getUploadedBlobs(request);
			BlobKey fotoKey = blobs.get("foto");
			if (fotoKey != null) {
				explicacao.setUrl(fotoKey.getKeyString());
			}
			result.include("operation", daoExplicacao.saveOrUpdate(explicacao));
			result.redirectTo(this).message();
	}
Resumindo a unica coisa que fiz foi trocar pelo pico container…
Abraços
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          [quote=Lucas Cavalcanti]não consegui testar aqui (a versão do meu plugin do gae tá desatualizada)
mas testa isso:
- remova o AppEngineMultipartInterceptor do vraptor-gae.jar
 
- remova os jars commons-fileupload e commons-io
 
- troque os jars do pico pelos do spring
 
isso deveria funcionar[/quote]
Ja fiz esse teste e mesmo assim chegava null utilizando o spring…
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          funciona por causa de um bug do vraptor+pico 
esse bug que o garcia-jj corrigiu: https://github.com/caelum/vraptor/issues/335
vou tentar fazer isso funcionar de qqer forma. []'s
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          [quote=Lucas Cavalcanti]funciona por causa de um bug do vraptor+pico 
esse bug que o garcia-jj corrigiu: https://github.com/caelum/vraptor/issues/335
vou tentar fazer isso funcionar de qqer forma. []'s[/quote]
Bem estranho… pq do ponto de vista do VRaptor, isso não é um fileupload. O upload é tratado pelo Blobstore e você só recebe a BlobKey já pronta. A URL que vai no seu form não é da sua aplicação, é do Google.
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          
Uso o GAE diariamente com VRaptor e acho melhor usar o Pico mesmo. O Spring no GAE é muito lento.
Uma outra dica seria usar o scanning estático do VRaptor, rodando ele no momento do build, ao invés de usar o scanning dinâmico default que roda quando a aplicação sobe (isso faz sua instância demorar muito no GAE).
No meu build.xml, tenho:
	<target name="cpscan" depends="compile, prepare-to-production">
		<java fork="true" classname="br.com.caelum.vraptor.scan.VRaptorStaticScanning"
			  classpathref="project.classpath">
		</java>
	</target>
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          O VRaptor intercepta as requisições ah*. Sendo assim o request é lido como multipart.
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          
Verdade, tem um ano que abri essa issue: https://github.com/caelum/vraptor/issues#issue/203
Aqui no projeto tenho um hack pra ele não filtrar ah*
Mas de qualquer forma, o pau que tá dando não é no request ah* do BlobStore, é no request seguinte, quando o BlobStore redireciona pra URL da aplicação. Nesse request seguinte, acho que não é multipart (será?), porque o arquivo foi tratado no request anterior do BlobStore
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          Será que por padrão não interceptar as páginas ah* é correto? Pergunto isso porque será que não haverá casos onde precisariamos interceptar essas páginas? Pergunto para ti isso porque sei que tu tens muita experiência no GAE/J.
Uma sugestão que o Lucas deu foi de dar suporte ao blobstore como multipart-interceptor.
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          Pro GAE, eu acho correto não filtrar _ah*. Esses endereços são usados só pelo GAE (login, blobstore, painel de admin etc).
O usuário até pode configurar uma URL da aplicação como _ah/blabla mas isso é feio; acho razoável assumir que as URLs _ah* são sempre do GAE e não da aplicação.
E do Blobstore passar pelo VRaptor, acho que não tem como. Não tem uma API pra inserir no Blobstore arbitrariamente, apenas usando o mecanismo dele de upload pelo BlobstoreService. Acho que o VRaptor não deve se meter nisso. Precisamos só descobrir direito qual foi o bug que fez os parâmetros não chegarem direito no Spring
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          O bug é porque o pico não estava processando upload no GAE. Houve uma correção há alguns dias para isso.
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          Oi pessoal. Não sei se esse tópico já é assunto superado, mas estou passando pelo problema e fiquei com uma dúvida.
No caso, estou conseguindo acessar todos os campos do meu formulário original via request.getParameter(). O “problema” é que eu não gostaria de perder a praticidade que o VRaptor me dá para povoar o objeto que é parâmetro de entrada do método. Então, a pergunta é: uma vez que o código do meu método começou a ser executado, há como eu passar, por exemplo, o request para alguma classe do VRaptor, de forma que essa chamada caia num outro método com as propriedades de meu objeto de entrada já setadas?
Não sei se expliquei direito a dúvida. Qualquer coisa posso tentar detalhar melhor…
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          vc não pode receber o objeto que vc quer que seja populado no método do controller?
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          Teoricamente sim. Mas, por algum motivo que não sei explicar, se o método do controller tiver algum parâmetro, eu volto a receber a exceção lá do começo da thread. Meu código só funcionou quando comecei a usar um método sem parâmetros…
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          ah, isso acontece só nos uploads…
o que a gente geralmente faz (e mtos sistemas fazem) é separar o upload do resto dos dados… ou seja, vc usa um form só pro upload e o resto dos dados vc seta em outro lugar
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          Pois eh, eu acabei fazendo isso, mas continuei pensando a respeito e fiquei com a impressão que o processo fica “burocrático” assim. Inclusive em outro sistema que tinha feito, os casos de upload fiz em forms separados…
De qualquer maneira, separar o cadastro em dois forms me gera um problema em potencial: detectar blobs orfãos na blobstore (para o caso do formulário seguinte não ser persistido. Acho que isso é uma questão para a lista do GAE (na verdade, já postei isso lá), mas (por curiosidade) alguém aqui do forum, que desenvolve para o GAE, já se preocupou com isso?
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          Olá pessoal!
Tenho um assunto que anda no mesmo caminho, então não vou criar uma nova discussão.
após chamar a url de upload gerada (_ah*) o próprio GAE me redireciona pra URL que eu informei no método createUploadUrl() certo?
Estou obtendo um 404 nessa requisição para a url de callback que informei nesse método.
03:10:54,146 DEBUG [VRaptor             ] VRaptor received a new request
... Request components are ...
03:10:54,146 DEBUG [PicoComponentRegistry] There's no @SessionScoped component, so skipping session container creation
03:10:54,157 DEBUG [PicoComponentAdapter] New adapter for app.infra.CriadorDeSessaoDB
03:10:54,160 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor ResourceLookupInterceptor
03:10:54,161 DEBUG [DefaultResourceTranslator] trying to access /_ah/upload/agtjb3JyZXRvcnJtanIbCxIVX19CbG9iVXBsb2FkU2Vzc2lvbl9fGFsM
Jul 18, 2011 12:10:54 AM com.google.appengine.tools.development.LocalResourceFileServlet doGet
WARNING: No file found for: /fotos
Ele tenta procurar por um arquivo e não acha?
Fiz um teste básico aqui apenas com servlet. A requisição para url de callback foi feita certinho.
Valeu 
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          Isso funciona bem aqui. Cola ai o trecho de código do JSP onde vc faz o upload, e o método do seu controller que deve receber a chamada da blobstore…
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          @Post("/fotos")
public void create(Foto foto) {
	Map<String, BlobKey> blobs = blobService.getUploadedBlobs(request);
	BlobKey blobKey = blobs.get("arquivo");
}
<form action="<%= blobstoreService.createUploadUrl("/fotos") %>" method="post" enctype="multipart/form-data">
	<p><input type="file" name="arquivo"></p>
	<p><input class="buttons" type="submit" value="Salvar"/></p> 
</form>
É isso aí.
Agora o método create() não chega nem a ser chamado.
Dá 404. Já quando eu faço uma requisição pra ele pelo form, ele é chamado normalmente.
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          Experimenta tirar o argumento do método create. Deixa assim:
@Post("/fotos")  
public void create() {  
    Map<String, BlobKey> blobs = blobService.getUploadedBlobs(request);  
    BlobKey blobKey = blobs.get("arquivo");  
}