Este guia demonstra como configurar uma aplicação web Java utilizando Spring Framework, Hibernate ORM, Spring MVC, Velocity Template Engine e Maven. O foco está na integração dessas tecnologias e na definição de arquivos de configuração essenciais.
Estrutura do Projeto e Configurações Iniciais
A estrutura de diretórios segue o padrão Maven. Os arquivos de configuração devem ser posicionados corretamente, como o arquivo context.xml para a fonte de dados, colocado no diretório META-INF dentro de target/m2e-wtp/web-resources/.
Todas as requisições devem incluir a extensão .html no URL, por exemplo: http://localhost:8080/aplicacao/usuario/index.html.
Arquivos de Configuração
Configuração do Log4j2
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<configuration status="debug">
<appenders>
<Console name="Console" target="SYSTEM_OUT">
<ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY" />
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n" />
</Console>
<RollingFile name="ArquivoRotativo" fileName="logs/app.log"
filePattern="log/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
<PatternLayout pattern="%d{yyyy-MM-dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n" />
<SizeBasedTriggeringPolicy size="10MB" />
</RollingFile>
<File name="Erro" fileName="logs/error.log">
<ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="%d{yyyy.MM.dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/>
</File>
</appenders>
<loggers>
<root level="debug">
<appender-ref ref="ArquivoRotativo" />
<appender-ref ref="Console" />
<appender-ref ref="Erro" />
</root>
</loggers>
</configuration>
Configuração do ApplicationContext do Spring
O arquivo applicationContext.xml define beans para fonte de dados, sessão do Hibernate, gerenciamento de transações e integração com Velocity.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.2.xsd">
<!-- Escaneamento de componentes -->
<context:component-scan base-package="com.exemplo.principal" />
<!-- Fonte de dados via JNDI -->
<bean id="fonteDados" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:comp/env/jdbc/bancoDadosApp</value>
</property>
</bean>
<!-- Configuração da sessão do Hibernate -->
<bean id="fabricaSessao"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="fonteDados" />
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.hbm2ddl.auto=none
hibernate.show_sql=true
hibernate.format_sql=true
hibernate.cache.use_second_level_cache=false
hibernate.cache.use_query_cache=false
hibernate.jdbc.fetch_size=50
hibernate.jdbc.batch_size=50
hibernate.connection.autocommit=true
hibernate.connection.release_mode=auto
hibernate.current_session_context_class=
org.springframework.orm.hibernate4.SpringSessionContext
javax.persistence.validation.mode=none
</value>
</property>
<property name="packagesToScan" value="com.exemplo.modelo" />
</bean>
<!-- Template do Hibernate -->
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="fabricaSessao" />
</bean>
<!-- Gerenciador de transações -->
<bean id="gerenciadorTransacao"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="fabricaSessao" />
</bean>
<tx:advice id="conselhoTransacao" transaction-manager="gerenciadorTransacao">
<tx:attributes>
<tx:method name="salvar*" propagation="REQUIRED" />
<tx:method name="atualizar*" propagation="REQUIRED" />
<tx:method name="excluir*" propagation="REQUIRED" />
<tx:method name="*" propagation="NOT_SUPPORTED" read-only="true" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="operacaoServico"
expression="execution(* com.exemplo.servico..*.*(..))" />
<aop:advisor advice-ref="conselhoTransacao" pointcut-ref="operacaoServico" />
</aop:config>
<!-- Resolver para upload de arquivos -->
<bean id="resolvedorMultipart" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8"/>
<property name="maxUploadSize" value="10485760000"/>
<property name="maxInMemorySize" value="40960"/>
</bean>
<!-- Configuração do Velocity -->
<bean id="configuradorVelocity"
class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
<property name="resourceLoaderPath">
<value>templates</value>
</property>
<property name="velocityProperties">
<props>
<prop key="file.resource.loader.cache">true</prop>
<prop key="file.resource.loader.modificationCheckInterval">2</prop>
<prop key="input.encoding">UTF-8</prop>
<prop key="output.encoding">UTF-8</prop>
<prop key="contentType">text/html;charset=UTF-8</prop>
</props>
</property>
</bean>
</beans>
Configuração do Dispatcher Servlet
O dispatch-servlet.xml gerencia controladores MVC, conversores de mensagem e resolução de visão com Velocity.
<?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:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd "
default-lazy-init="false">
<context:component-scan base-package="com.exemplo.controlador" />
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
<value>application/x-www-form-urlencoded;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
</list>
</property>
<property name="features">
<list>
<value>WriteMapNullValue</value>
<value>WriteNullStringAsEmpty</value>
<value>WriteNullNumberAsZero</value>
<value>QuoteFieldNames</value>
<value>WriteNullListAsEmpty</value>
<value>WriteNullBooleanAsFalse</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<mvc:resources mapping="/recursos/**" location="/recursos/" cache-period="86400" />
<mvc:resources mapping="/uploads/**" location="/uploads/" cache-period="86400" />
<bean class="org.springframework.web.servlet.mvc.WebContentInterceptor"
p:cacheSeconds="0" p:alwaysUseFullPath="true">
<property name="cacheMappings">
<props>
<prop key="/**/*.html">-1</prop>
</props>
</property>
</bean>
<bean id="resolvedorVisao"
class="org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver">
<property name="cache" value="false" />
<property name="dateToolAttribute" value="data" />
<property name="prefix" value="" />
<property name="suffix" value=".vm" />
<property name="contentType" value="text/html;charset=UTF-8" />
<property name="exposeSpringMacroHelpers" value="true" />
<property name="exposeRequestAttributes" value="true" />
<property name="requestContextAttribute" value="ctx" />
<property name="exposeSessionAttributes" value="true" />
<property name="allowSessionOverride" value="true" />
<property name="allowRequestOverride" value="true" />
<property name="layoutUrl" value="layout/padrao.vm" />
</bean>
<bean id="resolvedorMultipart"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="100000000" />
</bean>
</beans>
Configuração do web.xml
Define listaners, filtros e o servlet do Spring MVC.
<?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"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<display-name>aplicacaoDemo</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<filter>
<filter-name>filtroCodificacao</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>filtroCodificacao</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>60</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>/index.jsp</welcome-file>
</welcome-file-list>
</web-app>
Configuração do context.xml para Fonte de Dados
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource name="jdbc/bancoDadosApp" auth="Container"
type="javax.sql.DataSource"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/appdb"
username="admin"
password="senha_segura"
maxActive="50"
maxIdle="30"
maxWait="10000" />
</Context>
Configuração do Maven (pom.xml)
Inclui dependências para Spring, Hibernate, Velocity, Fastjson e outras bibliotecas.
<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>com.exemplo</groupId>
<artifactId>aplicacao-web</artifactId>
<packaging>war</packaging>
<version>1.0.0</version>
<name>Aplicação Web Demo</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<versao.hibernate>4.2.21.Final</versao.hibernate>
<versao.spring>4.2.3.RELEASE</versao.spring>
<versao.velocity>1.7</versao.velocity>
<versao.velocity-tools>2.0</versao.velocity-tools>
<versao.aspectjweaver>1.8.7</versao.aspectjweaver>
<versao.fastjson>1.2.8</versao.fastjson>
<versao.fileupload>1.3.1</versao.fileupload>
<versao.mysql-connector>5.1.37</versao.mysql-connector>
<versao.servlet>2.5</versao.servlet>
<versao.jsp-api>2.1</versao.jsp-api>
<versao.log4j>2.3</versao.log4j>
<versao.junit>4.12</versao.junit>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>utf8</encoding>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${versao.spring}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${versao.spring}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${versao.spring}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${versao.hibernate}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${versao.aspectjweaver}</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>${versao.velocity}</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-tools</artifactId>
<version>${versao.velocity-tools}</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>${versao.fileupload}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${versao.log4j}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${versao.fastjson}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${versao.mysql-connector}</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.3</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${versao.servlet}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>${versao.jsp-api}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${versao.junit}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${versao.spring}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Classes Java
Entidade de Modelo
Classe de entidade para representar um usuário no sistema.
package com.exemplo.modelo;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "usuarios")
public class Usuario implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long identificador;
@Column(name = "nome_usuario")
private String nomeUsuario;
@Column(name = "senha")
private String senha;
public Long getIdentificador() {
return identificador;
}
public void setIdentificador(Long identificador) {
this.identificador = identificador;
}
public String getNomeUsuario() {
return nomeUsuario;
}
public void setNomeUsuario(String nomeUsuario) {
this.nomeUsuario = nomeUsuario;
}
public String getSenha() {
return senha;
}
public void setSenha(String senha) {
this.senha = senha;
}
}
Camada DAO Base com JDBC
Classe base para operações de banco de dados usando JDBC com Spring.
package com.exemplo.dao.base;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
public class JdbcDaoBase extends JdbcDaoSupport {
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
@Autowired
public void configurarFonteDados(DataSource fonteDados) {
super.setDataSource(fonteDados);
namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(fonteDados);
}
public List<map :="" atualizarregistro="" buscarporchave="" campos="" campos.entryset="" campos.remove="" campos.size="" catch="" chaveprimaria="" clausulaset="new" clausulaset.append="" colunas="new" colunas.append="" consultacomin="" consultaunica="" contador="0;" deletarregistro="" e="" else="" entrada="" executaratualizacao="" executarconsulta="" for="" hashmap="" if="" inserirregistro="" int="" list="" lista="" map="" mapaparametros="new" mapaparametros.put="" namedparameterjdbctemplate.queryforlist="" null="" object="" object...="" placeholder="" public="" return="" set="" sql="" string="" stringbuilder="" tabela="" this.getjdbctemplate="" try="" valorchave="campos.get(chavePrimaria);" valores="" valores.append="" values="" where=""></map>
Interface DAO Base com Hibernate
package com.exemplo.dao.base;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
public interface DaoHibernateBase<T, PK extends Serializable> {
PK salvar(T entidade);
void salvarOuAtualizar(T entidade);
void atualizar(T entidade);
int atualizarOuDeletarHQL(String hql, Object... valores);
int atualizarOuDeletarSQL(String sql, Object... valores);
void deletar(T entidade);
void deletar(PK identificador);
void deletar(Collection<T> lista);
List<T> buscarTodos();
T buscarPorChave(PK identificador);
List<T> buscarPorExemplo(T entidade);
List<?> buscarHQL(String hql, Object... valores);
List<?> buscarSQL(String sql, Object... valores);
Object buscarUnicoHQL(String hql, Object... valores);
Object buscarUnicoSQL(String sql, Object... valores);
List<T> buscarPorPropriedade(String nomePropriedade, Object valor);
Object buscarUnicoPorPropriedade(String nomePropriedade, Object valor);
Query criarConsulta(String hql, Object... valores);
SQLQuery criarConsultaSQL(String sql, Object... valores);
Criteria criarCriteria(Criterion... criterios);
boolean propriedadeEhUnica(String nomePropriedade, Object novoValor, Object valorOriginal);
List<?> buscarPaginaHQL(String hql, int inicio, int tamanho, Object... valores);
List<?> buscarPaginaSQL(String sql, int inicio, int tamanho, Object... valores);
List<?> buscarComInHQL(String hql, String placeholder, List<?> valores);
List<?> buscarComInSQL(String sql, String placeholder, List<?> valores);
List<T> buscarPorCriteria(Criterion... criterios);
List<T> buscarPorCriteria(Order[] ordenacoes, Criterion... criterios);
List<T> buscarPaginaPorCriteria(int inicio, int tamanho, Order[] ordenacoes, Criterion... criterios);
Integer contarPorCriteria(Criterion... criterios);
}
Implementação DAO Base com Hibernate
package com.exemplo.dao.base;
import java.io.Serializable;
import java.util.List;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.hibernate.metadata.ClassMetadata;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;
import com.exemplo.utilitarios.ReflexaoUtilitarios;
public abstract class DaoHibernateBaseImpl<T, PK extends Serializable> {
private static final Logger logger = LogManager.getLogger(DaoHibernateBaseImpl.class);
protected Class<T> classeEntidade;
@Autowired
protected HibernateTemplate templateHibernate;
public DaoHibernateBaseImpl() {
this.classeEntidade = ReflexaoUtilitarios.obterTipoGenericoSuperclasse(getClass());
}
protected Session obterSessao() {
return templateHibernate.getSessionFactory().getCurrentSession();
}
public void salvar(T entidade) {
templateHibernate.save(entidade);
}
public void atualizar(T entidade) {
templateHibernate.update(entidade);
}
public void salvarOuAtualizar(T entidade) {
templateHibernate.saveOrUpdate(entidade);
}
public void deletar(T entidade) {
if (entidade != null) {
templateHibernate.delete(entidade);
}
}
public void deletar(PK identificador) {
if (identificador != null) {
deletar(obter(identificador));
}
}
public T obter(PK identificador) {
return (T) templateHibernate.get(classeEntidade, identificador);
}
public List<T> buscarTodos() {
return buscarPorCriteria();
}
public List<T> buscarPorPropriedade(String nomePropriedade, Object valor) {
Criterion criterio = Restrictions.eq(nomePropriedade, valor);
return buscarPorCriteria(criterio);
}
public T buscarUnicoPorPropriedade(String nomePropriedade, Object valor) {
Criterion criterio = Restrictions.eq(nomePropriedade, valor);
return (T) criarCriteria(criterio).uniqueResult();
}
public int executarAtualizacao(String hql, Object... valores) {
return criarConsulta(hql, valores).executeUpdate();
}
public List<T> buscar(String hql, Object... valores) {
return criarConsulta(hql, valores).list();
}
public List<T> buscarPagina(String hql, int inicio, int tamanho, Object... valores) {
return criarConsulta(hql, valores).setFirstResult(inicio).setMaxResults(tamanho).list();
}
public List<T> buscarComIn(String hql, String placeholder, List<?> valores) {
return criarConsultaComIn(hql, placeholder, valores).list();
}
public T buscarUnico(String hql, Object... valores) {
return (T) criarConsulta(hql, valores).uniqueResult();
}
public Query criarConsulta(String hql, Object... valores) {
Query consulta = obterSessao().createQuery(hql);
if (valores != null) {
for (int i = 0; i < valores.length; i++) {
consulta.setParameter(i, valores[i]);
}
}
return consulta;
}
public Query criarConsultaComIn(String hql, String placeholder, List<?> valores) {
Query consulta = obterSessao().createQuery(hql);
if (valores != null) {
consulta.setParameterList(placeholder, valores);
}
return consulta;
}
public List<T> buscarPorCriteria(Criterion... criterios) {
return criarCriteria(criterios).list();
}
public Criteria criarCriteria(Criterion... criterios) {
Criteria criteria = obterSessao().createCriteria(classeEntidade);
for (Criterion c : criterios) {
criteria.add(c);
}
return criteria;
}
public boolean propriedadeEhUnica(String nomePropriedade, Object novoValor, Object valorOriginal) {
if (novoValor == null || novoValor.equals(valorOriginal)) {
return true;
}
Object objeto = buscarUnicoPorPropriedade(nomePropriedade, novoValor);
return (objeto == null);
}
public String obterNomeChavePrimaria() {
ClassMetadata metadados = templateHibernate.getSessionFactory().getClassMetadata(classeEntidade);
return metadados.getIdentifierPropertyName();
}
public SQLQuery criarConsultaSQL(String sql, Object... valores) {
SQLQuery consultaSQL = obterSessao().createSQLQuery(sql);
if (valores != null) {
for (int i = 0; i < valores.length; i++) {
consultaSQL.setParameter(i, valores[i]);
}
}
return consultaSQL;
}
}
DAO de Usuário com Hibernate
package com.exemplo.dao;
import java.io.Serializable;
import org.springframework.stereotype.Repository;
import com.exemplo.dao.base.DaoHibernateBaseImpl;
import com.exemplo.modelo.Usuario;
@Repository
public class UsuarioDaoHQL extends DaoHibernateBaseImpl<Usuario, Serializable> {
public Usuario autenticar(String nomeUsuario, String senha) {
String hql = "FROM Usuario WHERE nomeUsuario = ? AND senha = ?";
return this.buscarUnico(hql, nomeUsuario, senha);
}
}
DAO de Usuário com JDBC
package com.exemplo.dao;
import java.util.Map;
import org.springframework.stereotype.Repository;
import com.exemplo.dao.base.JdbcDaoBase;
import com.exemplo.modelo.Usuario;
@Repository
public class UsuarioDaoJDBC extends JdbcDaoBase {
public Usuario autenticar(String nomeUsuario, String senha) {
String sql = "SELECT * FROM usuarios WHERE nome_usuario = ? AND senha = ?";
Map<String, Object> resultado = this.consultaUnica(sql, nomeUsuario, senha);
Usuario usuario = null;
if (resultado != null) {
usuario = new Usuario();
usuario.setIdentificador(resultado.get("identificador") != null ?
Long.parseLong(resultado.get("identificador").toString()) : null);
usuario.setNomeUsuario(resultado.get("nome_usuario") != null ?
resultado.get("nome_usuario").toString() : null);
usuario.setSenha(resultado.get("senha") != null ?
resultado.get("senha").toString() : null);
}
return usuario;
}
}
Serviço de Negócio
package com.exemplo.servico;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.exemplo.modelo.Usuario;
import com.exemplo.dao.UsuarioDaoHQL;
import com.exemplo.dao.UsuarioDaoJDBC;
@Transactional(readOnly = false)
@Service("servicoUsuario")
public class ServicoUsuario {
@Autowired
private UsuarioDaoHQL daoHQL;
@Autowired
private UsuarioDaoJDBC daoJDBC;
public Usuario autenticarComHQL(String nomeUsuario, String senha) {
return daoHQL.autenticar(nomeUsuario, senha);
}
public Usuario autenticarComJDBC(String nomeUsuario, String senha) {
return daoJDBC.autenticar(nomeUsuario, senha);
}
}
Controlador MVC
package com.exemplo.controlador;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.exemplo.modelo.Usuario;
import com.exemplo.servico.ServicoUsuario;
@Controller
@RequestMapping("/usuario")
public class ControladorUsuario {
@Autowired
private ServicoUsuario servicoUsuario;
@RequestMapping(value = "/pagina-inicial", method = RequestMethod.GET)
public String exibirPaginaInicial(HttpServletRequest requisicao, HttpServletResponse resposta) {
return "pagina-inicial";
}
@RequestMapping(value = "/login", method = RequestMethod.GET)
public String exibirFormularioLogin(HttpServletRequest requisicao, HttpServletResponse resposta) {
return "login";
}
@RequestMapping(value = "/autenticar", method = RequestMethod.POST)
@ResponseBody
public Map<String, String> processarLogin(Usuario usuario, HttpServletRequest requisicao,
HttpServletResponse resposta) {
Map<String, String> respostaMap = new HashMap<>();
if (usuario == null || usuario.getNomeUsuario() == null || usuario.getSenha() == null) {
respostaMap.put("status", "erro");
respostaMap.put("mensagem", "Credenciais não fornecidas");
return respostaMap;
}
Usuario usuarioAutenticado = servicoUsuario.autenticarComJDBC(usuario.getNomeUsuario(), usuario.getSenha());
if (usuarioAutenticado != null) {
respostaMap.put("status", "sucesso");
respostaMap.put("mensagem", "Autenticação bem-sucedida");
} else {
respostaMap.put("status", "erro");
respostaMap.put("mensagem", "Falha na autenticação");
}
return respostaMap;
}
}
Classe Utilitária de Reflexão
package com.exemplo.utilitarios;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public final class ReflexaoUtilitarios {
private static final Logger logger = LogManager.getLogger(ReflexaoUtilitarios.class);
private ReflexaoUtilitarios() {
}
public static Object obterValorCampo(Object objeto, String nomeCampo) {
Field campo = obterCampoDeclarado(objeto.getClass(), nomeCampo);
if (campo == null) {
throw new IllegalArgumentException("Campo não encontrado: " + nomeCampo);
}
tornarAcessivel(campo);
try {
return campo.get(objeto);
} catch (IllegalAccessException e) {
logger.error("Erro ao acessar campo", e);
return null;
}
}
public static void definirValorCampo(Object objeto, String nomeCampo, Object valor) {
Field campo = obterCampoDeclarado(objeto.getClass(), nomeCampo);
if (campo == null) {
throw new IllegalArgumentException("Campo não encontrado: " + nomeCampo);
}
tornarAcessivel(campo);
try {
campo.set(objeto, valor);
} catch (IllegalAccessException e) {
logger.error("Erro ao definir campo", e);
}
}
protected static Field obterCampoDeclarado(Class<?> classe, String nomeCampo) {
for (Class<?> classeAtual = classe; classeAtual != Object.class; classeAtual = classeAtual.getSuperclass()) {
try {
return classeAtual.getDeclaredField(nomeCampo);
} catch (NoSuchFieldException e) {
// Continua para a superclasse
}
}
return null;
}
protected static void tornarAcessivel(Field campo) {
if (!Modifier.isPublic(campo.getModifiers()) || !Modifier.isPublic(campo.getDeclaringClass().getModifiers())) {
campo.setAccessible(true);
}
}
@SuppressWarnings("unchecked")
public static Class<?> obterTipoGenericoSuperclasse(Class<?> classe) {
return obterTipoGenericoSuperclasse(classe, 0);
}
@SuppressWarnings("unchecked")
public static Class<?> obterTipoGenericoSuperclasse(Class<?> classe, int indice) {
Type tipoGenerico = classe.getGenericSuperclass();
if (!(tipoGenerico instanceof ParameterizedType)) {
logger.warn("Superclasse não é parametrizada: " + classe.getSimpleName());
return Object.class;
}
Type[] argumentos = ((ParameterizedType) tipoGenerico).getActualTypeArguments();
if (indice < 0 || indice ≥ argumentos.length) {
logger.warn("Índice inválido para tipo genérico: " + indice);
return Object.class;
}
if (argumentos[indice] instanceof Class) {
return (Class<?>) argumentos[indice];
}
logger.warn("Tipo genérico não é classe: " + classe.getSimpleName());
return Object.class;
}
public static List<?> extrairPropriedadesParaLista(Collection<?> colecao, String nomePropriedade) throws Exception {
List<Object> lista = new ArrayList<>();
for (Object objeto : colecao) {
lista.add(PropertyUtils.getProperty(objeto, nomePropriedade));
}
return lista;
}
public static String extrairPropriedadesParaString(Collection<?> colecao, String nomePropriedade, String separador) throws Exception {
List<?> lista = extrairPropriedadesParaLista(colecao, nomePropriedade);
return StringUtils.join(lista, separador);
}
}
Esta configuração fornece uma base completa para uma aplicação web Java moderna, integrando Spring para injeção de dependência e transações, Hibernate para persistência, Spring MVC para camada web, Velocity para renderização de templates e Maven para gerenciamento de dependências e build.