使用IntelliJ IDEA開發SpringMVC網站(五)博客文章管理

轉載請註明出處:Gaussic 。css

注:在閱讀本文前,請先閱讀:html

使用IntelliJ IDEA開發SpringMVC網站(一)開發環境前端

使用IntelliJ IDEA開發SpringMVC網站(二)框架配置html5

使用IntelliJ IDEA開發SpringMVC網站(三)數據庫配置java

使用IntelliJ IDEA開發SpringMVC網站(四)用戶管理jquery

訪問GitHub下載最新源碼:https://github.com/gaussic/SpringMVCDemogit

8、博客文章管理

        博客的管理與用戶的管理有許多的類似之處,可是另外多了外鍵的操做,下面作簡單的說明。github

一、查看文章

        查看文章的操做相對簡單。首先在com.gaussic.repository中添加BlogRepository,方法與UserRepository相似:web

package com.gaussic.repository;

import com.gaussic.model.BlogEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface BlogRepository extends JpaRepository<BlogEntity, Integer> {
}

        在com.gaussic.controller中添加一個BlogController類,並添加如下方法(固然也能夠寫在MainController中,在較大型的項目開發中,最好對各種的操做進行一個區分,以加強代碼的可讀性):spring

package com.gaussic.controller;

import com.gaussic.model.BlogEntity;
import com.gaussic.repository.BlogRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.List;

@Controller
public class BlogController {

    @Autowired
    BlogRepository blogRepository;
    
    // 查看全部博文
    @RequestMapping(value = "/admin/blogs", method = RequestMethod.GET)
    public String showBlogs(ModelMap modelMap) {
        List<BlogEntity> blogList = blogRepository.findAll();
        modelMap.addAttribute("blogList", blogList);
        return "admin/blogs";
    }
}

        接下來,在pages/admin目錄下新建blogs.jsp文件:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3個meta標籤*必須*放在最前面,任何其餘內容都*必須*跟隨其後! -->
 <title>SpringMVC 博客管理</title>

    <!-- 新 Bootstrap 核心 CSS 文件 -->
 <link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css">

    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
    <script src="//cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="//cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
</head>
<body>
<div class="container">
    <h1>SpringMVC 博客系統-博客管理</h1>
    <hr/>

    <h3>全部博客 <a href="/admin/blogs/add" type="button" class="btn btn-primary btn-sm">添加</a></h3>

    <!-- 若是用戶列表爲空 -->
 <c:if test="${empty blogList}">
        <div class="alert alert-warning" role="alert">
            <span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>Blog表爲空,請<a href="/admin/blogs/add" type="button" class="btn btn-primary btn-sm">添加</a>
        </div>
    </c:if>

    <!-- 若是用戶列表非空 -->
 <c:if test="${!empty blogList}">
        <table class="table table-bordered table-striped">
            <tr>
                <th>ID</th>
                <th>標題</th>
                <th>做者</th>
                <th>發佈日期</th>
                <th>操做</th>
            </tr>

            <c:forEach items="${blogList}" var="blog">
                <tr>
                    <td>${blog.id}</td>
                    <td>${blog.title}</td>
                    <td>${blog.userByUserId.nickname}, ${blog.userByUserId.firstName} ${blog.userByUserId.lastName}</td>
                    <td><fmt:formatDate value="${blog.pubDate }" pattern="yyyy-MM-dd"/></td>
                    <td>
                        <a href="/admin/blogs/show/${blog.id}" type="button" class="btn btn-sm btn-success">詳情</a>
                        <a href="/admin/blogs/update/${blog.id}" type="button" class="btn btn-sm btn-warning">修改</a>
                        <a href="/admin/blogs/delete/${blog.id}" type="button" class="btn btn-sm btn-danger">刪除</a>
                    </td>
                </tr>
            </c:forEach>
        </table>
    </c:if>
</div>

<!-- jQuery文件。務必在bootstrap.min.js 以前引入 -->
<script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>

<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</body>
</html>

        先不要急着運行代碼,咱們來看看blogs.jsp與users.jsp有何不一樣。

        注意到,在查看博文做者的時候,使用了以下代碼:

<td>${blog.userByUserId.nickname}, ${blog.userByUserId.firstName} ${blog.userByUserId.lastName}</td>

        也就是說,經過blog的userByUserId對象,找到了博文的做者,而且輸出了他的暱稱以及姓名。在這裏,外鍵起到了決定性的做用。下面咱們運行Tomcat,瀏覽器中輸入http://localhost:8080/admin/blogs,能夠看到以下界面:

二、添加博客       

 固然,如今數據庫中是沒有數據的,不用着急,咱們先實現博文的添加功能。回到BlogController,添加addBlog的GET和POST操做:

package com.gaussic.controller;

import com.gaussic.model.BlogEntity;
import com.gaussic.model.UserEntity;
import com.gaussic.repository.BlogRepository;
import com.gaussic.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.List;

@Controller
public class BlogController {

    @Autowired
    BlogRepository blogRepository;

    @Autowired
    UserRepository userRepository;

    // 查看全部博文
    @RequestMapping(value = "/admin/blogs", method = RequestMethod.GET)
    public String showBlogs(ModelMap modelMap) {
        List<BlogEntity> blogList = blogRepository.findAll();
        modelMap.addAttribute("blogList", blogList);
        return "admin/blogs";
    }


    // 添加博文
    @RequestMapping(value = "/admin/blogs/add", method = RequestMethod.GET)
    public String addBlog(ModelMap modelMap) {
        List<UserEntity> userList = userRepository.findAll();
        // 向jsp注入用戶列表
        modelMap.addAttribute("userList", userList);
        return "admin/addBlog";
    }

    // 添加博文,POST請求,重定向爲查看博客頁面
    @RequestMapping(value = "/admin/blogs/addP", method = RequestMethod.POST)
    public String addBlogPost(@ModelAttribute("blog") BlogEntity blogEntity) {
        // 打印博客標題
        System.out.println(blogEntity.getTitle());
        // 打印博客做者
        System.out.println(blogEntity.getUserByUserId().getNickname());
        // 存庫
        blogRepository.saveAndFlush(blogEntity);
        // 重定向地址
        return "redirect:/admin/blogs";
    }
}

       接下來,在pages/admin目錄下新建addBlog.jsp文件:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3個meta標籤*必須*放在最前面,任何其餘內容都*必須*跟隨其後! -->
 <title>SpringMVC 添加博客</title>

    <!-- 新 Bootstrap 核心 CSS 文件 -->
 <link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css">

    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
    <script src="//cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="//cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
</head>
<body>
<div class="container">
    <h1>SpringMVC 添加博客</h1>
    <hr/>
    <form:form action="/admin/blogs/addP" method="post" commandName="blog" role="form">
        <div class="form-group">
            <label for="title">Title:</label>
            <input type="text" class="form-control" id="title" name="title" placeholder="Enter Title:"/>
        </div>
        <div class="form-group">
            <label for="userByUserId.id">Author:</label>
            <select class="form-control" id="userByUserId.id" name="userByUserId.id">
                <c:forEach items="${userList}" var="user">
                    <option value="${user.id}">${user.nickname}, ${user.firstName} ${user.lastName}</option>
                </c:forEach>
            </select>
        </div>
        <div class="form-group">
            <label for="content">Content:</label>
            <textarea class="form-control" id="content" name="content" rows="3" placeholder="Please Input Content"></textarea>
        </div>
        <div class="form-group">
            <label for="pubDate">Publish Date:</label>
            <input type="date" class="form-control" id="pubDate" name="pubDate"/>
        </div>
        <div class="form-group">
            <button type="submit" class="btn btn-sm btn-success">提交</button>
        </div>
    </form:form>
</div>

<!-- jQuery文件。務必在bootstrap.min.js 以前引入 -->
<script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>

<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</body>
</html>

      講解:

        (1)首先在做者一欄使用了選擇框,經過select來選擇該博文的做者,注意到select標籤的id和name都是userByUserId.id(id能夠不一樣,但name必須如此),也就是說,須要經過blog的外鍵來定位到所須要選擇的做者。而在其選項組中,使用user.id來進行賦值,這樣,就能把blog和user表相關聯,是否是很方便呢?

        (2)Content處使用了textarea標籤,關於文中的一些標籤的用法能夠參照Bootstrap中文官網(沒有Bootstrap實在不會寫前端。。),注意因爲數據表的限制,請將字數保存在255如下。固然也能夠把數據表中的字段改成TEXT,以支持更長的輸入。

        (3)發佈日期的選取,採用了最簡單的H5 date控件,有興趣作成選擇框的話,能夠引入Bootstrap Datetimepicker,這是一個比較好的組件,但不是本文的重點,在此使用最簡單的。點擊其右方的下三角,能夠選擇日期,也能夠直接輸入:

 

        說了真麼多,咱們來重啓一下Tomcat,點擊博客管理界面的添加按鈕,添加如下內容:

      注意Author是一個select選框,以下圖所示,(若是選項不多效果不太好的話,請自行到用戶管理界面多添加幾個用戶再來):

       點擊提交,系統從新跳轉到了博客管理界面,這裏已經顯示出了所添加的博客列表:

三、查看博文詳情

       有了前面的基礎,這個就很好實現了,很少說,趁熱打鐵,在BlogController中添加以下方法:

// 查看博文詳情,默認使用GET方法時,method能夠缺省
@RequestMapping("/admin/blogs/show/{id}")
public String showBlog(@PathVariable("id") int id, ModelMap modelMap) {
    BlogEntity blog = blogRepository.findOne(id);
    modelMap.addAttribute("blog", blog);
    return "admin/blogDetail";
}

       在pages/admin目錄下新建文件blogDetail.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3個meta標籤*必須*放在最前面,任何其餘內容都*必須*跟隨其後! -->
 <title>SpringMVC 博文詳情</title>

    <!-- 新 Bootstrap 核心 CSS 文件 -->
 <link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css">

    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
    <script src="//cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="//cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
</head>
<body>
<div class="container">
    <h1>SpringMVC 博文詳情</h1>
    <hr/>

    <table class="table table-bordered table-striped">
        <tr>
            <th>ID</th>
            <td>${blog.id}</td>
        </tr>
        <tr>
            <th>Title</th>
            <td>${blog.title}</td>
        </tr>
        <tr>
            <th>Author</th>
            <td>${blog.userByUserId.nickname}, ${blog.userByUserId.firstName} ${blog.userByUserId.lastName}</td>
        </tr>
        <tr>
            <th>Content</th>
            <td>${blog.content}</td>
        </tr>
        <tr>
            <th>Publish Date</th>
            <td><fmt:formatDate value="${blog.pubDate}" pattern="yyyy年MM月dd日"/></td>
        </tr>
    </table>
</div>

<!-- jQuery文件。務必在bootstrap.min.js 以前引入 -->
<script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>

<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</body>
</html>

        注意:在輸出日期的時候使用了fmt標籤,請在頂部引入fmt標籤。

        如今重啓服務器,進入博客管理頁面,點擊剛纔添加的博文的詳情按鈕,查看該博文的詳情:

四、修改博客內容

      寫完了增長和查看的操做,如今實現修改的操做,內容依舊與用戶操做相似。首先,在BlogRepository中添加以下代碼:

// 修改博文操做
@Modifying
@Transactional
@Query("update BlogEntity blog set blog.title=:qTitle, blog.userByUserId.id=:qUserId," +
        " blog.content=:qContent, blog.pubDate=:qPubDate where blog.id=:qId")
void updateBlog(@Param("qTitle") String title, @Param("qUserId") int userId, @Param("qContent") String content,
                @Param("qPubDate") Date pubDate, @Param("qId") int id);

          接下來,在BlogController中添加修改博文的GET和POST方法:

// 修改博文內容,頁面
@RequestMapping("/admin/blogs/update/{id}")
public String updateBlog(@PathVariable("id") int id, ModelMap modelMap) {
    // 是否是和上面那個方法很像
    BlogEntity blog = blogRepository.findOne(id);
    List<UserEntity> userList = userRepository.findAll();
    modelMap.addAttribute("blog", blog);
    modelMap.addAttribute("userList", userList);
    return "admin/updateBlog";
}

// 修改博客內容,POST請求
@RequestMapping(value = "/admin/blogs/updateP", method = RequestMethod.POST)
public String updateBlogP(@ModelAttribute("blogP") BlogEntity blogEntity) {
    // 更新博客信息
    blogRepository.updateBlog(blogEntity.getTitle(), blogEntity.getUserByUserId().getId(),
            blogEntity.getContent(), blogEntity.getPubDate(), blogEntity.getId());
    blogRepository.flush();
    return "redirect:/admin/blogs";
}

        新建updateBlog.jsp頁面:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3個meta標籤*必須*放在最前面,任何其餘內容都*必須*跟隨其後! -->
 <title>SpringMVC 修改博客</title>

    <!-- 新 Bootstrap 核心 CSS 文件 -->
 <link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css">

    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
    <script src="//cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="//cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
</head>
<body>
<div class="container">
    <h1>SpringMVC 修改博客</h1>
    <hr/>
    <form:form action="/admin/blogs/updateP" method="post" commandName="blogP" role="form">
        <div class="form-group">
            <label for="title">Title:</label>
            <input type="text" class="form-control" id="title" name="title" placeholder="Enter Title:" value="${blog.title}"/>
        </div>
        <div class="form-group">
            <label for="userByUserId.id">Author:</label>
            <select class="form-control" id="userByUserId.id" name="userByUserId.id">
                <c:forEach items="${userList}" var="user">
                    <c:if test="${user.id==blog.userByUserId.id}">
                        <option value="${user.id}" selected="selected">${user.nickname}, ${user.firstName} ${user.lastName}</option>
                    </c:if>
                    <c:if test="${user.id!=blog.userByUserId.id}">
                        <option value="${user.id}">${user.nickname}, ${user.firstName} ${user.lastName}</option>
                    </c:if>
                </c:forEach>
            </select>
        </div>
        <div class="form-group">
            <label for="content">Content:</label>
            <textarea class="form-control" id="content" name="content" rows="3"
 placeholder="Please Input Content">${blog.content}</textarea>
        </div>
        <div class="form-group">
            <label for="pubDate">Publish Date:</label>
            <input type="date" class="form-control" id="pubDate" name="pubDate"
 value="<fmt:formatDate value="${blog.pubDate }" pattern="yyyy-MM-dd"/>"/>
        </div>
        <!-- 把 id 一併寫入 blogP 中 -->
 <input type="hidden" id="id" name="id" value="${blog.id}"/>
        <div class="form-group">
            <button type="submit" class="btn btn-sm btn-success">提交</button>
        </div>
    </form:form>
</div>

<!-- jQuery文件。務必在bootstrap.min.js 以前引入 -->
<script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>

<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</body>
</html>

       注:感謝某位同窗的指出,這裏pubDate的輸出如圖下圖所示:  

       重啓服務器,進入修改博客頁面,作出必定的修改:

        點擊提交, 返回博客列表頁面,能夠查看修改。

五、刪除博客文章

       刪除博客的實現很是簡單,在BlogController下加入如下方法:

// 刪除博客文章
@RequestMapping("/admin/blogs/delete/{id}")
public String deleteBlog(@PathVariable("id") int id) {
    blogRepository.delete(id);
    blogRepository.flush();
    return "redirect:/admin/blogs";
}

      重啓服務器,隨便添加一篇新的文章,而後刪除之:

       點擊刪除按鈕,刪除第二篇文章,將返回博客管理界面:

9、尾聲        

        這樣,整個博客的增刪改查操做就完成了,而這一系列的文章也即將接近尾聲。還有許多的細節是能夠優化的,SpringMVC還有許多優化代碼的小技巧,能讓你在開發時加省力,這一點是要在咱們的學習和使用中去探索和思考的,特別做爲一個WEB開發人員,探索和思考的能力是寶貴的。

        在此,還有一些小的事情須要交代,讓我一一道來。

一、如何部署

        在項目的目錄下,IntelliJ IDEA生成了一個target文件夾,以下圖所示:

        而springmvcdemo就是生成好的項目,咱們把這個項目放到Tomcat的webapps目錄下,而後啓動Tomcat,訪問 http://localhost:8080/springmvcdemo 就能夠看到網站。

二、進一步的學習

        若是本文知足不了你的需求,你還須要許多更高級的操做,那麼就應該查查文檔了,訪問 http://projects.spring.io/spring-framework/ 能夠查看springmvc的詳細文檔,按照所使用的版本進行查閱。在 http://spring.io/projects 中還有許多其餘的Spring框架,好比比較流行的Spring BOOT框架,以及本文中用到的Spring Data框架等。

         關於Bootstrap,在前端開發上面,離了Bootstrap我還真難寫出了像樣的前端來,固然爲了成爲一個出色的 Full Stack Developer,會一點HTML+CSS+JS那確定是有必要的。我維護過PHP的項目,開發過Django的項目,SpringMVC的項目也作了很多,甚至乎用Node.js搭建博客等都有必定的涉獵,這些項目不管哪個都離不開前端知識的支持。若是對前端不太瞭解,又想速成的話,建議上Bootstrap中文官網看看教程。

三、ENDING

        若是你對這幾篇文章有什麼問題、意見、或者建議的話,歡迎訪問個人GitHub博客提出,我會在空餘時間幫助你們解答。

        近日新開了我的博客,歡迎訪問:http://gaussic.top/ 。

相關文章
相關標籤/搜索