Nesse exemplo usaremos os conceitos interceptor e injeção. Por favor, leia as documentações correspondentes primeiro.
Você também precisa dos jars commons-io and commons-fileupload no seu classpath. Eles serão usados pelo MultipartRequestInterceptor, que já está incluído no VRaptor e oferece um simples caminho para fazer um upload de arquivo.
No nosso exemplo vamos seguir os seguintes passos:
Observe: O tamanho do arquivo para o upload é por padrão limitado em 2.000.000 bytes pelo VRaptor (e pode ser configurado numa versão no futuro).
Antes de começar escrever o código Java, vamos criar o formulário html para mandar o arquivo ao servidor:
<html> <form method="post" ACTION="upload.doIt.logic" ENCTYPE='multipart/form-data'> Arquivo:<input type="file" name="fileInfo" ><br> <input type="submit" name="Submit" value="send"> <input type="hidden" name="action" value="upload"> </form> </html>
Por favor, observe que o tipo de codificação do formulário é ENCTYPE='multipart/form-data'. Isso indica que o formulário inclui um arquivo e a requisição será do tipo multipart. Também observe que nós chamamos o arquivo fileInfo no formulário. Nossa lógica de negócios vai se referenciar a esse nome.
O interceptor recebe a requisição, trata, procura o arquivo, e o oferece depois. Ele faz todo trabalho 'sujo' para nós ...
Vamos escrever a classe de negócios que usa o MultipartRequestInterceptor:
package org.vraptor.examples.logic; import org.vraptor.annotations.Component; import org.vraptor.annotations.InterceptedBy; import org.vraptor.interceptor.MultipartRequestInterceptor; @Component @InterceptedBy( MultipartRequestInterceptor.class ) public class UploadLogic { public void doIt() { //omitido } }
Como você já sabe, nós usamos a anotação @InterceptedBy para avisar o VRaptor que precisa interceptar a lógica. Então o MultipartRequestInterceptor será executado antes de qualquer lógica na nossa classe. O interceptor procura e trata a requisição para nós.
O VRaptor usa o interceptor para achar o arquivo na requisição. Mas como receberemos o arquivo no final?
Muito simples, vamos injetar! Na verdade nós injetaremos um objeto wrapper.
A simples classe UploadedFileInformation representa o wrapper. Ela tem somente alguns métodos para acessar o arquivo e receber algumas informações (por exemplo o ContentType do arquivo).
Um código possível seria:
@Component @InterceptedBy( MultipartRequestInterceptor.class ) public class UploadLogic { //injeta o wrapper @In(required=false) private UploadedFileInformation fileInfo; public void doIt() { //tratamento de exceções omitido!!!! //recebe o arquivo de upload File uploadedFile = fileInfo.getFile(); System.out.println(uploadedFile.getAbsolutePath()); } }
Isso já é todo o código para tratar um upload no VRaptor. Só injeta o fileInfo e faz o que você quiser com ele. Todo o código sujo é encapsulado pelo MultipartRequestInterceptor.
Por favor, observe também a propriedade required=false da anotação @In. Como não está garantido que o arquivo realmente chega, o VRaptor não é obrigado a injetar o arquivo. Mas isso também significa que você deveria verificar o fileInfo e testar antes de usá-lo. Se você estiver com dúvidas sobre esse assunto, por avor leia o tutorial de validação.
Agora vamos mostrar o resultado usando o padrão do VRaptor. A página deve ser upload/doIt.ok.jsp:
<html> O upload foi feito com sucesso. </html>
Fazer um upload com VRaptor é muito simples. Use o MultipartRequestInterceptor e injete o UploadedFileInformation. Nada mais ... O resto não é diferente de qualquer outra lógica de negócios.