Objetivo
O sistema desenvolvido em Java com Spring Boot e MySQL permite que estudantes universitários publiqume, explorem, comprem e avaliem produtos eletrônicos usados. Alunos podem cadastrar itens, gerenciar estoque e acompanhar pedidos, enquanto compradores visualizam detalhes, realizam compras e deixam feedback. A plataforma resolve problemas de assimetria de informação e segurança em transações tradicionais, oferecendo um ambiente confiável para o comércio de eletrônicos recondicionados, além de incentivar a economia circular no campus.
Tecnologias Utilizadas
Backend – Spring Boot
O Spring Boot embute servidores como Tomcat e Jetty, eliminando configurações manuais. Sua auto-configuração baseada em dependências acelera o desenvolvimento. Recursos como Spring Data, Spring Security e Spring Cloud são integrados facilmente, permitindo criação rápida de aplicações robustas.
Frontend – Vue.js
Vue.js utiliza DOM virtual para renderização eficiente e reatividade. A ligação bidirecional de dados e o sistema de componentes simplificam a construção de interfaces dinâmicas e de fácil manutenção.
Persistência – MyBatis-Plus
MyBatis-Plus estende o MyBatis, reduzindo SQL manual por meio de anotações e API fluente. O gerador de código cria automaticamente entidades, mapeadores e XML. Recursos como paginação, bloqueio otimista e análise de desempenho são suportados, aumentando a produtividade no acesso a dados.
Testes do Sistema
Os testes validam a funcionalidade e a usabilidade. Foram realizados testes de caixa preta nos módulos de login e gerenciamento de usuários, utilizando casos de teste com valores válidos, inválidos e limites.
Teste de Login
| Entrada | Resultado esperado | Resultado real | Análise |
|---|---|---|---|
| usuário: admin, senha: 123456, captcha: correto | Login bem-sucedido | Login realizado | OK |
| usuário: admin, senha: 111111, captcha: correto | Senha incorreta | Mensagem de erro exibida | OK |
| usuário: admin, senha: 123456, captcha: errado | Captcha inválido | Alerta de captcha | OK |
| usuário: vazio, senha: 123456, captcha: correto | Usuário obrigatório | Campo obrigatório | OK |
Teste de Gerenciamento de Usuários
| Operação | Resultado esperado | Resultado real | Análise |
|---|---|---|---|
| Inserir dados comlpetos | Usuário adicionado | Aparece na lista | OK |
| Alterar informações | Dados atualizados | Lista reflete alterações | OK |
| Excluir usuário | Confirmação e remoção | Confirma e usuário some | OK |
| Adicionar sem nome | Erro: nome obrigatório | Mensagem exibida | OK |
| Adicionar nome duplicado | Falha: nome já existe | Mensagem de conflito | OK |
Os testes confirmam que o sistema atende aos requisitos funcionais e de usabilidade, com fluxos corretos para login e CRUD de usuários.
Exemplo de Código
// Endpoint de login (ignorando autenticação)
@PostMapping("/login")
public Response login(@RequestParam String user, @RequestParam String pass,
@RequestParam String captcha, HttpServletRequest req) {
UserEntity usuario = userRepo.findOne(
new QueryWrapper<UserEntity>().eq("username", user));
if (usuario == null || !usuario.getPassword().equals(pass)) {
return Response.error("Credenciais inválidas");
}
// Gera token
String token = tokenService.createToken(
usuario.getId(), user, "users", usuario.getRole());
return Response.ok().put("token", token);
}
// Serviço de token
public String createToken(Long userId, String name, String table, String role) {
TokenEntity tokenEntity = this.selectOne(
new QueryWrapper<TokenEntity>()
.eq("user_id", userId).eq("role", role));
String newToken = CommonUtil.randomString(32);
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
calendar.add(Calendar.HOUR_OF_DAY, 1);
if (tokenEntity != null) {
tokenEntity.setToken(newToken);
tokenEntity.setExpiration(calendar.getTime());
this.updateById(tokenEntity);
} else {
this.insert(new TokenEntity(userId, name, table, role, newToken, calendar.getTime()));
}
return newToken;
}
// Interceptador de autorização
@Component
public class AuthInterceptor implements HandlerInterceptor {
private static final String HEADER_TOKEN = "Authorization";
@Autowired
private TokenService tokenService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
return false;
}
IgnoreAuth ignore;
if (handler instanceof HandlerMethod) {
ignore = ((HandlerMethod) handler).getMethodAnnotation(IgnoreAuth.class);
} else {
return true;
}
String token = request.getHeader(HEADER_TOKEN);
if (ignore != null) {
return true;
}
TokenEntity tokenEntity = null;
if (token != null && !token.isEmpty()) {
tokenEntity = tokenService.findByToken(token);
}
if (tokenEntity != null) {
request.getSession().setAttribute("userId", tokenEntity.getUserId());
request.getSession().setAttribute("role", tokenEntity.getRole());
request.getSession().setAttribute("tableName", tokenEntity.getTableName());
request.getSession().setAttribute("username", tokenEntity.getUsername());
return true;
}
response.setContentType("application/json; charset=UTF-8");
response.setCharacterEncoding("UTF-8");
try (PrintWriter writer = response.getWriter()) {
writer.print(JSON.toJSONString(Response.error(401, "Autenticação necessária")));
}
return false;
}
}
Estrutura da Tabela (Exemplo)
-- Tabela de tokens
DROP TABLE IF EXISTS `token`;
CREATE TABLE `token` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`user_id` bigint(20) NOT NULL COMMENT 'ID do usuário',
`username` varchar(100) NOT NULL COMMENT 'Nome de usuário',
`table_name` varchar(100) DEFAULT NULL COMMENT 'Nome da tabela associada',
`role` varchar(100) DEFAULT NULL COMMENT 'Papel/função',
`token_value` varchar(200) NOT NULL COMMENT 'Valor do token',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Data de criação',
`expires_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'Data de expiração',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='Tabela de tokens de autenticação';
-- Dados de exemplo
INSERT INTO `token` VALUES (1, 23, 'cd01', 'xuesheng', 'estudante', 'exemplo123abc', '2023-02-23 21:46:45', '2023-03-15 14:01:36');
INSERT INTO `token` VALUES (2, 1, 'admin', 'users', 'administrador', 'tokenAdmin456', '2023-02-27 19:37:01', '2023-03-17 18:23:02');