Adicione nas bibliotecas do projeto o driver do PostgreSQL (ou outro banco). O do PostgreSQL pode ser baixado daqui: https://jdbc.postgresql.org/download/
Crie um pacote chamado connection e uma classe de nome SingleConnection:
package connection;
import java.sql.Connection;
import java.sql.DriverManager;
public class SingleConnection {
private static final String BANCO = "jdbc:postgresql://localhost:5432/cursojsp?autoReconnect=true";
private static final String USER = "postgres";
private static final String PASSWORD = "admin";
private static Connection conexao = null; // Importe (não é constante)
static { // Isso é para chamar o método sem precisar colocar o nome dele, apenas pelo nome da classe.
conectar();
}
public SingleConnection() {
conectar();
}
private static void conectar() {
try {
if(conexao == null) {
Class.forName("org.postgresql.Driver"); // Driver do tipo de banco
conexao = DriverManager.getConnection(BANCO, USER, PASSWORD);
conexao.setAutoCommit(false);
}
}
catch(Exception ex) {
throw new RuntimeException("Erro ao conectar com o banco");
}
}
public static Connection getConexao() {
return conexao;
}
}
E crie um banco de dados com esse código:
create database cursojsp;
Crie a tabela com essas colunas:
create table usuario (
id int not null primary key auto_increment,
login varchar(40) unique,
senha varchar(40)
)
E dê um insert com os dados do login e senha nessa mesma tabela.
No web.xml, dentro da tag web-app, coloque essas tags:
<filter>
<filter-name>filter</filter-name>
<filter-class>filter.FilterConnection</filter-class>
</filter>
<filter-mapping>
<filter-name>filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
E crie essa classe num pacote filter:
package filter;
import connection.SingleConnection;
import java.io.IOException;
import java.sql.Connection;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
@WebFilter(urlPatterns={"/*"}) // Importe
public class FilterConnection implements Filter {
private static Connection conexao;
@Override
public void init(FilterConfig filterConf) throws ServletException {
// Método sempre invocado
SingleConnection.getConexao();
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
try {
chain.doFilter(request, response);
conexao.commit();
}
catch(Exception ex) {
try {
conexao.rollback();
}
catch(Exception ex2) {
ex2.printStackTrace();
}
}
}
@Override
public void destroy() {
}
}
Crie um pacote com o nome dao e a classe com o nome DAOLogin, com esse código:
package dao;
import connection.*;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class DAOLogin {
private Connection conexao; // Importe
public DAOLogin() {
conexao = SingleConnection.getConexao(); // Importe
}
public boolean validarLoginSenha(String login, String senha) throws Exception {
String sql = "select * from usuario where login = ? and senha = ?";
PreparedStatement stmt = conexao.prepareStatement(sql); // Importe
stmt.setString(1, login);
stmt.setString(2, senha);
ResultSet rs = stmt.executeQuery(); // Importe
if(rs.next()) {
return true;
}
else {
return false;
}
}
}
No servlet LoginServlet, coloque essa declaração de objeto:
private DAOLogin dao = new DAOLogin(); // Importe
E na mesma classe, altere o método doPost assim:
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String login = request.getParameter("tLogin").trim();
String senha = request.getParameter("tSenha").trim();
RequestDispatcher dispatcher; // Importe
try {
if(dao.validarLoginSenha(login, senha)) {
dispatcher = request.getRequestDispatcher("acessoliberado.jsp");
}
else {
dispatcher = request.getRequestDispatcher("acessonegado.jsp");
}
dispatcher.forward(request, response);
}
catch(Exception ex) {
System.err.println(ex.getMessage());
}
}
No index.jsp deixe apenas o formulário de login e tente logar com o login e senha cadastrados no banco.
PS: Caso tenha problemas com a porta usada no momento, digite o comando netstat /ano | findstr :8080
(a porta especificada) no prompt de comando do Windows, e depois taskkill /pid 7800
(número do PID). Em sistemas Unix os comandos são netstat -tulpn | grep 8080
e kill -9 7800
.
Caso necessite criptografar as senhas, podemos criar uma classe com um método estático pra isso:
package hashs;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class CriptSenha {
private static byte vetor[] = null;
private static StringBuilder cript = null;
private static String hash = "";
public static String encripta(String sen, String tipo) {
try {
vetor = MessageDigest.getInstance(tipo).digest(sen.getBytes()); // Importe java.security.MessageDigest;
cript = new StringBuilder();
for(int i = 0; i < vetor.length; i++) {
cript.append(Integer.toHexString((vetor[i] & 0xFF) | 0x100).substring(1,3));
}
hash = cript.toString();
return hash;
}
catch(NoSuchAlgorithmException ex) { // Importe java.security.NoSuchAlgorithmException;
System.err.println("ERRO: " + ex.getMessage());
return null;
}
}
}
Essa classe acima pode ser usada em vários projetos do tipo, mas no nosso projeto, basta alterar o stmt.setString() da senha assim:
stmt.setString(2, CriptSenha.encripta(senha, "SHA-1"));
Obviamente, no caso acima, o hash deverá estar no banco de dados guardado como SHA-1. Podemos também escolher MD5 e SHA-256 como opções de hash.