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> 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> 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">×</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.