基于SpringBoot+thymeleaf+mybatisPlus实现的个人博客系统

基于springboot和Themleaf实现的个人博客系统 1,项目简介 该项目试基于SpringBoot2,X+Thymeleaf 实现的完整博客系统

本文包含相关资料包-----> 点击直达获取<-------

基于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

相关推荐

发表回复

登录后才能评论