Olá Raphael! bom dia meu caro.
Então sobre o código como disse ele é extraído do projeto da Algaworks que ta no Git onde eu estudei até o 25.2 pois tudo é uma sequencia,
Algaworks
eu fiz dois cursos desta empresa porém este que abordou sobre o caso infelizmente não pude fazer, venho com o java já há algum tempo mais longe de ser um profissional, olha eu também fiz umas alterações de forma que o erro é outro observei o seguinte:
O erro agora é de servidor 500, ou seja o upload da imagem é feita e ao tentar ler para mostrar a imagem ocorre o erro 500 conforme as três imagens abaixo o Header da requisição o Response e a pasta onde esta sendo feito o upload.
Então como o código não é meu e sim do projeto do curso eu fiz utilização do mesmo por entender que utilizando a lib UIkit uma lib Frot-End tem suas vantagens e o código para fazer ela funcionar um javascript com poucas linhas e o upload esta sendo feito então o problema é no servidor, onde esta sendo salvo ( o local ) e por não estar encontrando este caminho vem o erro, o erro do response vem de uma exceção vem então o código fonte extraído do git
FotoStorageLocal.jar ( comentei dentro do código nos metodos de criar pasta e de recuperar a foto )
class FotoStorageLocal implements FotoStorage {
private static final Logger logger = LoggerFactory.getLogger(FotoStorageLocal.class);
private static final String THUMBNAIL_PREFIX = "thumbnail.";
private Path local;
private Path localTemporario;
public FotoStorageLocal() {
this(getDefault().getPath(System.getenv("HOME"), ".ecommercefotos"));
}
public FotoStorageLocal(Path path) {
this.local = path;
criarPastas();
}
@Override
public String salvarTemporariamente(MultipartFile[] files) {
String novoNome = null;
if (files != null && files.length > 0) {
MultipartFile arquivo = files[0];
novoNome = renomearArquivo(arquivo.getOriginalFilename());
try {
arquivo.transferTo(new File(this.localTemporario.toAbsolutePath().toString() + getDefault().getSeparator() + novoNome));
} catch (IOException e) {
throw new RuntimeException("Erro salvando a foto na pasta temporária", e);
}
}
return novoNome;
}
@Override
public byte[] recuperarFotoTemporaria(String nome) {
try {
return Files.readAllBytes(this.localTemporario.resolve(nome));
} catch (IOException e) {
throw new RuntimeException("Erro lendo a foto temporária", e);
}
}
@Override
public void salvar(String foto) {
try {
Files.move(this.localTemporario.resolve(foto), this.local.resolve(foto));
} catch (IOException e) {
throw new RuntimeException("Erro movendo a foto para destino final", e);
}
try {
Thumbnails.of(this.local.resolve(foto).toString()).size(40, 68).toFiles(Rename.PREFIX_DOT_THUMBNAIL);
} catch (IOException e) {
throw new RuntimeException("Erro gerando thumbnail", e);
}
}
@Override
public byte[] recuperar(String nome) {
// Não esta sendo possivel recuperar a foto na pasta mais no Response em anexo vemos que o nome da imagem esta errado e também vemos o nome da pasta
try {
return Files.readAllBytes(this.local.resolve(nome));
} catch (IOException e) {
throw new RuntimeException("Erro lendo a foto " + nome + " na pasta " + this.local.toString(), e);
}
}
@Override
public byte[] recuperarThumbnail(String fotoCerveja) {
return recuperar(THUMBNAIL_PREFIX + fotoCerveja);
}
@Override
public void excluir(String foto) {
try {
Files.deleteIfExists(this.local.resolve(foto));
Files.deleteIfExists(this.local.resolve(THUMBNAIL_PREFIX + foto));
} catch (IOException e) {
logger.warn(String.format("Erro apagando foto '%s'. Mensagem: %s", foto, e.getMessage()));
}
}
private void criarPastas() {
// Aqui onde é criado as pastas que e onde ficara os arquivos apos upload
// Este código esta criando a pasta com o nome null e sei que o motivo é o atributo
// this.local não conter valor contudo em nenhum fonte encontrei uma passagem de parametros para a chamada desta classe e ao meu entender a pasta a ser criada deve ser fotos, ou deveria
try {
Files.createDirectories(this.local);
this.localTemporario = getDefault().getPath(this.local.toString(), "temp");
Files.createDirectories(this.localTemporario);
if (logger.isDebugEnabled()) {
logger.debug("Pastas criadas para salvar fotos.");
logger.debug("Pasta default: " + this.local.toAbsolutePath());
logger.debug("Pasta temporária: " + this.localTemporario.toAbsolutePath());
}
} catch (IOException e) {
throw new RuntimeException("Erro criando pasta para salvar foto", e);
}
}
private String renomearArquivo(String nomeOriginal) {
String novoNome = UUID.randomUUID().toString() + "_" + nomeOriginal;
if (logger.isDebugEnabled()) {
logger.debug(String.format("Nome original: %s, novo nome: %s", nomeOriginal, novoNome));
}
return novoNome;
}
}
Aqui abaixo temos a classe de controller da foto
@RestController
@RequestMapping("/fotos")
public class FotosController {
private static final Logger logger = LoggerFactory.getLogger(FotosController.class);
@Autowired
private FotoStorage fotoStorage;
@PostMapping
public DeferredResult<FotoDTO> upload(@RequestParam("files[]") MultipartFile[] files) {
DeferredResult<FotoDTO> resultado = new DeferredResult<>();
Thread thread = new Thread(new FotoStorageRunnable(files, resultado, fotoStorage));
thread.start();
return resultado;
}
@GetMapping("/temp/{nome:.*}")
public byte[] recuperarFotoTemporaria(@PathVariable String nome) {
return fotoStorage.recuperarFotoTemporaria(nome);
}
@GetMapping("/{nome:.*}")
public byte[] recuperar(@PathVariable String nome) {
return fotoStorage.recuperar(nome);
}
}
e pelo que pude perceber uma classe de configuracao do serviço do spring
@Configuration
@ComponentScan(basePackageClasses = {
CategoryService.class})
public class ServiceConfig {
@Bean
public FotoStorage fotoStorage() {
return new FotoStorageLocal();
}
}
Não entendi ainda o motivo da pasta a ser criada esta sendo criada com o nome “null” mais também em nenhum local do código eu vejo a passagem de parâmetro com o nome da pasta se pensar bem nome é e pode ser qualquer um correto? mais estou hoje novamente olhando este código pra ver se desenrolo isto.