Starting from 0, the first Spring Boot project (javaweb personal blog system) Spring Boot + thymeleaf article list display

review
In the previous article, we implemented the layout and publishing function of the article publishing page. There are some problems in it. In this article, we solved the problems and started to display the article list.

1 effect preview

1.1 writing articles

After logging in successfully, we click write article to enter the writing page

1.2 post

Click publish after writing.

1.3 article list page

After successful publishing, you will jump to the home page to display the article list information, as follows:

2. Specific implementation process

2.1 article list picture

Before that, we ignored the display of the publisher's Avatar and other attributes. This time, we added avatar URL fields in github User.java and User.java respectively. At the same time, we added avatar URL columns in the user table of the database. When we log in for the first time, we will save the avatar path in github to the database. When we publish the article, we can get the avatar through the current user information.
In order to facilitate our subsequent development, and to quickly add and delete fields, we introduced the lombok plug-in, as follows:

2.1.1 IDEA install lombok plug-in

Press and hold Ctrl+alt+s in IDEA, you can quickly open the settings panel, find plugins in it, enter lombok in the search box, click Install after finding it, and it will take effect after restarting IDEA after the installation is successful

After the plug-in is installed successfully, we need to add the dependency of lombok, as follows:

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.8</version>
    <scope>provided</scope>
</dependency>

After the dependency is added successfully, we will modify all previous entity classes as follows:

@Data
public class Article {
    private int id;
    private String title;
    private String description;
    private String tag;
    private Long authorId;
    private int readCount;    //Reading number
    private int answerCount;  //Reply number
    private int likeCount;    //Praise points
    private Long createTime;
    private Long modifiedTime;
    private User user;
}

Remove the getter and setter methods, and you can add a @ data annotation on the class. The annotation will automatically add the getter, setter methods and toString methods when compiling, which will save a lot of work and facilitate us to modify the entity class.

2.1.2 obtain the user's Avatar and save it in the database when logging in
AuthorizationController.java
@Controller
public class AuthorizationController {
    @Autowired
    GitHubProvider gitHubProvider;
    @Autowired
    UserMapper userMapper;

    @Value("${github.client.id}")
    private String client_id;
    @Value("${github.client.secret}")
    private String client_secret;
    @Value("${github.redirect.url}")
    private String redirect_url;

    @GetMapping("/callback")
    public String callback(@RequestParam(name = "code") String code,
                           @RequestParam(name = "state") String state,
                           HttpServletResponse response){

        AccessTokenParam accessTokenParam = new AccessTokenParam();
        accessTokenParam.setCode(code);
        accessTokenParam.setState(state);
        accessTokenParam.setClient_id(client_id);
        accessTokenParam.setClient_secret(client_secret);
        accessTokenParam.setRedirect_uri(redirect_url);
        String Token = gitHubProvider.getAccessToken(accessTokenParam);   //Get access_token
        String accessToken = Token.split("&")[0].split("=")[1];
        //Get user information using access? Token
        GitHubUser gitHubUser = gitHubProvider.getGitHubUser(accessToken);
        if(gitHubUser!=null){
            String token = UUID.randomUUID().toString();
            //Query whether the user exists according to the accountid
            User selectUser =  userMapper.selectUserByAccountId(gitHubUser.getId());

            //If there is an update token, user name and modification time
            if(selectUser!=null){
                if(gitHubUser.getName()==null||gitHubUser.getName()==""){
                    selectUser.setName("gid_"+gitHubUser.getId());
                }else if(gitHubUser.getName()!=null&&selectUser.getName()!=null&&!gitHubUser.getName().equals(selectUser.getName())){
                    selectUser.setName(gitHubUser.getName());
                }
                if(!gitHubUser.getAvatarUrl().equals(selectUser.getAvatarUrl())){
                    selectUser.setAvatarUrl(gitHubUser.getAvatarUrl());
                }
                selectUser.setToken(token);
                selectUser.setModifiedTime(System.currentTimeMillis());
                userMapper.updateUser(selectUser);
            }else{
                //If no new user information is added
                User user = new User();
                user.setName(gitHubUser.getName());
                user.setAccountId(gitHubUser.getId());
                user.setToken(token);
                //Set user image
                user.setAvatarUrl(gitHubUser.getAvatarUrl());
                user.setCreateTime(System.currentTimeMillis());
                user.setModifiedTime(user.getCreateTime());


                userMapper.addUser(user);
            }
            response.addCookie(new Cookie("token",token));
        }
        return "redirect:/";
    }
}
2.2 get all article list information

Operation statement of getting article and picture information in persistence layer

ArticleMapper.java
@Select("select u.*,a.id as aid,a.title,a.description,a.read_count,a.answer_count,a.like_count,a.create_time from article a,user u where a.author_id = u.id")
    @Results(id="ArticleUser",value = {
            @Result(id=true,property = "id",column = "id"),
            @Result(property = "id",column = "aid"),
            @Result(property = "title",column = "title"),
            @Result(property = "description",column = "description"),
            @Result(property = "authorId",column = "author_id"),
            @Result(property = "readCount",column = "read_count"),
            @Result(property = "answerCount",column = "answer_count"),
            @Result(property = "likeCount",column = "like_count"),
            @Result(property = "user.name",column = "name"),
            @Result(property = "user.avatarUrl",column = "avatar_url")
    })
    List<Article> list();

When the user enters the home page, the information obtained will be transferred to the front page for display.
IndexController.java

@GetMapping("/")
    public String index(HttpServletRequest request, Model model){
        Cookie[] cookies = request.getCookies();
        if(cookies!=null && cookies.length>0){
            for (Cookie cookie:cookies){
                if("token".equals(cookie.getName())){
                    String token = cookie.getValue();
                    User user =  userMapper.selectUserByToken(token);
                    if(user!=null){
                        request.getSession().setAttribute("user",user);
                    }
                }
            }
        }

        //Article list display
        List<Article> articleList = articleMapper.list();
        model.addAttribute("articleList",articleList);
        return "index";
    }

Homepage index.html page layout and usage of thmeleaf template statement

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <!-- The pit that I stepped on, springboot Do not add static resource path/static/,Otherwise, it will report 404-->
    <title>Personal blog</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <link rel="stylesheet" href="/bootstrap-3.3.7/css/bootstrap.min.css">
    <link rel="stylesheet" href="/css/community.css">
    <link rel="stylesheet" href="//at.alicdn.com/t/font_1643567_rm1fqucxtan.css">
    <link rel="stylesheet" href="/bootstrap-3.3.7/css/bootstrap-theme.min.css">
    <script src="/jquery-1.12.4/jquery-1.12.4.min.js"></script>
    <script src="/bootstrap-3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<!--Top navigation bar-->
<nav class="navbar navbar-default">
    <div class="container-fluid">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                <span class="sr-only">Personal blog</span>
            </button>
            <a class="navbar-brand" href="/">Personal blog</a>
        </div>

        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
            <form class="navbar-form navbar-left">
                <div class="form-group">
                    <input type="text" class="form-control" placeholder="Please search for questions">
                </div>
                <button type="submit" class="btn btn-default">search</button>
            </form>
            <ul class="nav navbar-nav navbar-right">
                <li th:if="${session.user!=null}">
                    <a href="/publish"><i class="iconfont icon-fabu2"></i>&nbsp;&nbsp;write an article</a>
                </li>
                <li th:if="${session.user==null}">
                    <a href="/login">Sign in</a>
                </li>
                <li class="dropdown" th:if="${session.user!=null}">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false" th:text="${session.user.name}"><span class="caret"></span></a>
                    <ul class="dropdown-menu">
                        <li><a href="#">Message center</a></li>
                        <li><a href="#">Foundation setup</a></li>
                        <li role="separator" class="divider"></li>
                        <li><a href="/logout">Logout</a></li>
                    </ul>
                </li>
            </ul>
        </div>
    </div>
</nav>

<div class="row main">
    <div class="col-lg-9 col-md-12 col-sm-12 col-xs-12 col-left">
        <div class="row">
            <div class="col-lg-3 col-md-3 col-sm-3 col-xs-3"><h4><i class="iconfont icon-liebiao"></i>&nbsp;list</h4></div>
            <div class="col-lg-6 col-md-6 col-sm-6 col-xs-9 alertMsg">
                <div class="alert alert-danger alert-dismissible alert-error" role="alert" th:if="${error != null}">
                    <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                    <span th:text="${error}"></span>
                </div>
            </div>
            <div class="col-lg-3 col-md-3 col-sm-3"></div>
        </div>
        <div class="media media_list" th:each="article : ${articleList}">
            <div class="media-left">
                <a href="#">
                    <img class="media-object img-rounded" th:src="${article.user.getAvatarUrl()}"  >
                </a>
            </div>
            <div class="media-body">
                <h4 class="media-heading" th:text="${article.title}">Title Title</h4>
                <span th:text="${article.answerCount}"></span> Reply • <span th:text="${article.readCount}"></span> Secondary browse • Release time<span th:text="${#dates.format(article.createTime,'yyyy-MM-dd HH:mm:ss')}"></span>
            </div>
        </div>

    </div>
    <div class="col-lg-3 col-md-12 col-sm-12 col-xs-12">
        <h4>Hot topics, billboards, hot labels, etc</h4>
    </div>
</div>
</body>
</html>

The above is the article list display operation, more source information can be accessed My github Download, the next article will take you to the handwritten data paging function.

Published 18 original articles, won praise 2, visited 1458
Private letter follow

Keywords: github Java Lombok Session

Added by gauravupadhyaya on Thu, 20 Feb 2020 12:17:14 +0200