之前做的人工智能和深度学习方向的期末课题一直想写博客记录一下来着,无奈时间安排上的不足未曾实现,分别是基于深度学习的图像识别系统和基于YOLOv3的人体口罩佩戴检测系统,如果大家感兴趣的话可以找我一起聊聊。转入正题,大四之前的想法一直都是想做关于深度学习的毕设课题,但在大学期间对于深度学习一直了解较为丰富,反而对于Java项目开发略显笨拙,抱着想接触这方面知识的想法确定了自己要做Java Web项目,进而我是一个对电影很感兴趣的人,无聊或者没事做又或者作为奖励都会去看一部电影,本人一般比较喜欢看治愈系的,但其他类型的也都有很喜欢的电影,所以最后确定的毕设课题为:基于SpringBoot的电影荐评系统。
对于Java Web开发工程的学习方面来说,如果希望可以快速上手的同学推荐在B站学习狂神说的视频,我个人觉得是我看的为数不多的教学视频里面干货多、好上手的教学视频。在项目开发前期对于Java语言一定要有一定程度上的积累,否则看狂神说的视频会有些吃力,建议一定要有一定程度上的积累。
对于数据库的知识也要进行学习,在对数据库的增删改查的操作较为简单,如果涉及较为复杂的数据库操作还是需要数据库相关知识的积累。此外,如果对数据库操作语言熟悉会减少很多Java代码的编写,因为在编程过程中会发现有些数据库语言完成的工作完全可以代替大量关于数据处理的Java代码。
关于IDEA的安装很简单,不必过于担忧,在CSDN上查找一些IDEA的安装教程进行安装即可,这里就不做赘述。下面是我用到IDEA2019的安装包,需要的话进行下载即可。
链接:https://pan.baidu.com/s/1oxEspRmcSNPa90VeDYh3hQ
提取码:9ccp
还有JDK(jdk1.8)的安装包也附上如下链接。
链接:https://pan.baidu.com/s/1KhBlCwxuKSWgObMcdoM1NQ
提取码:02av
项目开发中数据库我用的是mysql,关于mysql的安装问题较多,大家安装mysql5.7就可以,查找相关安装教程进行安装,在安装出现问题的时候根本报错进行解决就好。以下是我用到的安装包。
链接:https://pan.baidu.com/s/1XJKfRou0-A424S3qYV2yiQ
提取码:4gbh
对于mysql在cmd中操作不熟悉的同学可以下载navicat进行可视化操作,这样较为方便一些,对cmd命令操作熟悉的同学就不用了。Navicat安装包如下。
链接:https://pan.baidu.com/s/1x1C12_rxUpvsBn-PhhrU9g
提取码:kaxc
学习SpringBoot项目的开发和构建过程,其构建方法有三种:1.使用IDEA构建SpringBoot项目;2.在SpringBoot官网上构建项目;3.手动构建项目;三种方法里只有第一种方法较为便捷。
这是我在开发过程中用到的较好的教程大家可以参考一下,先初步构建一个简单的SpringBoot项目,了解SPringleBoot项目机制和构建的大致流程。
https://blog.csdn.net/qq_43006591/article/details/106137465?utm_term=%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AAspringboot%E9%A1%B9%E7%9B%AE%E7%9A%84%E6%AD%A5%E9%AA%A4&utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2allsobaiduweb~default-1-106137465&spm=3001.4430
简单来讲,构建静态资源就是先建立好可使用的Web静态网页。就个人理解来说,相当于先将项目的外包装搭建好,就是项目展现时的可视化界面先搭建出来,后期再一步一步完善。
对于构建静态资源来说,互联网上有很多可参考的静态网页,但需要很大程度上的修改才能完全构建出自己想要的前端界面,这就需要较多的Web前端知识来支撑,例如基础的HTML、CSS、JavaScript等语言,此外使用一些前端框架进行构建也较为方便。
在项目开发过程中,查阅了很多静态资源,也参考了很多,在搭建自己的静态页面的时候也耗费了大量时间和精力,不过我觉得毕竟是可视化的东西,第一时间展示给大家的就是页面,所以一定要认真对待,最起码要符合自己的审美,其次才会给大家带来好的用户感受。
以下是我查询资源时用到的静态资源网站,供大家参考:
Bootstrap网页模板:http://www.bootstrapmb.com/
Web项目中所用到的数据需要持久化存储,我们在之前安装了mysql,现在就要构建好项目需要用到的数据表、数据关系以及数据信息。
以下是我构建的数据库数据导出的SQL文件,链接如下。
链接:https://pan.baidu.com/s/1KNZko6XbO9oIXhqBrZnGBA
提取码:ia0j
简单SpringBoot的项目搭建、静态资源搭建和数据库数据构建完成之后,整个项目的重心要转到后端代码的编写上,此处建议大家认真观看狂神说的视频,对基本的登陆注册功能点进行实现之后,会对整个项目开发流程较为熟悉一些,此后就可以一步一步完成其他功能点。
狂神说的视频可以参考前后端数据传输的过程,但是对于传输到前端的数据格式以及前端如何处理数据大家可以查询参考一下AJAX技术,因为狂神说的视频是基于VUE实现的动态数据渲染,而本人项目开发对于前端数据处理使用AJAX技术和JavaScript实现的。
关于前后端的交互的部分代码实现会在主要功能点里有部分描述,有需要参考前后端是如何交互的可以看第四部分的内容。
当用户进入该系统时,默认显示网站前台首页,网站前台首页中的主要功能模块是为用户推荐热门和最新电影,视图层使用Thymeleaf中的模板语法将后端返回的热门电影和最新电影列表绑定到hot_movies和new_movies变量,进而使用JavaScript对页面中的内容进行动态渲染。前端核心代码实现如下所示。
window.onload = function () {
var new_list = [[${new_movies}]];
var hot_list = [[${hot_movies}]];
var new_html="";
var hot_html="";
for(i=0;i<8;i++){
new_html+="\n" +
"\t\t\t\t "+new_list[i].name+"div>\n" +
"\t\t\t\t div>\n\t\t\t\t 主演:"+new_list[i].actors+"div>\n\t\t\t div>a>";
hot_html+="\n" +
"\t\t\t\t "+hot_list[i].name+"div>\n" +
"\t\t\t\t div>\n\t\t\t\t 主演:"+hot_list[i].actors+"div>\n\t\t\t div>a>";
}
document.getElementById("newMoviesList").innerHTML=new_html;
document.getElementById("hotMoviesList").innerHTML=hot_html;
}
(3) 控制层实现
MovieController.java负责接收前端查询热门电影和最新电影的请求转到业务逻辑层中,核心代码实现如下所示。
@RequestMapping({
"/static/movies/index.html","/","/index","/movies/index.html"})
public String list(Model model){
List<MovieBean> new_movies = movieService.getNewMovies();
List<MovieBean> hot_movies = movieService.getHotMovies();
if(new_movies!=null){
model.addAttribute("new_movies",new_movies);
model.addAttribute("hot_movies",hot_movies);
return "movies/index";
}else {
return "movies/error";
}
}
(4) 业务逻辑层实现
MovieServiceImpl.java主要负责调用数据存取层的方法查询数据并返回,主要核心代码实现如下所示。
@Autowired
private MovieMapper movieMapper;
@Override
public List<MovieBean> getNewMovies() {
return movieMapper.getNewMovies();
}
@Override
public List<MovieBean> getHotMovies() {
return movieMapper.getHotMovies();
}
(5) 数据存取层实现
MovieMapper.xml 负责对热门电影和最新电影的面向数据库的查询操作,具体方法和代码如下所示。
<mapper namespace="com.example.movies_v1.mapper.MovieMapper">
<select id="getNewMovies" resultType="com.example.movies_v1.bean.MovieBean">
select * from tb_sys_film ORDER BY year DESC;
</select>
<select id="getHotMovies" resultType="com.example.movies_v1.bean.MovieBean">
select tb_sys_film.*, CAST(avg(score) AS decimal(18,1)) as score
from tb_sys_user_score, tb_sys_film
WHERE tb_sys_film.id = tb_sys_user_score.film_id
group by film_id
order by score DESC
</select>
</mapper>
2. 电影评价功能
(2) 视图层实现
电影评价功能是该系统的基本特色功能之一,用户在首页推荐电影或电影大厅中选择任意电影可以进入该电影的详情页,该页面向后端发送AJAX请求获取该电影信息和评论信息,进而使用JavaScript动态渲染该页面,该页面还有提交电影评价的功能实现,用户点击星星并输入评论内容可以对该电影进行评分及评论,电影详情页视图层的实现如图所示。
(3) 控制层实现
查询电影信息请求在控制层由 MovieController.java进行方法调用,提交评价请求在控制层由ScoreController.java接收数据并进行方法调用,其中部分方法的核心代码实现如下所示。
//查询电影信息
@ResponseBody
@RequestMapping("/movies/getFilmById")
public Result getFilmById(@RequestParam("film_id") Integer film_id){
try {
MovieBean film = movieService.getFilmById(film_id);
ScoreBean score = scoreService.getScoreByFilmId(film_id);
if(score!=null){
film.setScore(score.getScore());
}else{
film.setScore(0);
}
return new Result(2000,"获取电影信息成功!", film);
} catch (Exception e) {
e.printStackTrace();
}
return new Result(5000,"获取电影信息失败!");
}
//提交评价
@ResponseBody
@RequestMapping("/movies/submitScore")
public Result saveScore(@RequestParam("film_id") Integer film_id,
@RequestParam("user_id") Integer user_id,
@RequestParam("score") Integer score,
@RequestParam("remark") String remark) {
try {
Integer saveTrue = scoreService.saveScore(film_id, user_id, score, remark);
if (saveTrue==1){
return new Result(2000,"电影评分及评论提交成功!");
}else{
return new Result(2000,"电影评分及评论存储失败!");
}
} catch (Exception e) {
e.printStackTrace();
}
return new Result(5000,"提交失败!");
}
(4) 业务逻辑层实现
MovieServiceImpl.java和ScoreServiceImpl.java主要负责调用数据存取层的方法并返回操作结果,主要核心代码实现如下所示。
//查询电影信息
@Override
public MovieBean getFilmById(Integer film_id) {
return movieMapper.getFilmById(film_id);
}
//提交评价
@Override
public Integer saveScore(Integer film_id, Integer user_id, Integer score, String remark) {
return scoreMapper.saveScore(film_id, user_id, score, remark);
}
(5) 数据存取层实现
MovieMapper.xml 负责关于电影的面向数据库的具体操作,ScoreMapper.xml 负责关于电影评分的面向数据库的具体操作,核心代码如下所示。
// MovieMapper.xml
<mapper namespace="com.example.movies_v1.mapper.MovieMapper">
<select id="getFilmById" resultType="com.example.movies_v1.bean.MovieBean">
select * from tb_sys_film WHERE id = #{
film_id}
</select>
</mapper>
// ScoreMapper.xml
<mapper namespace="com.example.movies_v1.mapper.ScoreMapper">
<insert id="saveScore">
INSERT INTO tb_sys_user_score (film_id, user_id, score, remark, create_time)
VALUES (#{
film_id}, #{
user_id},#{
score},#{
remark},NOW())
</insert>
</mapper>
3. 未登录拦截功能
登录拦截功能主要是为了拦截非法人员强行进入后台管理从而破坏网站的数据和安全性。该功能可以有效拦截那些试图通过修改URL而进入需要管理员权限页面的恶性行为,仅有当管理员成功登录才可以进行一系列的后台管理操作,而当未登录的用户尝试行使管理员的权限时,系统会组织该用户的相关操作并跳转到后台登录界面,提示用户无权限进入。未登录拦截功能的顺序图如图所示。
(1) 前端实现
对未登录用户操作的拦截功能的设计主要是使用SpringBoot框架自带的拦截器来实现的,当用户发送关于后台管理的某请求,最先会被SpringBoot框架控制层的拦截器拦截,进而在拦截器中对用户提交的请求验证处理,最后按照验证结果进行不同的业务处理跳转到不同的页面。拦截功能的实现主要是使用SpringBoot框架中的Handler-Interceptor接口,重写preHandle方法,在该方法中定义拦截器的具体业务逻辑工作。核心代码如下所示。
public class LoginHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//登录成功之后,应该有用户的session:
Object manage_loginUser = request.getSession().getAttribute("manage_loginUser");
if(manage_loginUser==null){
//没有登陆
request.setAttribute("msg","没有权限,请先登录!");
//转发request
request.getRequestDispatcher("/manage/login.html").forward(request,response);
return false;
}else{
return true;
}
}
}
同时还需要通过继承SpringBoot中的WebMvcConfigurer类,定义需要采取权限拦截处理的特定操作,该功能主要是对后台管理中的相关操作权限进行验证,对其进行权限拦截,核心代码如下所示。
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginHandlerInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/","/movies/**","/manage/login",
"/manage/login.html","/static/manage/css/**",
"/static/manage/fonts/**",
"/static/manage/images/**","/static/manage/js/**");
}
4. 电影管理功能
管理员进入后台管理系统选择导航栏中的电影管理时,前端页面会向后端发送查询全部电影数据的请求并返回,前端使用JavaScript进行动态渲染页面,在该页面可以对电影进行添加、编辑、删除、查看电影海报等操作,电影管理的视图层实现如图所示。
当管理员进行编辑电影操作时,添加电影的视图层实现如图所示。
(3) 控制层实现
请求全部电影信息操作在控制层由 MovieController.java进行方法调用,其中部分方法的核心代码实现如下所示。
@ResponseBody
@RequestMapping("/movies/getAllMoviesByPage")
public Result getAllMoviesByPage(@RequestParam(defaultValue = "1",value = "pNum") Integer pNum, @RequestParam(defaultValue = "8",value = "pSize") Integer pSize){
try{
PageHelper.startPage(pNum,pSize);
List<MovieBean> moviesList = movieService.getAllMovies();
PageInfo<MovieBean> pageInfo = new PageInfo<MovieBean>(moviesList);
//pageInfo:将分页数据和显示的数据封装到PageInfo当中
return new Result(2000,"获取电影列表成功!", pageInfo);
}catch (Exception e){
e.printStackTrace();
}
return new Result(5000,"获取电影列表失败!");
}
(4) 业务逻辑层实现
MovieServiceImpl.java主要负责调用数据存取层的方法并返回操作结果,主要核心代码实现如下所示。
@Override
public List<MovieBean> getAllMovies() {
return movieMapper.getAllMovies();
}
@Override
public MovieBean getFilmById(Integer film_id) {
return movieMapper.getFilmById(film_id);
}
@Override
public Integer updateMovie(Integer id, String name, Integer category_id, String img, String director, String producer, String country, String actors, String language, String year, Integer length, String introduce) {
return movieMapper.updateMovie(id, name, category_id, img, director, producer, country, actors, language, year, length, introduce);
}
(5) 数据存取层实现
MovieMapper.xml 负责关于电影的面向数据库的具体操作,核心代码如下所示。
<mapper namespace="com.example.movies_v1.mapper.MovieMapper">
<select id="getAllMovies" resultType="com.example.movies_v1.bean.
MovieBean">
select * from tb_sys_film
</select>
</mapper>
五、总结
总的来说,毕设的完成在预期内。整个项目课题的开发过程中主要是前期和中期难点的时候较为难客服,当时觉得自己的毕设要Be了哈哈哈,后来还是顺利完成了,所以大家一定要加油呀,万事开头难,完成的时候会觉得自己很厉害的。
较为遗憾的一点是,由于自己在毕设前期的时间不贵充分,对于我自己来说我是想将自己接触较多的深度学习可以和本次课题结合,后期没有实现也是一个遗憾的地方,后面有时间的话可以进行优化。
自己的想法就是在网页首页增加猜你喜欢的板块,根据用户的评分和个人喜好通过算法输出用户可能会喜欢的电影TOP5进行推荐,当然我希望它的实现是人工智能而不是人工智障嘻嘻。
行文至此,谢谢你的阅读。生活愉快。