Exemplo de 1 minuto: download
O exemplo a seguir mostra como disponibilizar o download para seu cliente. Note novamente a simplicidade na implementação:
@Controller
public class PerfilController {
public File foto(Perfil perfil) {
return new File("/path/para/a/foto." + perfil.getId()+ ".jpg");
}
}
Adicionando mais informações no download
Se você quiser adicionar mais informações ao download você pode retornar um FileDownload
:
@Controller
public class PerfilController {
public Download foto(Perfil perfil) {
File file = new File("/caminho/para/a/foto." + perfil.getId()+ ".jpg");
String contentType = "image/jpg";
String filename = perfil.getNome() + ".jpg";
return new FileDownload(file, contentType, filename);
}
}
Para as situações em que você tem um InputStream
, você pode utilizar o InputStreamDownload
, conforme o exemplo abaixo:
public Download foto(Perfil perfil) {
InputStream stream = [...];
String contentType = "image/jpg";
return new InputStreamDownload(stream, contentType, filename);
}
E como outra opção há o ByteArrayDownload
, usado quando você tem um array de bytes.
public Download foto(Perfil perfil) {
byte[] conteudoFoto = [...];
String contentType = "image/jpg";
return new ByteArrayDownload(conteudoFoto, contentType, filename);
}
Você também pode enviar uma lista de arquivos para download, e desta forma eles serão enviados ao browser comprimidos em um arquivo Zip.
public Download fotos() {
Path foto01 = new File("/caminho/para/a/foto01.jpg").toPath();
Path foto02 = new File("/caminho/para/a/foto02.jpg").toPath();
return new ZipDownload("fotos.zip", foto01, foto02);
}
Usando o DownloadBuilder
DownloadBuilder
é uma classe útil para ajudar você a criar instâncias da classe Download
, usando uma interface fluente. Para criar uma instância de um FileDownload
você pode escrever o seguinte código:
FileDownload download = DownloadBuilder.of(meuArquivo)
.withFileName("curriculo.txt") // opcional, o padrão é File.getName()
.withContentType("text/plain") // optional, não será enviado se nulo
.downloadable() // opcional, o padrão é inline content
.build();
Upload
Para ativar o suporte a upload é necessário adicionar as bibliotecas commons-upload
e commons-io
em seu classpath. Veja mais informações aqui.
**Nota: ** O upload funciona apenas com métodos do seu controller anotados com @Post
. @Get
, @Put
e demais verbos não são suportados.
Exemplo de 1 minuto: upload
Para receber um upload você precisa receber um UploadedFile
em seu método conforme o exemplo abaixo. O UploadedFile
retorna o arquivo como um InputStream
. Com isso você pode copiar o arquivo para o disco facilmente.
public void atualizaFoto(Perfil perfil, UploadedFile foto) {
File fotoSalva = new File("/path/to/file/repository", foto.getFileName());
foto.writeTo(fotoSalva);
dao.atribui(fotoSalva, perfil);
}
Sobrescrevendo as configurações de upload
Há duas formas para alterar as configurações de upload.
A primeira forma é estendendo a classe DefaultMultipartConfig
. Isto é útil quando você precisa alterar o diretório temporário de arquivos ou o tamanho máximo do upload de forma global.
O valor padrão para o upload é de 2MB para cada arquivo, e o mesmo valor para a soma de todos os arquivos. Mas estes valores podem ser facilmente alterados como você pode ver no exemplo abaixo:
@Specializes
@ApplicationScoped
public class CustomMultipartConfig extends DefaultMultipartConfig {
// alteramos o tamanho total do upload para 50MB
public long getSizeLimit() {
return 50 * 1024 * 1024;
}
// alteramos o tamanho do upload de cada arquivo para 20MB
public long getFileSizeLimit() {
return 20 * 1024 * 1024;
}
}
A segunda forma é usando a anotação UploadSizeLimit
, que permite alterar a configuração do upload para um único método. No exemplo abaixo alteramos a configuração para permitir que cada arquivo tenha no máximo 10MB e o upload total tenha no máximo 40MB:
@UploadSizeLimit(sizeLimit=40 * 1024 * 1024, fileSizeLimit=10 * 1024 * 1024)
public void atualizaFoto(Perfil perfil, UploadedFile foto) {
[...]
}
A configuração pela anotação tem maior prioridade em relação a configuração global. Você pode usar as duas, porém se um método possuir a anotação UploadSizeLimit
, estes valores serão usados para validar o tamanho do upload, ignorando a configuração global.
Alterando o formulário de envio
Para que o browser possa fazer o upload corretamente, você precisa adicionar o atributo enctype para multipart/form-data
:
<form action="minha-action" method="post" enctype="multipart/form-data">
Validando o upload
Quando o tamanho máximo para upload de arquivo exceder o valor configurado, o VRaptor adiciona uma mensagem no objeto Validator
.