This project presents a complete movie and novel information website designed using SpringBoot, Vue (frontend), and UniApp (mobile). It includes full source code, deployment documentation, and an explanatory guide. The system supports user registration, content browsing, and admin management. It is suitable for learning full-stack development or as a graduation project reference.
Technical Stack
Backend Framework: SpringBoot
SpringBoot provides embedded servers like Tomcat, Jetty, and Undertow, enabling zero-configuration deployment. Its auto-configuration feature reduces manual setup by detecting dependencies in the classpath. The framework offers integrations with Spring Data, Spring Security, and Spring Cloud, speeding up development for scalable web applications. In this project, SpringBoot handles REST API creation, data persistence, and security.
Frontend Framework: Vue.js
Vue.js leverages a virtual DOM to optimize rendering performance. It supports reactive data binding, component-based architecture, and direct DOM manipulation when needed. This approach simplifies UI updates: when data changes, the view automatically refreshes without manual DOM handling. The result is a clean, maintainable frontend that separates logic from presentation.
Persistence Layer: MyBatis-Plus
MyBatis-Plus extends MyBatis with enhanced features such as automatic SQL generation, pagination, dynamic queries, optimistic locking, and performance analysis. It reduces boilerplate code by providing pre-built CRUD operations. The included code generator creates entity classes, Mapper interfaces, and XML mapping files from database tables. This speeds up development and ensures consistency across the data access layer.
System Testing
Testing Objectives
The primary goal of testing is to verify that the system meets functional requirements and operates without defects. Black-box testing is used to simulate user interactions across different modules. Test cases are designed to cover valid inputs, boundary values, and error handling. The process ensures that all features work correctly under expected usage patterns.
Functional Test Scenarios
Login Functionality: The login page validates credentials against the database. Test cases include correct credentials, wrong password, invalid captcha, and missing fields. The system displays appropriate error messages for each failure.
| Input Data | Expected Result | Actual Result | Outcome |
|---|---|---|---|
| Username: admin, Password: 123456, Captcha: correct | Successful login | Enters system | Pass |
| Username: admin, Password: 111111, Captcha: correct | Login fails, password error message | Shows "Password incorrect, please re-enter" | Pass |
| Username: admin, Password: 123456, Captcha: wrong | Login fails, captcha error message | Shows "Captcha error" | Pass |
| Username: (empty), Password: 123456, Captcha: correct | Mandatory field check | Shows "Please enter username" | Pass |
| Username: admin, Password: (empty), Captcha: corrrect | Mandatory field check | Shows "Please enter password" | Pass |
User Management: Tests cover adding, editing, deleting, and searching users. Key checks include empty required fields, duplicate usernames, and deletion confirmations.
| Input Action | Expected Result | Actual Result | Outcome |
|---|---|---|---|
| Fill all user details and submit | User added and visible in list | User appears in list | Pass |
| Modify existing user details | User updated with new information | Changes reflected in list | Pass |
| Delete an existing user | Confirmation dialog, then user removed | Confirmation shown, user removed | Pass |
| Add user with empty username | Username required error | Shows "Username cannot be empty" | Pass |
| Add user with duplicate username | Duplicate username error | Shows "Username already exists" | Pass |
Testing Conclusion
All functional tests passed. The system handles authentication, data validation, and user enteraction correctly. No critical defects were found. The application meets its design specifications and provides a stable user experience.
Code Sample
@IgnoreAuth
@PostMapping(value = "/login")
public R login(String username, String password, String captcha, HttpServletRequest request) {
UsersEntity user = userService.selectOne(new EntityWrapper<UsersEntity>().eq("username", username));
if(user==null || !user.getPassword().equals(password)) {
return R.error("Account or password incorrect");
}
String token = tokenService.generateToken(user.getId(), username, "users", user.getRole());
return R.ok().put("token", token);
}
@Override
public String generateToken(Long userid, String username, String tableName, String role) {
TokenEntity tokenEntity = this.selectOne(new EntityWrapper<TokenEntity>().eq("userid", userid).eq("role", role));
String token = CommonUtil.getRandomString(32);
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
cal.add(Calendar.HOUR_OF_DAY, 1);
if(tokenEntity != null) {
tokenEntity.setToken(token);
tokenEntity.setExpiratedtime(cal.getTime());
this.updateById(tokenEntity);
} else {
this.insert(new TokenEntity(userid, username, tableName, role, token, cal.getTime()));
}
return token;
}
/**
* Token-based authorization interceptor
*/
@Component
public class AuthorizationInterceptor implements HandlerInterceptor {
public static final String LOGIN_TOKEN_KEY = "Token";
@Autowired
private TokenService tokenService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// Handle CORS
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with,request-source,Token, Origin,imgType, Content-Type, cache-control,postman-token,Cookie, Accept,authorization");
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
if (request.getMethod().equals(RequestMethod.OPTIONS.name())) {
response.setStatus(HttpStatus.OK.value());
return false;
}
IgnoreAuth annotation;
if (handler instanceof HandlerMethod) {
annotation = ((HandlerMethod) handler).getMethodAnnotation(IgnoreAuth.class);
} else {
return true;
}
String token = request.getHeader(LOGIN_TOKEN_KEY);
if (annotation != null) {
return true;
}
TokenEntity tokenEntity = null;
if (StringUtils.isNotBlank(token)) {
tokenEntity = tokenService.getTokenEntity(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;
}
PrintWriter writer = null;
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
try {
writer = response.getWriter();
writer.print(JSONObject.toJSONString(R.error(401, "Please login first")));
} finally {
if (writer != null) {
writer.close();
}
}
return false;
}
}
Database Schema
-- Token table
DROP TABLE IF EXISTS `token`;
CREATE TABLE `token` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'Primary key',
`userid` bigint(20) NOT NULL COMMENT 'User ID',
`username` varchar(100) NOT NULL COMMENT 'Username',
`tablename` varchar(100) DEFAULT NULL COMMENT 'Table name',
`role` varchar(100) DEFAULT NULL COMMENT 'Role',
`token` varchar(200) NOT NULL COMMENT 'Token string',
`addtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Creation time',
`expiratedtime` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'Expiration time',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='Token table';
-- Sample token data
INSERT INTO `token` VALUES ('9', '23', 'cd01', 'xuesheng', 'Student', 'al6svx5qkei1wljry5o1npswhdpqcpcg', '2023-02-23 21:46:45', '2023-03-15 14:01:36');
INSERT INTO `token` VALUES ('10', '11', 'xh01', 'xuesheng', 'Student', 'fahmrd9bkhqy04sq0fzrl4h9m86cu6kx', '2023-02-27 18:33:52', '2023-03-17 18:27:42');
INSERT INTO `token` VALUES ('11', '17', 'ch01', 'xuesheng', 'Student', 'u5km44scxvzuv5yumdah2lhva0gp4393', '2023-02-27 18:46:19', '2023-02-27 19:48:58');
INSERT INTO `token` VALUES ('12', '1', 'admin', 'users', 'Admin', 'h1pqzsb9bldh93m92j9m2sljy9bt1wdh', '2023-02-27 19:37:01', '2023-03-17 18:23:02');
INSERT INTO `token` VALUES ('13', '21', 'xiaohao', 'shezhang', 'President', 'zdm7j8h1wnfe27pkxyiuzvxxy27ykl2a', '2023-02-27 19:38:07', '2023-03-17 18:25:20');
INSERT INTO `token` VALUES ('14', '27', 'djy01', 'xuesheng', 'Student', 'g3teq4335pe21nwuwj2sqkrpqoabqomm', '2023-03-15 12:56:17', '2023-03-15 14:00:16');
INSERT INTO `token` VALUES ('15', '29', 'dajiyue', 'shezhang', 'President', '0vb1x9xn7riewlp5ddma5ro7lp4u8m9j', '2023-03-15 12:58:08', '2023-03-15 14:03:48');
For the complete project, including database scripts, source code, and deployement instructions, please contact the author.