Nome do Projeto: BiblioNet - Sistema Distribuído de Gerenciamento Bibliotecário
O BiblioNet é um sistema CRUD de biblioteca implementado com arquitetura cliente-servidor, demonstrando conceitos avançados de comunicação via Sockets TCP com criptografia AES-256, persistência com JDBC puro, e otimizações de performance como pool de conexões manual e cache LRU. O sistema foi projetado para fins educacionais, evidenciando boas práticas de desenvolvimento Java EE-style com tecnologias core.
- JDBC Avançado: Gerenciamento manual de transações, prepared statements, batch processing, commit/rollback explícitos
- Pool de Conexões: Implementação manual de connection pooling com validação e timeout
- Segurança: Criptografia AES-256-GCM na comunicação via sockets
- Performance: Cache LRU com TTL para consultas frequentes e operações em lote
- Concorrência: Thread pool para clientes simultâneos
- Monitoramento: Logging estruturado com SLF4J + Logback
- Serialização Segura: Transmissão criptografada de dados via sockets
- Prevenção SQL Injection: Uso obrigatório de PreparedStatement
flowchart LR
Cliente["Cliente Java\n(Console)"]
Servidor["Servidor TCP Seguro\n(Thread Pool + Cache)"]
Banco["MySQL Database"]
Crypto["CryptoUtils\n(AES-256-GCM)"]
Infra["ConnectionPool\nQueryCache (LRU)\nBatchProcessor"]
Cliente <-->|AES-256\nSockets| Servidor
Servidor <-->|Pool JDBC| Banco
Cliente --> Crypto
Servidor --> Infra
| Comando | Formato Criptografado | Descrição |
|---|---|---|
| ADICIONAR | AES(ADICIONAR:titulo:autor:ano:isbn) |
Adiciona novo livro |
| LISTAR | AES(LISTAR) ou AES(LISTAR:titulo) |
Lista todos ou filtra por título (cacheado) |
| ATUALIZAR | AES(ATUALIZAR:id:titulo:autor:ano:isbn) |
Atualiza livro existente |
| DELETAR | AES(DELETAR:id) |
Remove livro por ID |
| BUSCAR | AES(BUSCAR:id) |
Busca livro específico (cacheado) |
| BATCH_ADD | AES(BATCH_ADD:json_array) |
Adiciona múltiplos livros em lote |
- Java SE 17+
- MySQL 8.0+
- JDBC Driver MySQL (puro, sem ORM)
- Sockets TCP (java.net)
- AES-256-GCM (javax.crypto)
- SLF4J + Logback (logging estruturado)
- Maven 3.8+ (gerenciamento de dependências)
- Java JDK 17 ou superior
- MySQL Server 8.0+
- Maven 3.8+
- Porta 8080 disponível para o servidor
git clone https://github.com/seu-usuario/biblionet.git
cd biblionet# Acesse o MySQL
mysql -u root -p
# Execute o script SQL
source src/main/resources/database/schema.sqlEdite o arquivo src/main/resources/application.properties:
# Banco de Dados
db.url=jdbc:mysql://localhost:3306/biblionet_db
db.user=root
db.password=sua_senha
# Connection Pool
db.pool.size=10
db.pool.timeout=30000
# Cache
cache.size=100
cache.ttl=60000
# Segurança (32 bytes para AES-256)
crypto.key=0123456789abcdef0123456789abcdef
# Servidor
server.port=8080mvn clean compilemvn exec:java -Dexec.mainClass="com.biblionet.server.BibliotecaServer"Saída esperada:
[INFO] Servidor Biblioteca iniciado na porta 8080
[INFO] Pool de conexões inicializado com 10 conexões
[INFO] Cache LRU inicializado com capacidade 100
[INFO] Aguardando conexões...
mvn exec:java -Dexec.mainClass="com.biblionet.client.BibliotecaClient"=== Sistema de Biblioteca Distribuído ===
Comandos disponíveis:
ADICIONAR:titulo:autor:ano:isbn
LISTAR
LISTAR:titulo
ATUALIZAR:id:titulo:autor:ano:isbn
DELETAR:id
BUSCAR:id
BATCH_ADD:[{...}, {...}]
SAIR
# Adicionar um livro
Digite um comando: ADICIONAR:Dom Quixote:Miguel de Cervantes:1605:978-84-376-0494-7
[SUCESSO] Livro adicionado com ID: 1
# Adicionar em lote
Digite um comando: BATCH_ADD:[{"titulo":"1984","autor":"George Orwell","ano":1949,"isbn":"978-0451524935"},{"titulo":"Brave New World","autor":"Aldous Huxley","ano":1932,"isbn":"978-0060850524"}]
[SUCESSO] 2 livros adicionados com sucesso
# Listar todos (primeira vez - consulta banco)
Digite um comando: LISTAR
Livros cadastrados:
ID: 1 | Dom Quixote | Miguel de Cervantes | 1605 | ISBN: 978-84-376-0494-7
ID: 2 | 1984 | George Orwell | 1949 | ISBN: 978-0451524935
ID: 3 | Brave New World | Aldous Huxley | 1932 | ISBN: 978-0060850524
# Buscar por título (usa cache)
Digite um comando: LISTAR:Quixote
ID: 1 | Dom Quixote | Miguel de Cervantes | 1605 | ISBN: 978-84-376-0494-7
# Buscar por ID (usa cache)
Digite um comando: BUSCAR:1
ID: 1 | Dom Quixote | Miguel de Cervantes | 1605 | ISBN: 978-84-376-0494-7
# Atualizar
Digite um comando: ATUALIZAR:1:Dom Quixote:Miguel de Cervantes:1605:978-84-376-0494-7
[SUCESSO] Livro atualizado
# Deletar
Digite um comando: DELETAR:3
[SUCESSO] Livro removido
# Sair
Digite um comando: SAIR
Encerrando cliente...biblionet/
│
├── pom.xml # Configuração Maven
├── README.md # Documentação completa
│
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/biblionet/
│ │ │ │
│ │ │ ├── server/
│ │ │ │ ├── BibliotecaServer.java # Servidor TCP principal
│ │ │ │ ├── ClientHandler.java # Handler para cada cliente
│ │ │ │ ├── SecureClientHandler.java # Handler com criptografia
│ │ │ │ ├── ConnectionPool.java # Pool de conexões manual
│ │ │ │ ├── PooledConnection.java # Wrapper para conexão pooled
│ │ │ │ ├── QueryCache.java # Cache LRU com TTL
│ │ │ │ ├── DatabaseManager.java # Gerenciador de banco de dados
│ │ │ │ └── BatchProcessor.java # Processamento em lote
│ │ │ │
│ │ │ ├── client/
│ │ │ │ ├── BibliotecaClient.java # Cliente console padrão
│ │ │ │ └── SecureBibliotecaClient.java # Cliente com criptografia
│ │ │ │
│ │ │ ├── security/
│ │ │ │ └── SecurityConstants.java # Constantes de segurança
│ │ │ │
│ │ │ ├── model/
│ │ │ │ └── Livro.java # Modelo de dados
│ │ │ │
│ │ │ ├── database/
│ │ │ │ └── DatabaseManager.java # Gerenciador JDBC puro
│ │ │ │
│ │ │ ├── cache/
│ │ │ │ ├── LRUCache.java # Implementação LRU genérica
│ │ │ │ └── CacheEntry.java # Entrada com TTL
│ │ │ │
│ │ │ ├── config/
│ │ │ │ ├── DatabaseConfig.java # Configurações do banco
│ │ │ │ └── ServerConfig.java # Configurações do servidor
│ │ │ │
│ │ │ ├── util/
│ │ │ │ ├── CryptoUtils.java # AES-256-GCM
│ │ │ │ ├── LoggerUtil.java # Utilitário de logging
│ │ │ │ ├── PerformanceMonitor.java # Monitor de performance
│ │ │ │ └── StringUtils.java # Utilitários de string
│ │ │
│ │ └── resources/
│ │ ├── database/
│ │ │ └── schema.sql # Script de criação do banco
│ │ ├── config/
│ │ │ └── application.properties # Configurações da aplicação
│ │ └── logback.xml # Configuração do Logback
public class ConnectionPool {
private final Queue<Connection> pool = new ConcurrentLinkedQueue<>();
private final int maxSize;
public Connection getConnection() throws SQLException {
Connection conn = pool.poll();
if (conn == null || !isValid(conn)) {
conn = createConnection();
}
return conn;
}
private boolean isValid(Connection conn) {
try {
return conn != null && conn.isValid(2);
} catch (SQLException e) {
return false;
}
}
}public class QueryCache<K, V> {
private final LinkedHashMap<K, CacheEntry<V>> cache;
private final long ttlMillis;
public V get(K key) {
CacheEntry<V> entry = cache.get(key);
if (entry != null && !entry.isExpired(ttlMillis)) {
return entry.getValue();
}
return null;
}
}public void batchInsert(List<Livro> livros) throws SQLException {
String sql = "INSERT INTO livros (titulo, autor, ano, isbn) VALUES (?, ?, ?, ?)";
try (PreparedStatement pstmt = connection.prepareStatement(sql)) {
for (Livro livro : livros) {
pstmt.setString(1, livro.getTitulo());
pstmt.setString(2, livro.getAutor());
pstmt.setInt(3, livro.getAno());
pstmt.setString(4, livro.getIsbn());
pstmt.addBatch();
}
pstmt.executeBatch();
}
}public void adicionarLivro(Livro livro) throws SQLException {
Connection conn = null;
try {
conn = pool.getConnection();
conn.setAutoCommit(false);
// Operações de banco
executeInsert(conn, livro);
conn.commit(); // Commit explícito
} catch (SQLException e) {
if (conn != null) conn.rollback(); // Rollback
throw e;
} finally {
if (conn != null) pool.releaseConnection(conn);
}
}Execute os testes unitários:
mvn testclassDiagram
class BibliotecaServer {
- serverSocket
- executor
- isRunning
+ start()
+ stop()
}
class ConnectionPool {
- pool
- maxSize
+ getConnection()
+ releaseConnection()
}
class ClientHandler {
- clientSocket
- dbManager
- crypto
+ run()
- processCommand()
}
class DatabaseManager {
- pool
- cache
+ adicionarLivro()
+ listarLivros()
+ atualizarLivro()
+ deletarLivro()
+ buscarLivro()
+ batchInsert()
}
class CryptoUtils {
- secretKey
+ encrypt()
+ decrypt()
}
class Livro {
- id
- titulo
- autor
- ano
- isbn
}
BibliotecaServer --> ClientHandler : usa
ClientHandler --> DatabaseManager : usa
ClientHandler --> CryptoUtils : usa
DatabaseManager --> ConnectionPool : usa
DatabaseManager --> Livro : usa
O sistema implementa tratamento robusto de erros:
- Erros de Conexão: Timeout configurável e validação periódica
- Erros de Banco: Rollback automático de transações
- Timeouts: Configuração de timeout nos sockets (30s)
- Validação: Verificação de dados antes da persistência
- Cache Miss: Fallback automático para consulta no banco
✅ Criptografia: AES-256-GCM na camada de socket
✅ Connection Pool: Pool próprio com validação e timeout
✅ Query Cache: LRU cache com TTL de 60s para queries frequentes
✅ Batch Processing: Inserção em lote com PreparedStatement
✅ SLF4J: Logging estruturado em arquivo e console
✅ Transações Manuais: Controle explícito de commit/rollback
✅ Prevenção SQL Injection: Uso obrigatório de PreparedStatement
✅ Thread Pool: Múltiplos clientes simultâneos
Este projeto está sob a licença MIT.