Local Storage
Local Storage Upload
Vamos criar dois pacotes para separarmos: o service e o controller. O pacote de service ficará nossa camada de serviço com a nossa regra de negócio, onde realizaremos a ação de salvar o arquivo e o pacote de controller vai ser usado para realizarmos nossas requisições HTTP.
@Service
public class UploadFileService {
public File salvarLocalmente(MultipartFile webFile) throws Exception{
Path caminhoDaPasta = Paths.get("C:\\imagem");
Files.createDirectories(caminhoDaPasta);
Path novoCaminhoDoArquivo = caminhoDaPasta.resolve(webFile.getOriginalFilename());
Files.copy(webFile.getInputStream(), novoCaminhoDoArquivo, StandardCopyOption.REPLACE_EXISTING);
return novoCaminhoDoArquivo.toFile();
}
}
Vamos aprofundar mais nesses métodos.
Começaremos pelo método salvarLocalmente da classe UploadFileService:
- A classe
MultipartFile
faz parte do Spring Framework e representa um arquivo carregado em uma solicitação multipart que geralmente é usada para uploads de arquivos via HTTP. - Com a utilização da classe
Path
realizamos a definição do caminho da pasta de destino especificando onde o arquivo será salvo no disco local. - Caso o diretório passado anteriormente não exista, o método createDirectories da classe
Files
garantirá a criação do diretório. - Próximo passo é realizar a cópia do arquivo enviado para o novo local indicado no novo caminho e indica que qualquer arquivo existente com o mesmo nome deve ser substituído.
- Por fim retornamos o objeto
Path
para um objetoFile
.
No método salvarLocalmente da classe UploadFileController:
- A anotação @RestController marca a classe como um controlador Spring especializado para Web RESTful. Já a @RequestMapping define a URL base para todos os endpoints dessa classe. O @Autowired injeta automaticamente uma instância do UploadFileService na classe UploadFileController para permitir que o controlador use os métodos definidos no serviço.
- Definimos o endpoint com @PostMapping e o
consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}
indica que este endpoint aceita dados de formulário multipart, o que é necessário para upload de arquivos. - A classe
MultipartFile
aparece novamente na assinatura do método justamente para indicar que será preenchido com o arquivo enviado na solicitação. E usamos a classeResponseEntity
para retornar uma mensagem de resposta do tipo String. - No bloco try iremos chamar o método salvarLocalmente do serviço e retorna um objeto
File
que representa o arquivo salvo.
O multipart é um tipo de conteúdo que permite a transmissão de diferentes tipos de dados em uma única mensagem HTTP.
Swagger Upload
Antes de avançarmos um pouco mais, precisamos adicionar nas dependências a interface gráfica e a API do Swagger:
<!-- Interface Gráfica -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.3.0</version>
</dependency>
<!-- API do Swagger -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.7.0</version>
</dependency>
Após isso, vamos acessar o endereço http://localhost:8080/swagger-ui/index.html
para acessarmos o endpoint criado.
Veja que o nosso endpoint de salvar localmente já está disponível para utilizarmos.
Conforme realizamos no desenvolvimento, é solicitado o arquivo para salvarmos localmente. Após escolher o arquivo é só executar:
Deu tudo certo com o nosso envio do arquivo. O código 200 significa sucesso e além disso a confirmação através da mensagem de retorno que adicionamos.
Só pra tirar a prova, vamos dar uma olhadinha no disco local? E aí está o arquivo, no caso a imagem salva.
Postman Upload
Com o Postman instalado vamos criar uma nova requisição. Como vamos adicionar um arquivo, nesse caso vai ser do tipo POST.
- Adicionamos o endpoint para o envio do arquivo.
- Selecionaremos a opção Body e do tipo form-data. (Lembra do
consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}
?) - A chave será file, o Tipo File e ao clicar no campo Value aparecerá a opção para adicionar o arquivo da máquina local.
Depois de adicionarmos o arquivo é só enviar a requisição:
Assim como vimos anteriormente no Swagger, recebemos a mensagem de retorno informando que deu tudo certo com nosso upload e também o código 200.
Acessando o arquivo
Agora que já fizemos o upload do arquivo, chegou a hora de acessarmos do disco. Nisso, vamos adicionar mais um método no controller. Como vamos buscar o arquivo, a nossa requisição será do tipo GET:
- Utilizamos novamente a classe
ResponseEntity
mas dessa vez retornando o tipo byte que será o conteúdo do arquivo de imagem. O parâmetroproduces = MediaType.IMAGE_JPEG_VALUE
indica que o método retorna um conteúdo do tipo image/jpeg. - Definimos o caminho da imagem que queremos acessar a através do filePath. Será usado a classe
Files
novamente para ler todos os bytes do arquivo que queremos acessar e armazena no array de bytes imagem. - Por última cria um
ResponseEntity
com status HTTP 200 OK e define o tipo de conteúdo da resposta como imagem do tipo JPEG e define o corpo da resposta com o array de bytes da imagem lido do arquivo.
Para fins didáticos usamos alguns caminhos e nome de arquivos de forma estática. Mas em aplicações reais utilizadas nas empresas e/ou outros projetos de maior escala esse caminho é sinalizado de forma dinâmica e passado geralmente pela equipe de arquitetura.
Usando o Swagger
Agora no Swagger apareceu mais um endpoint para testarmos:
Ao clicar em executar, mostrará a imagem que adicionamos anteriormente e que passamos o endereço para acessá-la:
Usando o Postman
Adicionamos o nosso endereço com o endpoint ver arquivo, a requisição será do tipo GET e depois enviamos a requisição:
Tudo certo em acessarmos o arquivo localmente:
Agora que já sabemos fazer o upload de arquivos localmente, vamos nos desafiar um pouco mais. Dessa vez, iremos realizar o upload utilizando a nuvem, nesse primeiro momento usando a AWS.