基于springboot和Themleaf实现的个人博客系统
1.项目简介
该项目试基于SpringBoot2.X+Thymeleaf 实现的完整博客系统。
部分的前端展示页面和css样式等借鉴了部分网络作者的开源项目,在此向其作者表示感谢!
因为博主的能力有限,重构计划一直拖后,但是对于自己项目的目标还是有的:未来计划后台采用vuejs,前台选用更加清晰的模板引擎,在整体的项目基础上实现前后端分离,使用Redis中间件做缓存。
1.1 博客特点
-
使用现如今流行的java语言及springboot框架开发,体系完整,结构清晰,是一套不错的学习项目
-
整体的后端开发模式使用MVC,分层清楚,逻辑清楚,适合学者参考学习
-
在博客的文档编辑、博客目录的生成与展示等地方使用了开源插件,实现了动态的js和对于makedown文档的编辑支持,整体上符合现如今流行的博客编辑器。
1.2 功能介绍
本博客系统基于 SpringBoot 2.x,支持快速开发,部署,服务器采用tomcat。
数据库采用常见的关系型数据库Mysql,ORM框架采用JPA
模板引擎采用Thymeleaf (对于为何使用Thymeleaf 作为模板引擎,可以阅读此文章为何选择Thymeleaf),由于精力及能力有限没有采用vue,在后期更新中考虑后台改为vue实现,敬请期待!
博客功能导图
1.3 整体功能
前台部分
-
首页:展示博客、展示所有的分类及标签、点击进入博客详情
-
分类:类型对博客进行划分并分别展示
-
标签:按标签对博客进行划分与展示
-
时间轴:根据文章发布的时间形成一个时间轴
-
照片墙: 记录自己的生活
-
归档:整体按照年份对博客进行归档,可以进行博客内容查询
-
关于我:展示博主有关信息
后台部分(管理员部分)
-
博客管理:实现博客的增删改查
-
分类管理:实现分类的增删改查
-
标签管理:实现标签的增删改查
整体架构
博客系统整体分层如下:
1.4 页面预览
2.数据库设计
2.1 表结构
文章表
评论表
消息表
照片表
分类表
用户表
2.2 E-R图
3.准备工作
两个星期前,我想做一个博客。于是找到资料,并开始搬砖。
- Spring学习 :理解IOC(控制反转)和AOP(面向切面编程)
-
https://blog.csdn.net/qq_22583741/article/details/79589910
-
Maven学习 :添加依赖,坐标定义(groupId,artifactId,version),pom基本配置
-
https://blog.csdn.net/weisg81/article/details/76795190
-
SpringBoot学习 :采用gradle框架,和Maven一样是自动构建工具。一样是采用SpringMVC的设计模式
-
https://blog.csdn.net/qq_22860341/article/details/79173580
-
Themleaf学习 :前端框架
-
https://blog.csdn.net/u012706811/article/details/52185345
-
Spring Data jpa :已封装好增删改查的方法,可以直接调用
- https://blog.csdn.net/tyyytcj/article/details/76281836
4.项目实现
4.1 controller包
包括管理员,博客,分类,评论,主页,用户,用户主页,点赞这八大块功能的实现。
java
@Controller
@RequestMapping("/admin")
public class BlogController {
@Autowired
private BlogService blogService;
@Autowired
private TypeService typeService;
//跳转到博客列表页
@GetMapping("/blogs")
public String blogs(Model model,
@RequestParam(defaultValue = "1",value = "pageNum") Integer pageNum){
String orderBy = "t_blog.update_time desc";
PageHelper.startPage(pageNum,10,orderBy);
List<Blog> allBlog = blogService.getAllBlog();
PageInfo<Blog> pageInfo = new PageInfo<>(allBlog);
model.addAttribute("pageInfo",pageInfo);
List<Type> allType = typeService.getAllType();
model.addAttribute("allType",allType);
return "admin/blogs";
}
//博客搜索
@PostMapping("/blogs/search")
public String blogsSearch(Model model,
@RequestParam(defaultValue = "1",value = "pageNum") Integer pageNum,
SearchBlog blog){
String orderBy = "t_blog.update_time desc";
PageHelper.startPage(pageNum,10,orderBy);
List<Blog> allBlog = blogService.getBlogByConditions(blog);
PageInfo<Blog> pageInfo = new PageInfo<>(allBlog);
model.addAttribute("pageInfo",pageInfo);
model.addAttribute("blogSearch",blog);
return "admin/blogs-search :: blogList";
}
//博客搜索-分页处理
@GetMapping("/blogs/search")
public String blogsSearchPage(Model model,
@RequestParam(defaultValue = "1",value = "pageNum") Integer pageNum,
SearchBlog blog ){
String orderBy = "t_blog.update_time desc";
PageHelper.startPage(pageNum,10,orderBy);
List<Blog> allBlog = blogService.getBlogByConditions(blog);
PageInfo<Blog> pageInfo = new PageInfo<>(allBlog);
model.addAttribute("pageInfo",pageInfo);
model.addAttribute("blogSearch",blog);
// return "admin/blogs-search :: blogList";
return "admin/blogs-search";
}
//新增博客页面跳转
@GetMapping("/blogs/input")
public String blogInput(Model model){
model.addAttribute("types",typeService.getAllType());
Blog blog = new Blog();
blog.setType(new Type());
model.addAttribute("blog",blog);
return "admin/blogs-input";
}
//博客编辑页面跳转
@GetMapping("/blogs/{id}/input")
public String blogEdit(Model model,@PathVariable Long id){
model.addAttribute("types",typeService.getAllType());
model.addAttribute("blog",blogService.getBlogById(id));
return "admin/blogs-input";
}
//新增操作
@PostMapping("/blogs")
public String post(Blog blog, HttpSession session, RedirectAttributes attributes){
User curUser = (User) session.getAttribute("user");
// blog.setUser(curUser);
blog.setUserId(curUser.getId());
// blog.setType(typeService.getTypeById(blog.getTypeId()));
int res = blogService.saveBlog(blog);
if(res == 0){
attributes.addFlashAttribute("message","提示:操作失败");
}else{
attributes.addFlashAttribute("message","提示:操作成功");
}
return "redirect:/admin/blogs";
}
//编辑操作
@PostMapping("/blogs/edit")
public String postEdit(Blog blog, HttpSession session, RedirectAttributes attributes){
User curUser = (User) session.getAttribute("user");
// blog.setUser(curUser);
blog.setUserId(curUser.getId());
// blog.setType(typeService.getTypeById(blog.getTypeId()));
int res = blogService.updateBlog(blog);
if(res == 0){
attributes.addFlashAttribute("message","提示:操作失败");
}else{
attributes.addFlashAttribute("message","提示:操作成功");
}
return "redirect:/admin/blogs";
}
//删除操作
@GetMapping("/blogs/{id}/delete")
public String deleteBlog(@PathVariable Long id){
blogService.deleteBlog(id);
return "redirect:/admin/blogs";
}
}
4.2 工具类
批量异常处理器
```java @ControllerAdvice //是一个拦截所有标有controller注解的控制器 public class ControllerExceptionHandler {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@ExceptionHandler(Exception.class)
public ModelAndView exceptionHandler(HttpServletRequest request,Exception e) throws Exception {
logger.error("Request URL : {}, Exception : {}",request.getRequestURL(),e);
if(AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null){
throw e;
}
ModelAndView mv = new ModelAndView();
mv.addObject("url",request.getRequestURL());
mv.addObject("exception",e);
mv.setViewName("error/error");
return mv;
}
```
加密工具
```java public class MD5Utils {
/**
* @Description: MD5加密
* @Auther: xlw
* @Date: 10:35 2020/3/27
* @Param: 要加密的字符串
* @Return: 加密后的字符串
*/
public static String code(String str){
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(str.getBytes());
byte[]byteDigest = md.digest();
int i;
StringBuffer buf = new StringBuffer("");
for (int offset = 0; offset < byteDigest.length; offset++) {
i = byteDigest[offset];
if (i < 0)
i += 256;
if (i < 16)
buf.append("0");
buf.append(Integer.toHexString(i));
}
//32位加密
return buf.toString();
// 16位的加密
//return buf.toString().substring(8, 24);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
}
}
```
Makrdown工具类
java
public class MarkdownUtils {
/**
* markdown格式转换成HTML格式
* @param markdown
* @return
*/
public static String markdownToHtml(String markdown) {
Parser parser = Parser.builder().build();
Node document = parser.parse(markdown);
HtmlRenderer renderer = HtmlRenderer.builder().build();
return renderer.render(document);
}
/**
* 增加扩展[标题锚点,表格生成]
* Markdown转换成HTML
* @param markdown
* @return
*/
public static String markdownToHtmlExtensions(String markdown) {
//h标题生成id
Set<Extension> headingAnchorExtensions = Collections.singleton(HeadingAnchorExtension.create());
//转换table的HTML
List<Extension> tableExtension = Arrays.asList(TablesExtension.create());
Parser parser = Parser.builder()
.extensions(tableExtension)
.build();
Node document = parser.parse(markdown);
HtmlRenderer renderer = HtmlRenderer.builder()
.extensions(headingAnchorExtensions)
.extensions(tableExtension)
.attributeProviderFactory(new AttributeProviderFactory() {
public AttributeProvider create(AttributeProviderContext context) {
return new CustomAttributeProvider();
}
})
.build();
return renderer.render(document);
}
/**
* 处理标签的属性
*/
static class CustomAttributeProvider implements AttributeProvider {
@Override
public void setAttributes(Node node, String tagName, Map<String, String> attributes) {
//改变a标签的target属性为_blank
if (node instanceof Link) {
attributes.put("target", "_blank");
}
if (node instanceof TableBlock) {
attributes.put("class", "ui celled table");
}
}
}
public static void main(String[] args) {
String table = "| hello | hi | 哈哈哈 |\n" +
"| ----- | ---- | ----- |\n" +
"| 斯维尔多 | 士大夫 | f啊 |\n" +
"| 阿什顿发 | 非固定杆 | 撒阿什顿发 |\n" +
"\n";
String a = "[ONESTAR](http://122.51.28.187:8080/)";
System.out.println(markdownToHtmlExtensions(a));
}
}
5.项目展示
5.1 前端
主页
首页底部
文章详情
评论
文章分类
时间轴
音乐盒
留言板
照片墙
关于我
5.2 后管
登录
主页
文章管理
发布文章
分类管理
相册管理
参考文献
- 基于SSH框架的企业内博客系统的设计与实现(山东大学·柳青)
- 基于SSH框架模式的博客系统的设计与实现(西北师范大学·王刚成)
- 博客管理系统的设计与实现(吉林大学·赵岩)
- 基于J2EE的辽油通信小灵通服务下载系统的设计与实现(电子科技大学·吴文哲)
- 基于Spring Boot的多用户博客系统的设计研究(青海师范大学·罗涛)
- 基于MD5改进算法的安全教师博客系统设计及开发(湖南大学·刘曼春)
- 基于MVC设计模式的博客系统的设计与实现(大连理工大学·侯林)
- 基于SSH的手机网站的设计与实现(东北大学 ·陶志刚)
- 基于SSH框架模式的博客系统的设计与实现(西北师范大学·王刚成)
- 基于OAuth2.0协议的企业分布式授权系统设计与实现(华中科技大学·支猛)
- 基于SSH框架的企业内博客系统的设计与实现(山东大学·柳青)
- 基于MD5改进算法的安全教师博客系统设计及开发(湖南大学·刘曼春)
- 基于MVC设计模式的博客系统的设计与实现(大连理工大学·侯林)
- 基于WEB2.0的教育博客应用与研究(北京化工大学·缪洪霞)
- 基于SSH架构的个人空间交友网站的设计与实现(北京邮电大学·隋昕航)
本文内容包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主题。发布者:毕设客栈 ,原文地址:https://m.bishedaima.com/yuanma/35469.html