listaTarefas Caelum-Java-Web

5 respostas
F

Pessoal, boa noite.
Pesquisei no fórum acerca do problema que estou enfrentando, porém não obtive sucesso quanto a resolução do mesmo.

De acordo com a apostila da Caelum java-web-fj21, estou tentando fazer o exercício 11.14.

Ao tentar acessar a listagem das tarefas cadastradas, a mesma apresenta erro.

De acordo com o Log, estou com o seguinte erro:
127.0.0.1 - - [06/Jun/2014:23:43:54 -0300] “GET /fj21-tarefas/listaTarefas HTTP/1.1” 500 3680

Segue também a página de erro apresentada:

HTTP Status 500 - Request processing failed; nested exception is java.lang.NullPointerException

type Exception report

message Request processing failed; nested exception is java.lang.NullPointerException

description The server encountered an internal error that prevented it from fulfilling this request.

exception

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException
	org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:965)
	org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:844)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
	org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:829)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
root cause

java.lang.NullPointerException
	java.util.Calendar.setTime(Calendar.java:1076)
	br.com.caelum.tarefas.dao.JdbcTarefaDao.lista(JdbcTarefaDao.java:56)
	br.com.caelum.tarefas.controller.TarefasController.lista(TarefasController.java:38)
	sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	java.lang.reflect.Method.invoke(Method.java:597)
	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:745)
	org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:685)
	org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
	org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:919)
	org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:851)
	org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:953)
	org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:844)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
	org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:829)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
note The full stack trace of the root cause is available in the Apache Tomcat/7.0.53 logs.

Apache Tomcat/7.0.53

Seguem também meus arquivos para implementação desta funcionalidade.

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
		 xmlns="http://java.sun.com/xml/ns/javaee" 
		 xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
		 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
		 id="WebApp_ID" version="2.5">
  <display-name>fj21-tarefas</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  
  <servlet>
  	<servlet-name>springmvc</servlet-name>
  	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  	<init-param>
  		<param-name>contextConfigLocation</param-name>
  		<param-value>/WEB-INF/spring-context.xml</param-value>
  	</init-param>
  	<load-on-startup>1</load-on-startup>
  </servlet>
  
  <servlet-mapping>
  	<servlet-name>springmvc</servlet-name>
  	<url-pattern>/</url-pattern>
  </servlet-mapping>  
  
</web-app>

TarefasController.java

package br.com.caelum.tarefas.controller;

import java.util.List;

import javax.validation.Valid;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;

import br.com.caelum.tarefas.dao.JdbcTarefaDao;
import br.com.caelum.tarefas.modelo.Tarefa;

@Controller
public class TarefasController 
{
	@RequestMapping("novaTarefa")
	public String form(){
		return "tarefa/formulario";
	}
	
	@RequestMapping("adicionaTarefa")
	public String adiciona(@Valid Tarefa tarefa, BindingResult result)
	{
		
		if(result.hasFieldErrors("descricao")){
			return "tarefa/formulario";
		}
		
		JdbcTarefaDao dao = new JdbcTarefaDao();
		dao.adiciona(tarefa);			
		return "tarefa/adicionada";
	}
	
	@RequestMapping("listaTarefas")
	public String lista(Model model)
	{
		JdbcTarefaDao dao = new JdbcTarefaDao();
		model.addAttribute("tarefas", dao.lista());
		return "tarefa/lista";
	}
	
}

JdbcTarefaDao.java

package br.com.caelum.tarefas.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import br.com.caelum.tarefas.jdbc.ConnectionFactory;
import br.com.caelum.tarefas.modelo.Tarefa;

public class JdbcTarefaDao {
	private Connection connection; 

	public JdbcTarefaDao()
	{
		this.connection = new ConnectionFactory().getConnection();
	}

	public void adiciona(Tarefa tarefa)
	{
		String sql = "Insert into tarefas (descricao, finalizado) values(?, ?)";
	
		try
		{
			PreparedStatement stmt =  connection.prepareStatement(sql);
		
			stmt.setString(1, tarefa.getDescricao());
			stmt.setBoolean(2, tarefa.isFinalizado());
		//	stmt.setDate(3, new Date(tarefa.getDataFinalizacao().getTimeInMillis()) );

			stmt.execute();
			stmt.close();
		}catch(SQLException e)
		{
			throw new RuntimeException(e);
		}
	}
	
	public List<Tarefa> lista()
	{
		try{
			List<Tarefa> tarefas = new ArrayList<Tarefa>();
			PreparedStatement stmt = this.connection.prepareStatement("select * from tarefas");
			ResultSet rs = stmt.executeQuery();
			
			while (rs.next())
			{
				Tarefa tarefa = new Tarefa();
				tarefa.setId(rs.getLong("id"));
				tarefa.setDescricao(rs.getString("descricao"));
				tarefa.setFinalizado(rs.getBoolean("finalizado"));
				
				Calendar data = Calendar.getInstance();
				data.setTime(rs.getDate("dataFinalizacao"));
				tarefa.setDataFinalizacao(data);
				
				tarefas.add(tarefa);
			}
			rs.close();
			stmt.close();
			
			return tarefas;
		}
		catch (SQLException e)
		{
			throw new RuntimeException(e);
		}
	}

}

lista.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
	<a href="novaTarefa">Criar nova tarefa</a>
	<br /><br />
	<table>
		<tr>
			<th>Id</th>
			<th>Descrição</th>
			<th>Finalizado?</th>
			<th>Data de finalização</th>
		</tr>
		<c:forEach items="${tarefas}" var="tarefa">
			<tr>
				<td>${tarefa.id}</td>
				<td>${tarefa.descricao}</td>
				<c:if test="${tarefa.finalizado eq false}">
					<td>Não finalizado</td>
				</c:if>
				<c:if test="${tarefa.finalizado eq true}">
					<td>Finalizado</td>
				</c:if>	
				<td>
					<fmt:formatDate
						value="${tarefa.dataFinalizacao.time}"
						pattern="dd/MM/yyyy"/>
				</td>
			</tr>	
		</c:forEach>	
	</table>
</body>
</html>

spring-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"    
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    
	   xmlns:context="http://www.springframework.org/schema/context"    
	   xmlns:mvc="http://www.springframework.org/schema/mvc"    
	   xsi:schemaLocation="http://www.springframework.org/schema/mvc    
	    				   http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd    
	    				   http://www.springframework.org/schema/beans    
	    				   http://www.springframework.org/schema/beans/spring-beans-3.1.xsd    
	    				   http://www.springframework.org/schema/context    
	    				   http://www.springframework.org/schema/context/spring-context-3.1.xsd">    
	  
		<context:component-scan base-package="br.com.caelum.tarefas.controller" />   
		<mvc:annotation-driven /> 
		<mvc:resources mapping="/resources/**" location="/resources/" />  
		  
		<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">   
			<property name="prefix" value="/WEB-INF/views/"/>   
			<property name="suffix" value=".jsp"/>   
		</bean> 
		
		<bean id="messageSource" class= "org.springframework.context.support.ReloadableResourceBundleMessageSource">
			<property name="basename" value="/WEB-INF/mensagens"></property>
		</bean>  
  
</beans>

Tarefa.java

package br.com.caelum.tarefas.modelo;

import java.util.Calendar;

import javax.validation.constraints.Size;

import com.sun.istack.internal.NotNull;

public class Tarefa 
{
	private Long id;
	
	@NotNull//(message="{tarefa.descricao.vazia}") 
	@Size(min=5, message="{tarefa.descricao.pequena}")
	private String descricao;
	private boolean finalizado;
	private Calendar dataFinalizacao;
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public String getDescricao() {
		return descricao;
	}
	public void setDescricao(String descricao) {
		this.descricao = descricao;
	}
	public boolean isFinalizado() {
		return finalizado;
	}
	public void setFinalizado(boolean finalizado) {
		this.finalizado = finalizado;
	}
	public Calendar getDataFinalizacao() {
		return dataFinalizacao;
	}
	public void setDataFinalizacao(Calendar dataFinalizacao) {
		this.dataFinalizacao = dataFinalizacao;
	}
	
}

Agradeço a ajuda de todos.
Abraço,
Fernando Nascimento

5 Respostas

F

Alguém sabe o que pode ser isso?

F

Alguém?

E

Veja se no banco a coluna dataFinalização está preenchida em todas as linhas.

F

Erick,

Este campo não está preenchido em nenhuma linha.
Ele só será populado a partir do momento que as tarefas forem finalizadas.
Não há como listar as tarefas com estes campos null?

E

Não, pois na sua consulta, como na coluna está null, você está passando null para o objeto:

data.setTime(rs.getDate("dataFinalizacao")); // 1- vem null do banco tarefa.setDataFinalizacao(data); // 2- passa o null para a tarefa

E depois você tenta formatar um campo nulo:

Só se você fizer o tratamento do valor quando estiver nulo no banco.

Criado 6 de junho de 2014
Ultima resposta 10 de jun. de 2014
Respostas 5
Participantes 2