Introducción Técnica
Este documento detalla la creación de una funcionalidad para actualizar la contraseña de usuario en una aplicación web basada en Java. El proceso fundamental implica ejecutar una operación de actualización directa en la base de datos mediante SQL.
Capa de Acceso a Datos (DAO)
Se define una interfaz para interactuar con la tabla de usuarios, encapsulando las operaciones de consulta y modificación.
public interface AccesoDatosUsuario {
public Usuario buscarUsuarioPorCredenciales(Connection conexion, PreparedStatement declaracion, ResultSet resultados, String consulta, Object[] parametros);
public int modificarContrasena(Connection conexion, PreparedStatement declaracion, int identificadorUsuario, String nuevaContrasena);
}
La implementación concreta ejecuta las setnencias SQL proporcionadas.
public class AccesoDatosUsuarioImpl implements AccesoDatosUsuario {
@Override
public Usuario buscarUsuarioPorCredenciales(Connection conexion, PreparedStatement declaracion, ResultSet resultados, String consulta, Object[] parametros) {
Usuario usuario = new Usuario();
try {
resultados = BaseDatos.ejecutarConsulta(conexion, consulta, parametros, declaracion, resultados);
if (resultados.next()) {
usuario.setIdentificador(resultados.getInt("id"));
usuario.setNombreUsuario(resultados.getString("nombre_usuario"));
usuario.setContrasenaActual(resultados.getString("contrasena"));
// Mapeo de otros campos según esquema
}
} catch (SQLException error) {
error.printStackTrace();
}
return usuario;
}
@Override
public int modificarContrasena(Connection conexion, PreparedStatement declaracion, int identificadorUsuario, String nuevaContrasena) {
String sentenciaSQL = "UPDATE usuarios SET contrasena=? WHERE id=?";
Object[] valores = {nuevaContrasena, identificadorUsuario};
int filasModificadas = 0;
try {
filasModificadas = BaseDatos.ejecutarActualizacion(conexion, sentenciaSQL, valores, declaracion);
} catch (SQLException error) {
error.printStackTrace();
}
return filasModificadas;
}
}
Capa de Servicios
Se establece una interfaz de servicio para abstraer la lógica de negocio relacionada con la autenticación y gestión de credenciales.
public interface ServicioAutenticacion {
public Usuario autenticarUsuario(String codigoAcceso);
public boolean cambiarContrasena(int idUsuario, String nuevaClave);
}
La implementación maneja la transacción y liberación de recursos.
public class ServicioAutenticacionImpl implements ServicioAutenticacion {
private final Connection conexionDB = BaseDatos.obtenerConexion();
private final AccesoDatosUsuario daoUsuario;
public ServicioAutenticacionImpl() {
daoUsuario = new AccesoDatosUsuarioImpl();
}
@Override
public Usuario autenticarUsuario(String codigoAcceso) {
String sql = "SELECT * FROM usuarios WHERE codigo=?";
Object[] params = {codigoAcceso};
PreparedStatement stmt = null;
ResultSet rs = null;
Usuario usuarioAutenticado = daoUsuario.buscarUsuarioPorCredenciales(conexionDB, stmt, rs, sql, params);
BaseDatos.liberarRecursos(null, stmt, rs);
return usuarioAutenticado;
}
@Override
public boolean cambiarContrasena(int idUsuario, String nuevaClave) {
PreparedStatement stmt = null;
int actualizaciones = daoUsuario.modificarContrasena(conexionDB, stmt, idUsuario, nuevaClave);
boolean operacionExitosa = (actualizaciones > 0);
BaseDatos.liberarRecursos(null, stmt, null);
return operacionExitosa;
}
}
Controlador Servlet
El servlet recibe la solicitud HTTP, valida los parámetros y delega la operación al servicio.
@WebServlet("/cambiarClave.do")
public class ControladorUsuario extends HttpServlet {
protected void doPost(HttpServletRequest peticion, HttpServletResponse respuesta) throws ServletException, IOException {
Object sesionUsuario = peticion.getSession().getAttribute("USUARIO_ACTIVO");
String claveNueva = peticion.getParameter("clave_nueva");
if (sesionUsuario != null && claveNueva != null && !claveNueva.trim().isEmpty()) {
Usuario usuarioActual = (Usuario) sesionUsuario;
ServicioAutenticacion servicio = new ServicioAutenticacionImpl();
boolean resultado = servicio.cambiarContrasena(usuarioActual.getIdentificador(), claveNueva);
if (resultado) {
peticion.setAttribute("MENSAJE_EXITO", "La contraseña se ha actualizado correctamente.");
peticion.getSession().invalidate(); // Cerrar sesión por seguridad
} else {
peticion.setAttribute("MENSAJE_ERROR", "No se pudo completar la actualización.");
}
} else {
peticion.setAttribute("MENSAJE_ERROR", "Datos de entrada inválidos.");
}
peticion.getRequestDispatcher("/vistas/cambio_contrasena.jsp").forward(peticion, respuesta);
}
}
Configuración de Despliegue
La definición del servlet en el descriptor de la aplicación web asocia la URL con la classe controladora.
<servlet>
<servlet-name>gestorUsuarios</servlet-name>
<servlet-class>com.aplicacion.web.ControladorUsuario</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>gestorUsuarios</servlet-name>
<url-pattern>/cambiarClave.do</url-pattern>
</servlet-mapping>
El mecanismo de reenvío (forward) permite transmitir mensajes de retroalimentación al cliente mediante atributos de solicitud, los cuales son interpretados por la interfaz de usuario para mostrar notificaciones contextuales.