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)
10
respostas

Erro ao salvar um novo livro

Após criar o FileServlet para recuperar a capa do livro, que está ocorrendo com êxito. Fui tentar inserir um novo livro e está dando a seguinte exceção.

10 respostas
18:18:08,416 ERROR [io.undertow.request] (default task-6) UT005023: Exception handling request to /casadocodigo/livros/formLivro.xhtml: javax.servlet.ServletException: java.lang.RuntimeException
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:671)
    at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)
    at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
    at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
    at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
    at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
    at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
    at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
    at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
    at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
    at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292)
    at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81)
    at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138)
    at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135)
    at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)

Segue meu método Salvar em AdminLivrosBean

    @Transactional
    public String salvar() throws IOException {

        FileSaver fileServer = new FileSaver();
        livro.setCapaPath(fileServer.write(capaLivro, "livros"));

        livroDao.salvar(livro);


        context.getExternalContext().getFlash().setKeepMessages(true);
        context.addMessage(null, new FacesMessage("Livro cadastrado com sucesso."));

        return "/livros/listaLivro?faces-redirect=true";        
    }

Classe FileSaver

public class FileSaver {

    public static final String SERVERPATH = "/Daniel/casadocodigo";

    public String write(Part part, String path) {
        String relativePath = path + "/" + part.getSubmittedFileName();
        try {
            part.write( SERVERPATH + "/" + relativePath);

            return relativePath;
        } catch(IOException e){
            throw new RuntimeException();
        }
    }

    public static void transfer(Path source, OutputStream outputStream) {

        try {
            FileInputStream input = new FileInputStream(source.toFile());
            try(ReadableByteChannel inputChannel = Channels.newChannel(input);
                    WritableByteChannel outputChannel = Channels.newChannel(outputStream) ){

                ByteBuffer buffer = ByteBuffer.allocate(1024 * 10);

                while(inputChannel.read(buffer) != -1) {
                    buffer.flip();
                    outputChannel.write(buffer);
                    buffer.clear();
                }

            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }

    }

Servlet FileServlet

@WebServlet("/file/*")
public class FileServlet extends HttpServlet{

    private static final long serialVersionUID = -2996287734967186731L;

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

        String path = req.getRequestURI().split("/file")[1];
        Path source = Paths.get(FileSaver.SERVERPATH + "/" + path);
        FileNameMap fileNameMap = URLConnection.getFileNameMap();
        String contentType = fileNameMap.getContentTypeFor("file:"+source);

        res.reset();
        res.setContentType(contentType);
        res.setHeader("Content-Length", String.valueOf(Files.size(source)));
        res.setHeader("Content-Disposition", "filename=\""+source.getFileName().toString()+"\"");
        FileSaver.transfer(source, res.getOutputStream());

    }

}

Oi Daniel,

Como está seu pom.xml?

Olá bom dia !

Segue o pom.xml , conforme solicitado.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>br.com.casadocodigo</groupId>
  <artifactId>casadocodigo</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <packaging>war</packaging>
  <build>
    <finalName>casadocodigo</finalName>
  </build>
  <properties>
    <failOnMissingWebXml>false</failOnMissingWebXml>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.jboss.spec.javax.faces</groupId>
      <artifactId>jboss-jsf-api_2.1_spec</artifactId>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>javax.enterprise</groupId>
      <artifactId>cdi-api</artifactId>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>javax.annotation</groupId>
      <artifactId>jsr250-api</artifactId>
      <scope>provided</scope>
    </dependency>
  </dependencies>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.jboss.spec</groupId>
        <artifactId>jboss-javaee-6.0</artifactId>
        <version>3.0.3.Final</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
      <dependency>
        <groupId>javax.annotation</groupId>
        <artifactId>jsr250-api</artifactId>
        <version>1.0</version>
        <scope>provided</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
</project>

Poderia enviar o código do formLivro.xhtml junto com o restante do log de erro?

Abraço!

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:f="http://xmlns.jcp.org/jsf/core">

    <h:form enctype="multipart/form-data">
        <div>
            <h:outputLabel value="Título"/>
            <h:inputText value="#{adminLivrosBean.livro.titulo}" required="true"
                         id="titulo"/>
            <h:message for="titulo"/>
        </div>

        <div>
            <h:outputLabel value="Descrição"/>
            <h:inputTextarea value="#{adminLivrosBean.livro.descricao}" rows="4" columns="20" required="true" 
                             id="descricao"/>
            <h:message for="descricao"/>
        </div>

        <div>
            <h:outputLabel value="Páginas"/>
            <h:inputText value="#{adminLivrosBean.livro.numeroPaginas}" required="true"
                         id="numeroPaginas"/>
            <h:message for="numeroPaginas"/>
        </div>

        <div>
            <h:outputLabel value="Preço"/>
            <h:inputText value="#{adminLivrosBean.livro.preco}" required="true"
                         id="preco"/>
            <h:message for="preco"/>
        </div>

        <div>
            <h:outputLabel value="Autores" />
            <h:selectManyListbox value="#{adminLivrosBean.livro.autores}"
                        converter="autorConverter" id="autores">
                <f:selectItems value="#{adminLivrosBean.autores}" var="autor"
                            itemValue="#{autor}" itemLabel="#{autor.nome}" />
            </h:selectManyListbox>
            <h:message for="autores" />
        </div>

        <div>
            <h:outputLabel value="Data de Publicação"/>
            <h:inputText value="#{adminLivrosBean.livro.dataPublicacao}"
                id="dataPublicacao" />
            <h:message for="dataPublicacao"/>
        </div>

        <div>
            <h:outputLabel value="Capa do Livro"/>
            <h:inputFile value="#{adminLivrosBean.capaLivro}" id="capaLivro"/>
            <h:message for="capaLivro"/>
        </div>        

        <h:commandButton value="Salvar" action="#{adminLivrosBean.salvar}"/>
    </h:form>

</html>

11:58:02,316 ERROR [io.undertow.request] (default task-3) UT005023: Exception handling request to /casadocodigo/livros/formLivro.xhtml;jsessionid=s78zEYVM9WrNIF-2TvaqQ3aSyPN2sB0seYi9jqLy.ebixla-luiz: javax.servlet.ServletException: java.lang.RuntimeException at javax.faces.webapp.FacesServlet.service(FacesServlet.java:671) at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85) at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131) at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60) at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77) at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50) at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292) at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81) at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138) at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135) at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48) at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43) at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44) at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44) at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44) at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44) at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44) at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44) at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272) at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81) at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104) at io.undertow.server.Connectors.executeRootHandler(Connectors.java:202) at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:805) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748)

Caused by: javax.faces.el.EvaluationException: java.lang.RuntimeException
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:101)
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
    at javax.faces.component.UICommand.broadcast(UICommand.java:315)
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:658)
    ... 38 more
Caused by: java.lang.RuntimeException
    at br.com.casadocodigo.loja.infra.FileSaver.write(FileSaver.java:26)
    at br.com.casadocodigo.loja.beans.AdminLivrosBean.salvar(AdminLivrosBean.java:49)
    at br.com.casadocodigo.loja.beans.AdminLivrosBean$Proxy$_$$_WeldSubclass.salvar$$super(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.jboss.weld.interceptor.proxy.TerminalAroundInvokeInvocationContext.proceedInternal(TerminalAroundInvokeInvocationContext.java:49)
    at org.jboss.weld.interceptor.proxy.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:77)
    at com.arjuna.ats.jta.cdi.transactional.TransactionalInterceptorBase.invokeInOurTx(TransactionalInterceptorBase.java:117)
    at com.arjuna.ats.jta.cdi.transactional.TransactionalInterceptorRequired.doIntercept(TransactionalInterceptorRequired.java:53)
    at com.arjuna.ats.jta.cdi.transactional.TransactionalInterceptorBase.intercept(TransactionalInterceptorBase.java:76)
    at com.arjuna.ats.jta.cdi.transactional.TransactionalInterceptorRequired.intercept(TransactionalInterceptorRequired.java:47)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.jboss.weld.interceptor.reader.SimpleInterceptorInvocation$SimpleMethodInvocation.invoke(SimpleInterceptorInvocation.java:74)
    at org.jboss.weld.interceptor.proxy.InterceptorMethodHandler.executeAroundInvoke(InterceptorMethodHandler.java:84)
    at org.jboss.weld.interceptor.proxy.InterceptorMethodHandler.executeInterception(InterceptorMethodHandler.java:72)
    at org.jboss.weld.interceptor.proxy.InterceptorMethodHandler.invoke(InterceptorMethodHandler.java:56)
    at org.jboss.weld.bean.proxy.CombinedInterceptorAndDecoratorStackMethodHandler.invoke(CombinedInterceptorAndDecoratorStackMethodHandler.java:79)
    at org.jboss.weld.bean.proxy.CombinedInterceptorAndDecoratorStackMethodHandler.invoke(CombinedInterceptorAndDecoratorStackMethodHandler.java:68)
    at br.com.casadocodigo.loja.beans.AdminLivrosBean$Proxy$_$$_WeldSubclass.salvar(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.sun.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:181)
    at com.sun.el.parser.AstValue.invoke(AstValue.java:289)
    at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:304)
    at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40)
    at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
    at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40)
    at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
    ... 46 more

Peguei o pom.xml do projeto do curso no final do capítulo 5, que estava diferente do meu, baixei as dependências e nada.

solução!

Consegui resolver o meu problema. O console estava me exibindo a exceção errada. Daí peguei a estrutura do método write em FileSaver do projeto disponibilizado no final do cap. 5 e ao tentar salvar, me lançou uma exceção indicando que o arquivo já existia no diretório onde eu estava tentando salvar.

Método antigo, escrito por mim junto com o Cap. 5

    public String write(Part part, String path) {
        String relativePath = path + "/" + part.getSubmittedFileName();
        try {
            part.write( SERVERPATH + "/" + relativePath);

            return relativePath;
        } catch(IOException e){
            throw new RuntimeException();
        }
    }

Método do projeto disponibilizado no final do Cap. 5

    public String write(Part arquivo, String path) {

        String relativePath = path + "/" + arquivo.getSubmittedFileName();
        String fullPath = SERVERPATH + "/" + relativePath;
        try {
            arquivo.write(fullPath);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        return relativePath;        
    }

A diferença mais significativa é que o return do método está fora do try.