Dúvida - Apostila Caelum FJ21 - 9.8 - Exercícios: Lógica para alterar contatos[Resolvido]

14 respostas
D

Amigos boa tarde! Sou iniciante em java, estou estudando a apostila fj21 da caelum. No exercício 9.8, quando acesso o form altera-contato.jsp para alterar o contato no banco, e clico em enviar a seguinte exceção é lançada no console:

SEVERE: Servlet.service() for servlet [controlador] in context with path [/fj21-agenda] threw exception [A lógica de negócios causou uma exceção] with root cause
java.lang.ClassNotFoundException: br.com.caelum.mvc.logica.AlteraContatoLogic

at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1711)

at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1556)

at java.lang.Class.forName0(Native Method)

at java.lang.Class.forName(Unknown Source)

at br.com.caelum.mvc.servlet.ControllerServlet.service(ControllerServlet.java:22)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)

at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)

at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)

at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)

at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)

at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)

at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)

at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)

at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)

at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1001)

at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)

at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)

at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)

at java.lang.Thread.run(Unknown Source)

Segue a interface e as servlets, conforme o exemplo da apostila:

Logica:

package br.com.caelum.mvc.logica;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public interface Logica {
	
		void executa(HttpServletRequest req, HttpServletResponse res) throws Exception;

	}

ControllerServlet:

package br.com.caelum.mvc.servlet;



import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import br.com.caelum.mvc.logica.Logica;


public class ControllerServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;
	
		@Override
		protected void service(HttpServletRequest request, HttpServletResponse response)
				throws ServletException, IOException {
					super.service(request, response);
			
			String parametro = request.getParameter("logica");
			String nomeDaClasse = "br.com.caelum.mvc.logica." + parametro;
			
			try {
				Class classe = Class.forName(nomeDaClasse);
				
				Logica logica = (Logica) classe.newInstance();
				logica.executa(request, response);
				
			} catch (Exception e) {
				throw new ServletException("A lógica de negócios causou uma exceção", e);
				
		}
	}
}

AlteraContatoLogic:

package br.com.caelum.mvc.logica;


import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;



import br.com.caelum.jdbc.dao.ContatoDAO;
import br.com.caelum.jdbc.modelo.Contato;

public class AlteraContatoLogic implements Logica {

	@Override
	public void executa(HttpServletRequest request, HttpServletResponse response)
			throws Exception {

		Contato contato = new Contato();
		long id = Long.parseLong(request.getParameter("id"));
		contato.setId(id);
		contato.setNome(request.getParameter("nome"));
		contato.setEndereco(request.getParameter("endereco"));
		contato.setEmail(request.getParameter("email"));
		
		//Converte a data de String para Calendar
		String dataEmTexto = request.getParameter("dataNascimento");
		Date date = new SimpleDateFormat("dd//MM/yyyy").parse(dataEmTexto);
		Calendar dataNascimento = Calendar.getInstance();
		dataNascimento.setTime(date);
		
		contato.setDataNascimento(dataNascimento);
		
		ContatoDAO dao = new ContatoDAO();
		dao.altera(contato);
		
		RequestDispatcher rd = request.getRequestDispatcher("/lista-contatos-elegante.jsp");
		rd.forward(request, response);
		System.out.println("Alterando contato ..." + contato.getNome());
		
		
	}
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws IOException, ServletException {

	}
}

altera-contato.jsp:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib tagdir="/WEB-INF/tags" prefix="caelum" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<c:import url="cabecalho.jsp" />

	Formulário para a alteração de contatos:<br/>
	
	<form action="mvc" method="POST">
		Id: <input type="text" name="id"/><br/>
		Nome: <input type="text" name="nome"/><br/>
		E-mail: <input type="text" name="email"/><br/>
		Endereço: <input type="text" name="endereco"/><br/>
		Data de Nascimento: <caelum:campoData id="dataNascimento" />
				<input type="hidden" name="logica" value="AlteraContatoLogic"/>
				<input type="submit" value="Enviar"/>
	</form>
	
<c:import url="rodape.jsp" />

Mapeamento no xml:

<servlet>
  	<servlet-name>controlador</servlet-name>
  	<servlet-class>br.com.caelum.mvc.servlet.ControllerServlet</servlet-class>
  </servlet>
  
  <servlet-mapping>
  	<servlet-name>controlador</servlet-name>
  	<url-pattern>/mvc</url-pattern>
  </servlet-mapping>

Podem me ajudar a entender porque mesmo com minha servlet mapeada, esta exceção está sendo lançada? Daí eu poderei corrigir o exercício.
Muito Obrigado!

[]´s

14 Respostas

sergiolopes

A exceção tá dentro do ControllerServlet quando voce carrega a classe de logica (linha do Class.forName). Ta dizendo que nao ta encontrando a classe:

java.lang.ClassNotFoundException: br.com.caelum.mvc.logica.AlteraContatoLogic

Dá uma conferida se o pacote e o nome da classe estão certinhos mesmo…

D

Fala Sergio! Tudo bem? Obrigado por responder a minha dúvida.

Cara dei uma conferida no nome dos pacotes e das classes. Tá tudo certinho, todas as classes estão nos pacotes corretos como na apostila, inclusive também os nomes das classes.

Existe alguma possibilidade de que algum outro tipo de erro, possa estar causando essa exceção? Não sei se isso está relacionado, mas consigo acessar minha servlet PrimeiraLogica tranquilamente através da url http://localhost:8080/fj21-agenda/mvc?logica=PrimeiraLogica

Obrigado, um abraço!

D

Sérgio tranquilo? Fiz um teste com System.out.println(), pegando as variáveis “parametro” e “nomeDaClasse”.
Quando executo a página, deveria imprimir no console o valor concatenado das variáveis, mas isso não está acontecendo. Ocorre o mesmo erro que postei acima, sem a informação do System.out.println(). Acredito que este seja o motivo do erro na linha do Class.forName, pois se System.out.println() não conseguiu pegar os valores, também não está chegando na linha Class.forName. Pode me dar uma ajudar por favor?

Obrigado.
[]´s

sergiolopes

Ta bem esquisito esse erro. Seu codigo esta aparentemente correto. Mas ele nao consegue achar a classe de jeito nenhum.

Eu tentaria dar um clean no projeto e ver se ele recompilando tudo as coisas funcionam.

Alias, nao tem nenhum erro de compilacao no projeto nao ne? Nem em outras classes nao relacionadas?

D

Beleza Sérgio? Os únicos erros que o eclipse apontou foram dois arquivos js-ui que havia em meu projeto, mas acho que talvez seja por uma questão de validação do eclipse mesmo. Mesmo assim retirei os arquivos para testar novamente.

Fiz o seguinte dei o clean, e em seguida um build all. Todos os arquivos que são application java foram recompilados. Exceto meus arquivos web, as servlets do projeto fj21-agenda que é um projeto dynamic web project. Como devo fazer o build no projeto fj21-agenda? Já pesquisei bastante e não encontrei nada a respeito. O projeto fj21-agenda foi o único onde não foram gerados os “.class”. Só preciso fazer o build nesse projeto para poder testá-lo, vou precisar da sua ajuda mais uma vez cara rss.

Novamente, obrigado!
[]´s

sergiolopes

Ele não tá compilando as classes do projeto então? Isso explica porque tá dando ClassNotFoundException.

Precisa ver na view Problems se tem algum erro relacionado a esse projeto. Quando ele para de compilar geralmente ta relacionado a algum problema no Build Path.

D

Então na verdade estava dando ClassNotFoundException, mesmo contendo os .class no tomcat e workspace, isso foi antes de eu ter feito o clean e o build. Depois do processo do clean, não consegui mais fazer o build, isso aconteceu devido ao erro que existia no projeto como disse você.

Mas enfim como você sugeriu dei check na view Problems e havia mesmo um erro. O erro apontava para o driver do mysql, que apesar de eu ter copiado o driver para projeto, ainda não tinha add no build path. Adicionei no build path, executei o build no meu projeto e todos os arquivos foram compilados. Muito obrigado, vou ficar mais atento a view Problems rss.

O que acontece agora é quando tentei atualizar o banco que surgiu um "com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘where id = 7’ at line 1

Meu metodo altera no ContatoDAO está correto. Como pode ver ocorre na hora de alterar o id, que é um campo no banco auto increment é possível aterar esse tipo de campo? Porque este erro ocorre?

Sérgio muito obrigado pela ajuda, se precisar eu crio outro tópico porque este já não tem nada a ver com minha dúvida inicial.

Vlw!
[]´s

sergiolopes

Que bom que resolveu o problema!

Essa exception é de erro no código SQL… dá uma checada se ficou certinho

raffamz

Amigos,

achie estranho esta dupla barra no seu código, é isso mesmo?

Date date = new SimpleDateFormat("dd//MM/yyyy").parse(dataEmTexto);

Abraços,

D

Fala raffaamz tranquilo?

Estava errado mesmo, já corrigi vlw pela observação!
[]´s

D

Sérgio dá uma olhada no meu metodo altera da classe ContatoDAO:

//...metodos lista e adiciona


public void altera(Contato contato) {
	
	String sql = "update contatos set nome = ?, email = ?, endereco = ?, dataNascimento = ?, where id = ?";
	
		try { 
			PreparedStatement stmt = connection.prepareStatement(sql);
			stmt.setString(1, contato.getNome());
			stmt.setString(2, contato.getEmail());
			stmt.setString(3, contato.getEndereco());
			stmt.setDate(4, new Date(contato.getDataNascimento().getTimeInMillis()));
			stmt.setLong(5, contato.getId());
			stmt.execute();
			stmt.close();
			
	  } catch (SQLException e) {
			throw new RuntimeException(e);
			
		}
	}

Tá tudo certinho incluindo a ordem dos binds.

Vlw
[]´s

sergiolopes

Tem uma virgula a mais antes do where. O correto é:

update contatos set nome = ?, email = ?, endereco = ?, dataNascimento = ? where id = ?

D

Outro puta vacilo! rss

Alterei o código, gerei o .jar, agora funcionou tudo! Sergião muito obrigado mesmo! Agora vou poder continuar a estudar rss
De agora em diante prestarei mais atenção a estes detalhes, rss.

Muito obrigado!
[]´s

alexandre.marques

Cara, esse erro aconteceu comigo vc configurou tudo inclusive o filtro?

para localizar a classe do class.forName() coloca assim Class<?> classe = Class.forName(nomeDaClasse);

testa ai para ver se é o mesmo… :slight_smile:

Criado 11 de setembro de 2012
Ultima resposta 13 de set. de 2012
Respostas 14
Participantes 4