Spring boot开源项目之个人博客(15)—博客详情页面展示

Spring boot开源项目之个人博客(15)—博客详情页面展示

博客详情页分为两个部分,一个是博客详情信息的渲染,一个是评论功能。在这之前,做了一个全局搜索的功能。

1. 全局搜索

在导航栏有一个搜索框,定义搜索的功能是输入字段查找标题和内容中包含字段的博客,然后把符合条件的博客分页展示。

简单处理一下页面,粘贴之前博客列表中的div,就省去了再写theamleaf去渲染了,主要内容是根据搜索字段查找符合条件的博客。从前端开始看

<form action="#" name="search" th:action="@{/search}" method="post">
    <div class="ui icon input">
        <input type="text" placeholder="search..." name="query" th:value="${query}">
        <i onclick="document.search.submit()" class="search link icon"></i>
    </div>
</form>

用form包裹搜索框,post方式提交,给icon图标定义点击事件,通过name定位到表单,点击则提交,输入框则向后台推一个query字符串,还需要后端处理完之后,跳转页面再把query传回来并将其值渲染在搜索框里。

后台controller方法

@PostMapping("/search")
public String search(@PageableDefault(size = 6, sort = {
   "updateTime"}, direction = Sort.Direction.DESC) Pageable pageable,
                     Model model, @RequestParam String query){
   
    model.addAttribute("page", blogService.listBlog("%" +query+ "%", pageable));
    model.addAttribute("query", query);
    return "search";
}

@RequestParam String query取出前端传来的搜索条件字符串,controller里主要是把查找到的数据推到前端。

service层

@Override
public Page<Blog> listBlog(String query, Pageable pageable) {
   
    return blogRepository.findBlogByQuery(query, pageable);
}

把搜索条件和pageable对象传入dao层,在数据库层面查找数据,因为需要分页,需要返回Page<Blog>类型,这个要注意,否则前端会取不到值。

dao层

@Query("select b from Blog b where b.title like ?1 or b.content like ?1")
Page<Blog> findBlogByQuery(String query, Pageable pageable);

通过@Query自定义语句进行条件查找,like ?1表示对第一个参数进行like查找,另外,sql的like查询的条件字段是有特定格式的:”%内容%“,在字段左右需要加一个“%”,前端传来的是字符串,所以需要进行拼接,这个工作是在controller层完成的。

这样,整个功能就完成了,当输入搜索条件点击搜索时,就会跳转到新的搜索结果页面,博客列表分页展示。

2. 博客内容处理

这部分和列表差不多,先通过id找到对应的博客对象,然后推到前端使用theamleaf渲染页面,需要记录的是博客内容部分的处理。

博客内容在数据库里是以带Markdown语法的文本格式存储的,显然,直接取出来渲染到页面上,格式就全乱了,所以必须把Markdown语法格式的文本转化成HTML格式的文本,而且也不希望改变数据库的内容,因为博客的编辑也需要提取内容,那里是需要Markdown语法格式的。此外,我们有生成目录的插件,表格还希望采用semantic的ui样式,文章中的a标签链接也希望点击之后打开新的页面,这时,就需要一个灵活方便的Markdown转HTML的插件,在对内容格式进行转化之后,还能进行一些定制化操作。

首先,引入依赖

<!--markdown转html插件-->
<dependency>
    <groupId>com.atlassian.commonmark</groupId>
    <artifactId>commonmark</artifactId>
    <version>0.10.0</version>
</dependency>
<dependency>
    <groupId>com.atlassian.commonmark</groupId>
    <artifactId>commonmark-ext-heading-anchor</artifactId>
    <version>0.10.0</version>
</dependency>
<dependency>
    <groupId>com.atlassian.commonmark</groupId>
    <artifactId>commonmark-ext-gfm-tables</artifactId>
    <version>0.10.0</version>
</dependency>

第一个是功能的核心,实现Markdown转html,下面两个是为了实现header和table的定制化而导入的。

controller层

@GetMapping("/blog/{id}")
public String blog(@PathVariable Long id, Model model){
   
    model.addAttribute("blog", blogService.getAndInvertBlog(id));
    return "blog";
}

根据id查找对应的博客对象,并在service层对博客对象的内容进行处理,再推到前端渲染。

service层

@Override
public Blog getAndInvertBlog(Long id) {
   
    Blog blog = blogRepository.getOne(id);
    if (blog == null){
   
        throw new NotFoundException("该博客不存在");
    }
    Blog b = new Blog();
    BeanUtils.copyProperties(blog, b);
    String content = b.getContent();
    b.setContent(MarkdownUtils.markdownToHtmlExtensions(content));
    return b;
}

先根据id取出博客对象,这里将取出的对象的值赋给new出的博客对象,这么做的原因是如果直接对原对象进行set操作会改变数据库的内容。然后定义了一个工具类,将Markdown转化为html,并做一些定制化的扩展功能。

public class MarkdownUtils {
   

    /*
    *markdown格式转换成HTML格式
     */
    public static String markdownToHtml(String markdown){
   
        Parser parser = Parser.builder().build();
        org.commonmark.node.Node docoment = parser.parse(markdown);
        HtmlRenderer renderer = HtmlRenderer.
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值