Estou tentando aprender a desenvolver aplicações Java para WEB (JavaEE). Para isso estava utilizando uma apostila confeccionada pela equipe da Caelum. Tudo ia bem até o momento em que resolvi fazer o exercício do item 9.8 da mesma o qual pedia para desenvolver uma lógica para alterar e inserir contato. Comecei, como sugeria a apostila, inserindo um link para alterar contato na página que lista os contatos conforme mostra o código abaixo:
Arquivo: listaContatos.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<jsp:useBean id="contato" class="agenda.Contato" scope="session"/>
<jsp:setProperty name="contato" property="*"/>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>teste</title>
<title>Listar contatos</title>
</head>
<body>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<c:import url="cabecalho.jsp" />
<table border="1px">
<thead>
<tr><th>NOME</th><th>EMAIL</th><th>ENDEREÇO</th><th>DATA NASCIMENTO</th></tr>
</thead>
<c:forEach var="contato" items="${contatos}" varStatus="id">
<tr bgcolor="#${id.count % 2 == 0 ? 'aaee88' : 'ffffff' }" >
<td>${contato.nome}</td>
<td>
<c:choose>
<c:when test="${not empty contato.email}">
<a href="mailto:${contato.email}">${contato.email}</a>
</c:when>
<c:otherwise>
Não informado
</c:otherwise>
</c:choose>
</td>
<td>${contato.endereco}</td>
<td>
<fmt:formatDate value="${contato.dataNascimento.time}"
pattern="dd/MM/yyyy" />
</td>
<td>
<!-- Aqui Link para a lógica para alterar contato -->
<a href="mvc?logica=AlteraContatoLogic&id=${contato.id}">Alterar</a>
</td>
<td>
<a href="mvc?logica=RemoveContatoLogic&id=${contato.id}">Remover</a>
</td>
</tr>
</c:forEach>
</table>
<c:import url="rodape.jsp" />
</body>
</html>`
A seguir, a lógica para alterar contato. Arquivo: AlteraContatoLogic.java (para onde o link da página de listar contatos aponta).
package logica;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import agenda.Contato;
import agenda.ContatoDAO;
public class AlteraContatoLogic implements Logica {
@Override
public String executa(HttpServletRequest req, HttpServletResponse res) throws Exception {
long id = Long.parseLong(req.getParameter("id"));
ContatoDAO dao = new ContatoDAO();
Contato contato = new Contato();
contato = dao.getContato(id);
req.setAttribute("contato", contato);
return "altera_contato.jsp";
}
}
A seguir Logica.java (a interface)
package logica;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public interface Logica {
String executa(HttpServletRequest req,
HttpServletResponse res) throws Exception;
}
Página com o formulário para alterar contato: altera_contato.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<jsp:useBean id="contato" class="agenda.Contato" scope="session"/>
<jsp:setProperty name="contato" property="*" />
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script src="/js/jquery.maskedinput.js"></script>
</head>
<body>
<c:import url="cabecalho.jsp" />
<hr>
<h3>Alterar Contato</h3>
<form action="mvc">
<input type="hidden" name="logica" value="AlteraContatoLogic2">
<input type="hidden" name=id value="${contato.id}">
<table>
<tr>
<td>Nome:</td><td><input type="text" name="nome" value="${contato.nome }"/></td>
</tr>
<tr>
<td>E-mail:</td><td><input type="text" name="email" value="${contato.email }"/></td>
</tr>
<tr>
<td>Endereço:</td><td><input type="text" name="endereco" value="${contato.endereco}"/></td>
</tr>
<tr>
<td>Data Nascimento:</td>
<td>
<input type="text" name="dataNascimento" value='<fmt:formatDate value="${contato.dataNascimento.time }"/>'>
</td>
</tr>
</table>
<hr>
<input type="submit" value="Gravar" />
</form>
<c:import url="rodape.jsp" />
</body>
</html>
Logica para alterar contato no banco de dados: AlteraContatoLogic2.java
package logica;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import agenda.Contato;
import agenda.ContatoDAO;
public class AlteraContatoLogic2 implements Logica {
@Override
public String executa(HttpServletRequest req, HttpServletResponse res) throws Exception {
try {
long id = Long.parseLong(req.getParameter("id"));
String nome = req.getParameter("nome");
String email = req.getParameter("email");
String endereco = req.getParameter("endereco");
String strData = req.getParameter("dataNascimento");
Date date = new SimpleDateFormat("dd/MM/yyyy").parse(strData);
Calendar dataNascimento = Calendar.getInstance();
dataNascimento.setTime(date);
Contato contato = new Contato();
contato.setId(id);
contato.setNome(nome);
contato.setEmail(email);
contato.setEndereco(endereco);
contato.setDataNascimento(dataNascimento);
ContatoDAO dao = new ContatoDAO();
dao.altera(contato);
System.out.println("Alterar contato... ");
//Creio ser este o valor de retorno a ser passado para o controler.
return "mvc?logica=ListaContatosLogic";
} catch (ParseException e) {
e.printStackTrace();
return "erro.html"; //para a execução do método
}
}
}
Acho que não é necessário postar “ConectionFactory.java”, “Contato.java” e “ContatoDAO.java”. Basta dizer que estão funcionando.
Por fim, o problema que gostaria de submeter a vossa análise: quando “clico” em Gravar uma exception é gerada no controler (creio eu). Vide mensagem de erro abaixo trancrita:
type Exception reportmessage A lógica de negócios causou uma exceção para AlteraContatoLogic2description The server encountered an internal error that prevented it from fulfilling this request.exceptionjavax.servlet.ServletException: A lógica de negócios causou uma exceção para AlteraContatoLogic2
mvc.ControllerServlet.service(ControllerServlet.java:37)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
root causejavax.servlet.ServletException: A lógica de negócios causou uma exceção para ListaContatosLogic
mvc.ControllerServlet.service(ControllerServlet.java:37)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
mvc.ControllerServlet.service(ControllerServlet.java:35)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
root causeorg.apache.jasper.JasperException: org.apache.jasper.JasperException: org.apache.jasper.JasperException: org.apache.jasper.JasperException: Unable to convert string "24/02/2011" to class "java.util.Calendar" for attribute "dataNascimento": Property Editor not registered with the PropertyEditorManager
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:555)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:461)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:396)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:340)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
mvc.ControllerServlet.service(ControllerServlet.java:35)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
mvc.ControllerServlet.service(ControllerServlet.java:35)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
root causeorg.apache.jasper.JasperException: org.apache.jasper.JasperException: org.apache.jasper.JasperException: Unable to convert string "24/02/2011" to class "java.util.Calendar" for attribute "dataNascimento": Property Editor not registered with the PropertyEditorManager
org.apache.jasper.runtime.JspRuntimeLibrary.internalIntrospecthelper(JspRuntimeLibrary.java:362)
org.apache.jasper.runtime.JspRuntimeLibrary.introspecthelper(JspRuntimeLibrary.java:308)
org.apache.jasper.runtime.JspRuntimeLibrary.introspect(JspRuntimeLibrary.java:286)
org.apache.jsp.listaContatos_jsp._jspService(listaContatos_jsp.java:146)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:438)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:396)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:340)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
mvc.ControllerServlet.service(ControllerServlet.java:35)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
mvc.ControllerServlet.service(ControllerServlet.java:35)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
root causeorg.apache.jasper.JasperException: org.apache.jasper.JasperException: Unable to convert string "24/02/2011" to class "java.util.Calendar" for attribute "dataNascimento": Property Editor not registered with the PropertyEditorManager
org.apache.jasper.runtime.JspRuntimeLibrary.convert(JspRuntimeLibrary.java:273)
org.apache.jasper.runtime.JspRuntimeLibrary.internalIntrospecthelper(JspRuntimeLibrary.java:354)
org.apache.jasper.runtime.JspRuntimeLibrary.introspecthelper(JspRuntimeLibrary.java:308)
org.apache.jasper.runtime.JspRuntimeLibrary.introspect(JspRuntimeLibrary.java:286)
org.apache.jsp.listaContatos_jsp._jspService(listaContatos_jsp.java:146)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:438)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:396)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:340)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
mvc.ControllerServlet.service(ControllerServlet.java:35)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
mvc.ControllerServlet.service(ControllerServlet.java:35)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
root causeorg.apache.jasper.JasperException: Unable to convert string "24/02/2011" to class "java.util.Calendar" for attribute "dataNascimento": Property Editor not registered with the PropertyEditorManager
org.apache.jasper.runtime.JspRuntimeLibrary.getValueFromPropertyEditorManager(JspRuntimeLibrary.java:854)
org.apache.jasper.runtime.JspRuntimeLibrary.convert(JspRuntimeLibrary.java:269)
org.apache.jasper.runtime.JspRuntimeLibrary.internalIntrospecthelper(JspRuntimeLibrary.java:354)
org.apache.jasper.runtime.JspRuntimeLibrary.introspecthelper(JspRuntimeLibrary.java:308)
org.apache.jasper.runtime.JspRuntimeLibrary.introspect(JspRuntimeLibrary.java:286)
org.apache.jsp.listaContatos_jsp._jspService(listaContatos_jsp.java:146)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:438)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:396)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:340)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
mvc.ControllerServlet.service(ControllerServlet.java:35)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
mvc.ControllerServlet.service(ControllerServlet.java:35)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
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/8.0.36 logs.A
Organização das pastas (IDE: Eclipse)
.
├── ./build
│ └── ./build/classes
│ ├── ./build/classes/agenda
│ │ ├── ./build/classes/agenda/ConnectionFactory.class
│ │ ├── ./build/classes/agenda/Contato.class
│ │ └── ./build/classes/agenda/ContatoDAO.class
│ ├── ./build/classes/logica
│ │ ├── ./build/classes/logica/AlteraContatoLogic2.class
│ │ ├── ./build/classes/logica/AlteraContatoLogic3.class
│ │ ├── ./build/classes/logica/AlteraContatoLogic.class
│ │ ├── ./build/classes/logica/ListaContatosLogic.class
│ │ ├── ./build/classes/logica/Logica.class
│ │ └── ./build/classes/logica/RemoveContatoLogic.class
│ └── ./build/classes/mvc
│ └── ./build/classes/mvc/ControllerServlet.class
├── ./src
│ ├── ./src/agenda
│ │ ├── ./src/agenda/ConnectionFactory.java
│ │ ├── ./src/agenda/ContatoDAO.java
│ │ └── ./src/agenda/Contato.java
│ ├── ./src/logica
│ │ ├── ./src/logica/AlteraContatoLogic2.java
│ │ ├── ./src/logica/AlteraContatoLogic3.java
│ │ ├── ./src/logica/AlteraContatoLogic.java
│ │ ├── ./src/logica/ListaContatosLogic.java
│ │ ├── ./src/logica/Logica.java
│ │ └── ./src/logica/RemoveContatoLogic.java
│ └── ./src/mvc
│ └── ./src/mvc/ControllerServlet.java
└── ./WebContent
├── ./WebContent/AdicionaContato.jsp
├── ./WebContent/altera_contato.jsp
├── ./WebContent/cabecalho.jsp
├── ./WebContent/css
│ └── ./WebContent/css/jquery-ui.css
├── ./WebContent/documentos
│ ├── ./WebContent/documentos/aniversariantes2.csv
│ ├── ./WebContent/documentos/aniversariantes.csv
│ └── ./WebContent/documentos/contatos.csv
├── ./WebContent/erro.html
├── ./WebContent/imagens
│ └── ./WebContent/imagens/caelum.png
├── ./WebContent/index.html
├── ./WebContent/js
│ ├── ./WebContent/js/jquery-3.0.0.min.js
│ ├── ./WebContent/js/jquery.maskedinput.js
│ ├── ./WebContent/js/jquery.ui.datepicker-pt-BR.js
│ ├── ./WebContent/js/jquery-ui.js
│ └── ./WebContent/js/jquery-ui.min.js
├── ./WebContent/listaContatos.jsp
├── ./WebContent/META-INF
│ └── ./WebContent/META-INF/MANIFEST.MF
├── ./WebContent/rodape.jsp
└── ./WebContent/WEB-INF
├── ./WebContent/WEB-INF/lib
│ ├── ./WebContent/WEB-INF/lib/javax.servlet.jsp.jstl-api-1.2.1.jar
│ ├── ./WebContent/WEB-INF/lib/jstl-1.2.jar
│ ├── ./WebContent/WEB-INF/lib/postgresql-9.3-1102.jdbc41.jar
│ └── ./WebContent/WEB-INF/lib/standard-1.1.2.jar
└── ./WebContent/WEB-INF/web.xml
17 directories, 43 files
Algumas informações adicionais:
- Há uma linha no stack informando que não consegue converter converter String para Java.util.calendar. Não entendo como isso ocorre.
- A atualização no banco de dados, apesar da mensagem de erro, é executada. Verifiquei isso quando recarreguei a página listarContatos.jsp. Os campos que editei reapareceram alterados como esperado.
- Estou usando Apache Tomcat/8.0.36.
- Pela mensagem e após tentar depurar a aplicação (modo debug) verifiquei que a exceção ocorre no controler quando recebe o parámetro logica=ListarContatosLogic.
- Se houver necessidade, posso enviar todo o código compactado e pronto para ser importado no Eclipse.
Finalizando. Já estou há dias tentando encontrar a causa desse erro, mas sem sucesso. Talvez alguém com mais conhecimento possa enxergar a causa do mesmo.
Desde já agradeço.