这个校园网站项目是为冀中工程技师学院开发的一套综合性网络平台,采用了前后端分离的架构设计。前端使用Django框架构建,后端基于Java技术栈的Spring+SpringMVC+Mybatis(SSM)组合。项目实现了学院信息展示、师生互动、资源管理等多种功能模块,为学院师生提供了一个便捷的数字化校园环境。
作为开发者,我在这个项目中主要负责技术选型、架构设计和核心功能实现。整个开发周期约3个月,期间遇到了不少技术挑战,特别是在前后端数据交互和权限控制方面。下面我将详细分享这个项目的技术实现细节和开发经验。
选择Django作为前端框架主要基于以下考虑:
实际开发中,我们主要使用了以下Django组件:
SSM框架组合是Java Web开发的经典选择:
选择SSM而非Spring Boot主要考虑到:
项目同时支持MySQL和SQLServer两种数据库:
这种双数据库支持的设计带来了以下好处:
系统采用典型的三层架构:
各层之间通过明确定义的接口进行通信,保证了系统的松耦合性。
系统主要包含以下功能模块:
每个模块都遵循单一职责原则,便于维护和扩展。
虽然项目整体不是严格的前后端分离架构,但我们仍然采用了RESTful风格的接口设计:
核心接口示例:
java复制@RestController
@RequestMapping("/api/news")
public class NewsController {
@Autowired
private NewsService newsService;
@GetMapping
public ResponseEntity<PageResult<News>> listNews(
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "10") int size) {
PageResult<News> result = newsService.getNewsList(page, size);
return ResponseEntity.ok(result);
}
@PostMapping
public ResponseEntity<News> createNews(@RequestBody News news) {
News created = newsService.createNews(news);
return ResponseEntity.status(HttpStatus.CREATED).body(created);
}
}
系统采用基于角色的访问控制(RBAC)模型:
权限配置示例:
java复制@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/teacher/**").hasAnyRole("TEACHER", "ADMIN")
.antMatchers("/**").permitAll()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/")
.and()
.logout()
.logoutSuccessUrl("/");
}
}
新闻模块实现了以下功能:
核心代码片段:
java复制@Service
public class NewsServiceImpl implements NewsService {
@Autowired
private NewsMapper newsMapper;
@Override
@Transactional
public News createNews(News news) {
// 设置默认值
if (news.getPublishTime() == null) {
news.setPublishTime(new Date());
}
news.setCreateTime(new Date());
news.setUpdateTime(new Date());
news.setViewCount(0);
newsMapper.insert(news);
return news;
}
@Override
public PageResult<News> getNewsList(int page, int size) {
PageHelper.startPage(page, size);
List<News> list = newsMapper.selectAll();
PageInfo<News> pageInfo = new PageInfo<>(list);
return new PageResult<>(
pageInfo.getTotal(),
pageInfo.getList()
);
}
}
校园风光模块特点:
留言板实现了:
敏感词过滤实现:
java复制public class SensitiveWordFilter {
private static final Set<String> sensitiveWords = new HashSet<>();
static {
// 初始化敏感词库
sensitiveWords.add("暴力");
sensitiveWords.add("色情");
// 可以从数据库或文件加载更多
}
public static String filter(String content) {
if (StringUtils.isEmpty(content)) {
return content;
}
for (String word : sensitiveWords) {
content = content.replaceAll(word, "***");
}
return content;
}
}
教师评价功能包括:
用户管理实现了:
密码加密采用MD5加盐:
java复制public class PasswordUtil {
private static final String SALT = "JZJSXY";
public static String encrypt(String password) {
return DigestUtils.md5DigestAsHex((SALT + password).getBytes());
}
public static boolean matches(String rawPassword, String encodedPassword) {
return encrypt(rawPassword).equals(encodedPassword);
}
}
数据字典功能:
sql复制CREATE TABLE `sys_user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL COMMENT '用户名',
`password` varchar(100) NOT NULL COMMENT '密码',
`real_name` varchar(50) DEFAULT NULL COMMENT '真实姓名',
`email` varchar(100) DEFAULT NULL COMMENT '邮箱',
`phone` varchar(20) DEFAULT NULL COMMENT '手机号',
`avatar` varchar(255) DEFAULT NULL COMMENT '头像',
`status` tinyint(1) DEFAULT '1' COMMENT '状态 0:禁用 1:正常',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统用户表';
sql复制CREATE TABLE `cms_news` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`title` varchar(100) NOT NULL COMMENT '标题',
`content` text COMMENT '内容',
`category_id` bigint(20) DEFAULT NULL COMMENT '分类ID',
`cover_image` varchar(255) DEFAULT NULL COMMENT '封面图',
`publish_time` datetime DEFAULT NULL COMMENT '发布时间',
`view_count` int(11) DEFAULT '0' COMMENT '浏览次数',
`status` tinyint(1) DEFAULT '0' COMMENT '状态 0:草稿 1:已发布',
`create_user_id` bigint(20) DEFAULT NULL COMMENT '创建人',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `idx_category` (`category_id`),
KEY `idx_publish_time` (`publish_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='新闻资讯表';
针对查询频繁的字段建立了索引:
采取的优化措施:
bash复制# 创建数据库
mysql -u root -p -e "CREATE DATABASE jzjsxy DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;"
# 导入初始数据
mysql -u root -p jzjsxy < init.sql
bash复制# 打包项目
mvn clean package -DskipTests
# 部署到Tomcat
cp target/jzjsxy.war $TOMCAT_HOME/webapps/
bash复制# 安装依赖
pip install -r requirements.txt
# 收集静态文件
python manage.py collectstatic
# 启动服务
python manage.py runserver 0.0.0.0:8000
主要配置文件:
properties复制# 数据源配置
spring.datasource.url=jdbc:mysql://localhost:3306/jzjsxy
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
# MyBatis配置
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.jzjsxy.entity
python复制DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'jzjsxy',
'USER': 'root',
'PASSWORD': '123456',
'HOST': 'localhost',
'PORT': '3306',
}
}
由于前后端分离部署,遇到了跨域问题。解决方案:
java复制@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.maxAge(3600);
}
}
javascript复制// vue.config.js
module.exports = {
devServer: {
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
}
}
}
针对大文件上传:
核心代码:
java复制@PostMapping("/upload")
public ResponseEntity<String> upload(
@RequestParam("file") MultipartFile file,
@RequestParam(value = "chunk", required = false) Integer chunk,
@RequestParam(value = "chunks", required = false) Integer chunks) {
try {
String fileName = file.getOriginalFilename();
String filePath = "/upload/" + fileName;
if (chunks != null && chunks > 1) {
// 分片上传处理
filePath += ".part" + chunk;
}
File dest = new File(filePath);
file.transferTo(dest);
if (chunks != null && chunk == chunks - 1) {
// 最后一个分片,合并文件
mergeFiles(fileName, chunks);
}
return ResponseEntity.ok("Upload success");
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("Upload failed: " + e.getMessage());
}
}
缓存策略:
数据库优化:
前端优化:
输入验证:
权限控制:
其他安全措施:
这个校园网站项目从技术选型到最终上线历时3个月,期间遇到了不少挑战,也积累了很多宝贵的经验。项目成功上线后,为学院师生提供了便捷的信息服务平台,获得了良好的用户反馈。
在技术层面,我们实现了:
未来可以考虑的改进方向:
这个项目的成功实施,不仅为学院信息化建设做出了贡献,也为类似教育机构网站的开发提供了可参考的案例。在开发过程中积累的技术方案和经验教训,都将成为未来项目开发的宝贵财富。