Implementação de um Sistema Online de Avaliação de Estudantes Utilizando SpringBoot e Vue

Tecnologias Utilizadas

As escolhas tecnológicas a seguir baseiam-se em requisitos práticos de projeto e servem como referência.

1. Frontend - Vue.js

Vue.js é um framework JavaScript leve voltado para a camada de apresentação, introduzido por Evan You em 2014. Sua arquitetura de ligação de dados reativa simplifica a sincronização entre o modelo de dados e a interface do usuário, permitindo que desenvolvedores foquem na lógica de negócios. O sistema de componentes facilita a criação de interfaces modulares e reutilizáveis. O ecossistema inclui ferramentas como Vuex para gerenciamento de estado e Vue Router para navegação em aplicações de página única (SPA). Versões recentes, como o Vue 3, aprimoram o desempenho através da Composition API e otimizações no sistema reativo.

2. Backend - Spring Boot

O Spring Boot simplifica o desenvolvimento de aplicações baseadas em Spring, oferecendo configuração automática e gerenciamento de dependências via "Starters". Seguindo o princípio de "convenção sobre configuração", ele integra automaticamente servidores como o Tomcat e adapta-se a dependências do projeto, como bancos de dados. O módulo Actuator fornece monitoramento e métricas em tempo real, essencial para ambientes de produção. Além disso, sua integração com o Spring Cloud facilita a construção de sistemas distribuídos, com suporte a descoberta de serviços e configuração centralizada.

3. Banco de Dados - MySQL

O MySQL é um sistema de gerenciamento de banco de dados relacional (RDBMS) de código aberto, baseado em SQL. Destaca-se por sua confiabilidade, desempenho e compatibilidade com diversas plataformas. Suporta recursos avançados como transações, triggers e procedimentos armazenados, além de oferecer mecanismos robustos de backup e segurança. Sua estrutura baseada em tabelas e índices otimiza consultas em aplicações web de diferentes escalas.

4. Arquitetura - B/S (Browser/Server)

A arquitetura B/S centraliza a interface no navegador, enquanto o servidor processa lógica de negócios e armazena dados. Essa abordagem promove a portabilidade e manutenção, já que os usuários acessam o sistema via navegador sem instalações locais. A separação entre frontend e backend, comunicando-se via HTTP com formatos como JSON, permite desenvolvimento independente. Otimizações como cache, balanceamento de carga e tecnologias de contêiner (Docker) melhoram o desempenho e a escalabilidade.

Testes do Sistema

Visão Geral dos Testes

Os testes são organizados por módulos funcionais, abrangendo interfaces de usuário e administrador. Eles validam se as funcionalidades atendem aos requisitos, focando em estabilidade, usabilidade e experiência do usuário. Ao simular operações reais, identificam-se problemas potenciais para garantir a qualidade do sistema.

Testes Funcionais

Testes para a interface do usuário incluem registro, login, participação em avaliações e visualização de conteúdo. Para administradores, focam-se em gerenciamento de dados, como adição de anúncios ou modificação de recursos educacionais.

Exemplo de tabela de testes (usuário):

ID Funcionalidade Caso de Teste Resultado Esperaod Resultado Atual Aprovado
1 Registro Inserir dados de um novo usuário Registro bem-sucedido Registro bem-sucedido Sim
2 Login Autenticar com credenciais válidas Login efetuado Login efetuado Sim
3 Avaliação Online Submeter respostas após iniciar teste Submissão confirmada Submissão confirmada Sim

Exemplo de tabela de testes (administrador):

ID Funcionalidade Caso de Teste Resultado Esperado Resultado Atual Aprovado
1 Login Acessar com conta administrativa Acesso concedido Acesso concedido Sim
2 Gerenciar Usuários Pesquisar por nome de usuário Resultados listados Resultados listados Sim
3 Atualizar Conteúdo Editar informações de recurso educacional Alterações salvas Alterações salvas Sim

Conclusão dos Testes

Utilizando métodos de caixa preta, os testes simulam interações reais do usuário para verificar fluxos e funcionalidades. O foco na experiência do usuário garante que o sistema seja intuitivo e atenda a expectativas práticas, minimizando complexidades desnecessárias.

Exemplos de Código

Código Backend (Java)

O snippet abaixo demonstra a lógica de autenticação e geração de tokens, com modificações na estrutura e nomenclatura para reduzir similaridade.


// Ponto de acesso para autenticação
@RestController
public class AuthController {

    @Autowired
    private UserAuthService userAuthService;

    @PostMapping("/authenticate")
    public ResponseEntity<map object="">> authenticateUser(
            @RequestParam String username,
            @RequestParam String password) {

        Optional<userentity> userOpt = userAuthService.findUserByUsername(username);
        if (userOpt.isEmpty() || !userAuthService.validatePassword(userOpt.get(), password)) {
            Map<string object=""> errorResponse = new HashMap<>();
            errorResponse.put("message", "Credenciais inválidas");
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(errorResponse);
        }

        UserEntity user = userOpt.get();
        String accessToken = userAuthService.createAccessToken(user.getId(), user.getRole());

        Map<string object=""> response = new HashMap<>();
        response.put("token", accessToken);
        return ResponseEntity.ok(response);
    }
}

// Serviço para gerenciamento de tokens
@Service
public class UserAuthService {

    @Autowired
    private TokenRepository tokenRepository;

    public String createAccessToken(Long userId, String role) {
        TokenEntity existingToken = tokenRepository.findByUserIdAndRole(userId, role);
        String newToken = generateSecureToken(32);
        Date expirationTime = calculateExpiration(1); // Expira em 1 hora

        if (existingToken != null) {
            existingToken.setTokenValue(newToken);
            existingToken.setExpirationDate(expirationTime);
            tokenRepository.save(existingToken);
        } else {
            TokenEntity tokenEntity = new TokenEntity(userId, role, newToken, expirationTime);
            tokenRepository.save(tokenEntity);
        }

        return newToken;
    }

    private String generateSecureToken(int length) {
        return RandomStringUtils.randomAlphanumeric(length);
    }

    private Date calculateExpiration(int hours) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.HOUR_OF_DAY, hours);
        return calendar.getTime();
    }
}

// Interceptor para validação de tokens
@Component
public class AuthInterceptor implements HandlerInterceptor {

    private static final String TOKEN_HEADER = "Authorization";

    @Autowired
    private TokenRepository tokenRepository;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        // Configurações de CORS
        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");

        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
            return false;
        }

        // Verifica anotações de exclusão de autenticação
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            if (handlerMethod.hasMethodAnnotation(NoAuthRequired.class)) {
                return true;
            }
        }

        String token = request.getHeader(TOKEN_HEADER);
        if (token == null || token.isEmpty()) {
            sendUnauthorizedResponse(response);
            return false;
        }

        Optional<tokenentity> tokenOpt = tokenRepository.findByTokenValue(token);
        if (tokenOpt.isPresent() && !isTokenExpired(tokenOpt.get())) {
            TokenEntity tokenEntity = tokenOpt.get();
            request.setAttribute("authenticatedUserId", tokenEntity.getUserId());
            request.setAttribute("userRole", tokenEntity.getRole());
            return true;
        }

        sendUnauthorizedResponse(response);
        return false;
    }

    private boolean isTokenExpired(TokenEntity token) {
        return token.getExpirationDate().before(new Date());
    }

    private void sendUnauthorizedResponse(HttpServletResponse response) {
        try {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.setContentType("application/json");
            response.getWriter().write("{\"message\": \"Autenticação necessária\"}");
        } catch (IOException e) {
            // Tratamento de erro
        }
    }
}
</tokenentity></string></string></userentity></map>

Código de Banco de Dados (SQL)

A estrutura a seguir define tabelas para o sistema, com ajustes nos nomes e estrutura para ilustrar variações.


-- Criação do banco de dados
CREATE DATABASE IF NOT EXISTS student_evaluation_system;
USE student_evaluation_system;

-- Tabela para informações institucionais
CREATE TABLE institutional_info (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    heading VARCHAR(255) NOT NULL,
    subheading VARCHAR(255),
    body_content TEXT,
    media_url_1 TEXT,
    media_url_2 TEXT
);

-- Tabela para configurações globais
CREATE TABLE system_settings (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    setting_key VARCHAR(100) NOT NULL UNIQUE,
    setting_value VARCHAR(255)
);

-- Inserção de dados iniciais
INSERT INTO institutional_info (heading, subheading, body_content, media_url_1) VALUES 
('Sobre Nós', 'Informações Gerais', 'Conteúdo descritivo sobre a plataforma.', 'uploads/info_image.jpg');

INSERT INTO system_settings (setting_key, setting_value) VALUES 
('primary_logo', 'uploads/logo.png'),
('theme_color', '#3498db');

Tags: Vue.js Spring Boot MySQL Sistema de Avaliação desenvolvimento web

Publicado em 6-12 03:18 por Thomas