Solucionado (ver solução)

Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

Solucionado
(ver solução)
12
respostas

Spring não encontra a pasta "arquivos-sumario"

Bom Dia pessoal, Preciso de uma ajudinha!

Seguindo exatamente como foi apresentado no vídeo 02 da aula 09 sobre Arquivos, o Spring não reconhece a pasta "arquivos-sumario", eu já criei essa pasta dentro do webapp (criei via eclipse, New Folder e tals) enfim, sempre que tento cadastrar um produto recebo o erro 500:

HTTP Status 500 - Request processing failed; nested exception is java.lang.RuntimeException: java.io.IOException: java.io.FileNotFoundException: C:\Users\Tiago\workspaceweb\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\casadocodigo\arquivos-sumario\spring.jpg (O sistema não pode encontrar o caminho especificado)

type Exception report

message Request processing failed; nested exception is java.lang.RuntimeException: java.io.IOException: java.io.FileNotFoundException: C:\Users\Tiago\workspaceweb\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\casadocodigo\arquivos-sumario\spring.jpg (O sistema não pode encontrar o caminho especificado)

root cause

java.io.IOException: java.io.FileNotFoundException: C:\Users\Tiago\workspaceweb\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\casadocodigo\arquivos-sumario\spring.jpg (O sistema não pode encontrar o caminho especificado)
    org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile.transferTo(StandardMultipartHttpServletRequest.java:258)
    br.com.casadocodigo.loja.infra.FileSaver.write(FileSaver.java:22)
    br.com.casadocodigo.loja.controllers.ProdutosController.gravar(ProdutosController.java:57)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    java.lang.reflect.Method.invoke(Unknown Source)
    org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
    org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
    org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:781)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:721)
    org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
    org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
    org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
12 respostas
root cause

java.io.FileNotFoundException: C:\Users\Tiago\workspaceweb\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\casadocodigo\arquivos-sumario\spring.jpg (O sistema não pode encontrar o caminho especificado)
    java.io.FileOutputStream.open0(Native Method)
    java.io.FileOutputStream.open(Unknown Source)
    java.io.FileOutputStream.<init>(Unknown Source)
    java.io.FileOutputStream.<init>(Unknown Source)
    org.apache.tomcat.util.http.fileupload.disk.DiskFileItem.write(DiskFileItem.java:394)
    org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile.transferTo(StandardMultipartHttpServletRequest.java:258)
    br.com.casadocodigo.loja.infra.FileSaver.write(FileSaver.java:22)
    br.com.casadocodigo.loja.controllers.ProdutosController.gravar(ProdutosController.java:57)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    java.lang.reflect.Method.invoke(Unknown Source)
    org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
    org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
    org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:781)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:721)
    org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
    org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
    org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
note The full stack trace of the root cause is available in the Apache Tomcat/7.0.79 logs.

Apache Tomcat/7.0.79

Percebi também que na pasta física do projeto dentro de webapp não contém a pasta "arquivos-sumario", se alguém puder me ajudar serei muito grato!

Boa tarde thiago, tem como postar seu FileSaver e seu ProdutoController por favor?

Agora a pasta "arquivos-sumario" consta no projeto, mas mesmo assim, da o mesmo erro:

Produtos Controller:

package br.com.casadocodigo.loja.controllers;

import java.util.ArrayList;
import java.util.List;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import br.com.casadocodigo.loja.daos.ProdutoDAO;
import br.com.casadocodigo.loja.infra.FileSaver;
import br.com.casadocodigo.loja.models.Preco;
import br.com.casadocodigo.loja.models.Produto;
import br.com.casadocodigo.loja.models.TipoPreco;
import br.com.casadocodigo.loja.validation.ProdutoValidation;

@Controller
@RequestMapping("/produtos")
public class ProdutosController {

    @Autowired
    private ProdutoDAO produtoDao;

    @Autowired
    private FileSaver fileSaver;

    @InitBinder
    public void initBinder(WebDataBinder binder){
        binder.addValidators(new ProdutoValidation());
    }

    @RequestMapping("/form")
    public ModelAndView form(Produto p){
        ModelAndView modelAndView = new ModelAndView("produtos/form");
        modelAndView.addObject("tipos", TipoPreco.values());
        //System.out.println("Acesso ao form");
        return modelAndView;
    }

    @RequestMapping(method=RequestMethod.POST)
    public ModelAndView gravar(MultipartFile sumario, @Valid Produto p, BindingResult result, RedirectAttributes redirectAttributes){
        //System.out.println(sumario.getOriginalFilename());
        if(result.hasErrors()){
            //System.out.println("Um syso antes de chamar de novo  o form");
            return form(p);
            //return new ModelAndView("produtos/form");
        }
        String path = fileSaver.write("arquivos-sumario", sumario);
        p.setSumarioPath(path);

        produtoDao.gravar(p);

        redirectAttributes.addFlashAttribute("sucesso", "Produto cadastrado com sucesso!");

        return new ModelAndView("redirect:produtos");
    }

    @RequestMapping(method=RequestMethod.GET)
    public ModelAndView listar(){
        List<Produto> produtos = produtoDao.listar();
        ModelAndView modelAndView = new ModelAndView("produtos/lista");
        modelAndView.addObject("produtos", produtos);
        return modelAndView;
    }
}

File Saver:

package br.com.casadocodigo.loja.infra;

import java.io.File;
import java.io.IOException;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

@Component
public class FileSaver {

    @Autowired
    private HttpServletRequest request;

    public String write(String baseFolder, MultipartFile file){
        try {
            String realPath = request.getServletContext().getRealPath("\\" + baseFolder);
            String path = realPath + "\\" + file.getOriginalFilename();
            System.out.println("Path Real: " + path);
            file.transferTo(new File(path));

            System.out.println("Path Relativo: " + baseFolder + "\\" + file.getOriginalFilename());
            return baseFolder + "\\" + file.getOriginalFilename();
            //return path;
        } catch (IllegalStateException | IOException e) {
            throw new RuntimeException(e);
        } 
    }
}

Formulário:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib prefix="s" uri="http://www.springframework.org/tags"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Livros de Java, Android, Iphone, PHP, Ruby e muito mais - Casa do Código</title>
</head>
<body>

    <form:form action="${s:mvcUrl('PC#gravar').build() }" method="POST" 
        commandName="produto" enctype="multipart/form-data">
        <div>
            <label>Título</label>
            <form:input path="titulo"/>
            <form:errors path="titulo" />
        </div>
        <div>
            <label>Descrição</label>
            <form:textarea path="descricao" rows="10" cols="20"/>
            <form:errors path="descricao" />
        </div>
        <div>
            <label>Páginas</label>
            <!-- <input type="text" name="paginas"> -->
            <form:input path="paginas"/>
            <form:errors path="paginas" />
        </div>
        <div>
            <label>Data de Lançamento</label>
            <form:input path="dataLancamento" />
            <form:errors path="dataLancamento"/>
        </div>
        <c:forEach var="tipoPreco" varStatus="status" items="${tipos }">
            <div>
                <label>${tipoPreco }</label>
                <form:input path="precos[${status.index }].valor"/>
                <form:hidden path="precos[${status.index }].tipo" value="${tipoPreco }"/>
                <!--  <input type="text" name="precos[${status.index }].valor">
                <input type="hidden" name="precos[${status.index }].tipo" value="${tipoPreco }"> -->
            </div>
        </c:forEach>
        <div>
            <label>Sumário</label>
            <input name="sumario" type="file">
        </div>
        <button type="submit">Cadastrar</button>
    </form:form>
</body>
</html>

ServletSpringMVC

package br.com.casadocodigo.loja.conf;

import javax.servlet.Filter;
import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletRegistration.Dynamic;

import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class ServletSpringMVC extends AbstractAnnotationConfigDispatcherServletInitializer{

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return null;
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[] {AppWebConfiguration.class, JPAConfiguration.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] {"/"};
    }

    @Override
    protected Filter[] getServletFilters() {
        CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();
        encodingFilter.setEncoding("UTF-8");
        return new Filter[] {encodingFilter};
    }

    @Override
    protected void customizeRegistration(Dynamic registration) {
        registration.setMultipartConfig(new MultipartConfigElement(""));
    }
}

AppWebConfiguration

package br.com.casadocodigo.loja.conf;

import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.format.datetime.DateFormatter;
import org.springframework.format.datetime.DateFormatterRegistrar;
import org.springframework.format.support.DefaultFormattingConversionService;
import org.springframework.format.support.FormattingConversionService;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

import br.com.casadocodigo.loja.controllers.HomeController;
import br.com.casadocodigo.loja.daos.ProdutoDAO;
import br.com.casadocodigo.loja.infra.FileSaver;

@EnableWebMvc
@ComponentScan(basePackageClasses={HomeController.class,ProdutoDAO.class,FileSaver.class})
public class AppWebConfiguration {

    @Bean
    public InternalResourceViewResolver internalResourceViewResolver(){
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        return resolver;
    }

    @Bean
    public MessageSource messageSource(){
        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
        messageSource.setBasename("/WEB-INF/messages");
        messageSource.setDefaultEncoding("UTF-8");
        messageSource.setCacheSeconds(1);

        return messageSource;
    }

    @Bean
    public FormattingConversionService mvcConversionService(){
        DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService();
        DateFormatterRegistrar registrar = new DateFormatterRegistrar();
        registrar.setFormatter(new DateFormatter("dd/MM/yyyy"));
        registrar.registerFormatters(conversionService);

        return conversionService;
    }

    @Bean
    public MultipartResolver multipartResolver(){
        return new StandardServletMultipartResolver();
    }

}

O erro persiste:

root cause

java.lang.RuntimeException: java.io.IOException: java.io.FileNotFoundException: C:\Users\Tiago\workspaceweb\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\casadocodigo\arquivos-sumario\spring.jpg (O sistema não pode encontrar o caminho especificado)
    br.com.casadocodigo.loja.infra.FileSaver.write(FileSaver.java:29)
    br.com.casadocodigo.loja.controllers.ProdutosController.gravar(ProdutosController.java:57)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    java.lang.reflect.Method.invoke(Unknown Source)
    org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
    org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
    org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:781)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:721)
    org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
    org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
    org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
root cause

Grato desde já!

Oi Tiago, na sua classe FileSaver, tem dois System.out.println(), me cola aqui aqui o caminho que a classe ta montando por favor?

solução!

Opa, meu chute aqui. Realmente ele parece não estar encontrando a pasta arquivos-sumario. A primeira coisa é criar a pasta, se não tiver crida. Se isso já foi feito, tenta o seguinte:

  • remove o projeto do tomcat
  • apaga o tomcat da aba servers
  • adiciona o tomcat de novo
  • dois cliques no tomcat e seleciona para ele usar a instalação original do tomcat
  • adiciona o projeto
  • testa de novo :).

Um ponto para adicionar é: o arquivo vai ser adicionado na sua instalação do tomcat, não no seu projeto do eclipse, ok :)?

Tentei mudar o Server Location pra instalação do tomcat e não funcionou, a única diferença é que agora o erro mudou daquela pasta (C:\Users\deoliveira\alura\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\casadocodigo\sumarioarquivos\a.bin) pra minha pasta do tomcat (D:\Users\deoliveira\Desktop\apache-tomcat-7.0.81\wtpwebapps\casadocodigo\sumarioarquivos\a.bin), o resto do erro continua o mesmo

Existe a pasta sumarioarquivos no seu projeto? Acho que esse pode ser o problema :).

Parece que foi isso mesmo, eu tinha criado a pasta no sistema de arquivos mas o eclipse não tinha reconhecido, foi só dar um F5 no Eclipse na pasta webapp que a pasta sumarioarquivos apareceu dentro da IDE, a partir daí começou a funcionar. Estava mal acostumado com o IntelliJ hehe

Graaaande Alberto Souza deu certo, segui os passos em relação ao Tomcat, ah e obrigado também por "se adiantar" ao falar que o arquivo fica salvo na instalação do Tomcat, pq eu iria ficar procurando o arquivo igual maluco dentro da pasta "arquivos-sumario"!!!! Esse problema estava me enlouquecendo, muito obrigado pela atenção de todos. Agradeço mesmo.