Solucionado (ver solução)
Solucionado
(ver solução)
6
respostas

Problema com o FileSaver

Estou recebendo uma NullPointer ao enviar o arquivo, ela acusa a linha de declaração da String do path, já verifiquei tudo varias vezes e não aparenta ter nada de errado...alguma ideia?

6 respostas

Oi Nícolas, tudo bem?

Poste seu código fonte junto ao erro, por favor.

Abraço!

Claro Otávio, ta aqui:

package br.com.nick.casadocodigo.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 fileWriter(String basePath, MultipartFile file) {

        try {
            String realPath = request.getServletContext().getRealPath("/" + basePath);
            String path = realPath + "/" + file.getOriginalFilename();
            file.transferTo(new File(path));

            return basePath + "/" + file.getOriginalFilename();

        } catch (IllegalStateException | IOException e) {
            throw new RuntimeException(e);
        }

    }

}

Erro:

java.lang.NullPointerException
    br.com.nick.casadocodigo.infra.FileSaver.fileWriter(FileSaver.java:22)
    br.com.nick.casadocodigo.controllers.ProdutosController.confirmaProduto(ProdutosController.java:89)
    java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.base/java.lang.reflect.Method.invoke(Method.java:564)
    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)

O seu método fileWriter está recebendo null no parâmetro file. Posta sua classe ProdutosController para eu dar uma olhada também, por favor.

Abraço!

Desculpa os vários comments, mas primeira vez usando o Spring, só assim pra fazer sentido kkk

package br.com.nick.casadocodigo.controllers;

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.nick.casadocodigo.daos.ProdutoDAO;
import br.com.nick.casadocodigo.infra.FileSaver;
import br.com.nick.casadocodigo.models.Produto;
import br.com.nick.casadocodigo.models.TipoPreco;
import br.com.nick.casadocodigo.validation.ProdutoValidation;

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

    /*
     * injecao de dependencia, falamos pro Spring que eh dever dele instanciar e
     * cuidar do objeto dao realizando assim a inversao de controle, deixando de ser
     * responsabilidade do dev e passando a ser do framework
     */
    @Autowired
    private ProdutoDAO dao;

    /*
     * injeta o fileSaver para salvar um multipart file
     */
    @Autowired
    private FileSaver fileSaver;

    // faz o biding do validator para o controller
    @InitBinder
    public void initBinder(WebDataBinder wdb) {
        wdb.addValidators(new ProdutoValidation());
    }

    /*
     * recebe um produto como parametro, se caso for a primeira chamada de form
     * vai ter null para as Strings e 0 para as paginas sem grandes mudancas
     * e caso seja acesso via redirect da validation nao perde os dados ja escritos
     * corretamente
     */
    @RequestMapping("form")
    public ModelAndView form(Produto produto) {
        /*
         * passo no construtor de model and view (objeto que passa objetos de modelo
         * para a view) a string a ser retornada, uso o addObject para apelidar a lista
         * de valores do objeto que esta sendo passada e os respectivos valores
         */
        ModelAndView modelAndView = new ModelAndView("/produtos/form");
        // o Spring faz o biding da variavel com o name do form automaticamente
        modelAndView.addObject("tipos", TipoPreco.values());
        return modelAndView;
    }

    @RequestMapping(method = RequestMethod.GET) // vai para '/produtos' atraves de get
    public ModelAndView listaProdutos() {
        List<Produto> produtos = dao.listaProdutos();
        ModelAndView modelAndView = new ModelAndView("/produtos/lista");
        modelAndView.addObject("listaProdutos", produtos);
        return modelAndView;
    }

    @RequestMapping(method = RequestMethod.POST) // vai para '/produtos' atraves de post
    /*
     * valid basicamente avisa que o produto eh o objeto a ser validado,
     * BindingResult precisa ficar logo depois do produto como ordem de parametro e
     * devolve os resultados da validation se deu algo errado ele nao persiste o
     * produto
     */
    public ModelAndView confirmaProduto(MultipartFile file , @Valid Produto produto, BindingResult result,
            RedirectAttributes redirectAttributes) {

        if (result.hasErrors()) {
            return form(produto);
        }

        String sumarioProduto = fileSaver.fileWriter("arquivos-sumario", file);
        produto.setSumarioPath(sumarioProduto);


        dao.salvaProduto(produto);
        System.out.println("Produto salvo com sucesso");
        System.out.println(produto);

        // flash atributes sempre deixam de existir após o redirect
        redirectAttributes.addFlashAttribute("sucesso", "Produto salvo com sucesso");
        return new ModelAndView("redirect:produtos"); // always redirect after post
    }

}

poderia postar o código fonte da JSP? Só a parte do upload

solução!

Então Igor, o problema era um erro bem tonto na JSP mesmo, mas agora apesar de estar recebendo a mensagem de sucesso e o do path estar sendo salvo, o arquivo em si não vai para a pasta indicada...