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