从0开始码第一个Spring Boot项目(javaweb个人博客系统)Spring Boot + thymeleaf 文章列表展示

回顾
上一篇我们实现了文章发布页面布局及发布功能,其中存在一些问题,这一篇我们解决问题并开始着手文章列表展示。
1 效果预览
1.1 编写文章

登录成功后我们点击写文章,进入编写页面
写文章
文章编写发布页面

1.2 发布文章

编写完成后点击发布。
点击发布

1.3 文章列表浏览页面

发布成功后会跳转到首页展示文章列表信息,如下:
列表展示

2.具体实现过程
2.1 文章列表图片

之前我们忽略了发布者头像显示及其他属性,这次分别在GitHubUser.java和User.java中增加头像字段avatarUrl,同时在数据库中user 表添加avatar_url列,当我们首次登陆时,就会将github中头像路径保存至数据库中,当我们发布文章后,就可以通过当前用户信息获取到头像。
为了方便我们后续开发,并且可以快捷增加字段删除字段,我们引入lombok插件,如下:

2.1.1 IDEA安装lombok插件

我们在IDEA中按住Ctrl+alt+s,可以快速打开设置面板,在里面找到plugins,在搜索框输入lombok,找到后点击Install,安装成功后需要重启IDEA后生效
IDEA中安装lombok插件
插件安装成功后,我们需要添加lombok的依赖,如下:

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

依赖添加成功后我们将之前所有的实体类进行修改如下:

@Data
public class Article {
    private int id;
    private String title;
    private String description;
    private String tag;
    private Long authorId;
    private int readCount;    //阅读数
    private int answerCount;  //回复数
    private int likeCount;    //点赞数
    private Long createTime;
    private Long modifiedTime;
    private User user;
}

将getter和setter方法去掉,可以在类上面添加一个@data注解,该注解会在编译的时候,自动将getter、setter方法,toString方法加上,这样会省去大量工作,同时便于我们对实体类进行修改。

2.1.2 在登录时获取用户头像并保存在数据库
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);   //获取到access_token
        String accessToken = Token.split("&")[0].split("=")[1];
        //使用access_token获取用户信息
        GitHubUser gitHubUser = gitHubProvider.getGitHubUser(accessToken);
        if(gitHubUser!=null){
            String token = UUID.randomUUID().toString();
            //根据accountid查询是否存在该用户
            User selectUser =  userMapper.selectUserByAccountId(gitHubUser.getId());

            //如果存在更新token,用户名及修改时间
            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{
                //如果不存在添加新的用户信息
                User user = new User();
                user.setName(gitHubUser.getName());
                user.setAccountId(gitHubUser.getId());
                user.setToken(token);
                //设置用户头像
                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获取所有文章列表信息

持久层获取文章及头像信息操作语句

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();

当用户进入到首页是,就会将获取到的信息传递到前台页面用于展示。
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);
                    }
                }
            }
        }

        //文章列表展示
        List<Article> articleList = articleMapper.list();
        model.addAttribute("articleList",articleList);
        return "index";
    }

主页index.html页面布局及thymeleaf模板语句使用

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <!-- 踩过的坑,springboot引入静态资源路径不要加/static/,否则会报404-->
    <title>个人博客</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>
<!--顶部导航栏-->
<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">个人博客</span>
            </button>
            <a class="navbar-brand" href="/">个人博客</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="请搜索问题">
                </div>
                <button type="submit" class="btn btn-default">搜索</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;写文章</a>
                </li>
                <li th:if="${session.user==null}">
                    <a href="/login">登录</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="#">消息中心</a></li>
                        <li><a href="#">基础设置</a></li>
                        <li role="separator" class="divider"></li>
                        <li><a href="/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;列表</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}">标题标题</h4>
                <span th:text="${article.answerCount}"></span> 个回复 • <span th:text="${article.readCount}"></span> 次浏览 • 发布时间<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>热门话题、广告栏、热门标签栏等</h4>
    </div>
</div>
</body>
</html>

以上就是文章列表展示操作,更多源码信息可以访问我的github下载,下一篇将带大家手把手写数据分页功能。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
核心功能 文章/图片/视频发布、喜欢、统计阅读次数。 文章标签tag功能、支持按tag分类 文章支持ueditor/markdown编辑器切换(后台配置) 评论功能,支持回复,支持表情。 第三方(微、QQ)登录。 lucene实现的站内搜索。 响应式布局 支持用户订阅 先看效果图 SpringBoot开发非常美观的java系统(包含后台管理功能) SpringBoot开发非常美观的java系统(包含后台管理功能) SpringBoot开发非常美观的java系统(包含后台管理功能) http://localhost:8080/admin/group/list SpringBoot开发非常美观的java系统(包含后台管理功能) SpringBoot开发非常美观的java系统(包含后台管理功能)SpringBoot开发非常美观的java系统(包含后台管理功能) 技术选型: JDK8 数据库MySQL 主框架 (Spring-bootSpring-data-jpa) 安全权限 Shiro 搜索工具 Lucene 缓存 Ehcache 视图模板 Freemarker 其它 Jsoup、fastjson jQuery、Seajs Bootstrap 前端框架 UEditor/Markdown编辑器 font-Awesome 字体/图标 准备工作(sql文件在项目里面) 安装 Jdk8 安装 Maven 准备 IDE (如果你不看源码,可以忽略下面的步骤,直接通过Maven编译war包:mvn clean package -DskipTests) IDE 需要配置的东西 编码方式设为UTF-8 配置Maven 设置Jdk8 关于这些配置,网上有一大把的资料,所以此处不再重复。 获取代码导入到IDE 下载代码 导入到IDE的时候请选择以Maven的方式导入 项目配置参考 系统配置手册 配置完毕 启动项目,在控制台看到Mblog加载完毕的信息后,表示启动成功 打开浏览器输入:http//localhost/mblog/ (此处仅是示例,具体具体端口因人而异),访问成功即部署完毕 后台管理的地址是 /admin, 如果你是管理员账号点导航栏的头像会看到"后台管理" 启动成功后,你应该去后台的系统配置里配置你的网站信息等。 常见问题总结 进入系统后, 菜单加载不出来, 那应该是你没有导 db_init.sql 点标签显示乱码, 请设置Tomcat的 URIEncoding 为 UTF-8 项目截图 SpringBoot开发非常美观的java系统(包含后台管理功能) 转自:https://gitee.com/mtons/mblog SpringBoot开发非常美观的java系统(包含后台管理功能) 注意: 一、java main方式运行mblog-web下的BootApplication.java时抛出异常的解决方案 Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean. SpringBoot开发非常美观的java系统(包含后台管理功能) 注释掉后下面图片的这段后,记得maven要重新reimport SpringBoot开发非常美观的java系统(包含后台管理功能) SpringBoot开发非常美观的java系统(包含后台管理功能) 否则maven依赖不生效还是会抛出以上的异常 二、第三方登录点击后无响应,那是因为第三方开放平台回调的url失效导致,需要你去对应的第三方开放平台注册app后获取对应的oauth帐号 SpringBoot开发非常美观的java系统(包含后台管理功能) 三、idea以maven项目导入该项目后,发现没有maven的依赖包时,需要对每个maven module进行clear和install,并且注意maven的依赖顺序 SpringBoot开发非常美观的java系统(包含后台管理功能) SpringBoot开发非常美观的java系统(包含后台管理功能) 四、访问地址是http://localhost:8080 登录时,帐号,密码只要自己找个密码,然后md5下在更新到db中即可登录成功。 比如:zuidaima 111111,md5后密码是 3931MUEQD1939MQMLM4AISPVNE,md5的java类 SpringBoot开发非常美观的java系统(包含后台管理功能) SpringBoot开发非常美观的java系统(包含后台管理功能)
基于springboot_ssm的个人源代码: 个人系统主要用于发表个人,记录个人生活日常,学习心得,技术分享等,供他人浏览,查阅,评论等。本系统结构如下: (1)主端: 登录模块:登入后台管理系统:首先进入登录页面,需要输入账号和密码。它会使用Shiro进行安全管理,对前台输入的密 码进行加密运算,然后与数据库中的进行比较。成功后才能登入后台系统管理模块: 管理功能分为写信息管理。写主用来发表编写的,需要标题,然后选择 类型,最后将内容填入百度的富文本编辑器中,点击发布按钮即可发布类别管理模块:主类别管理系统可以添加,修改和删除类型名称和排序序号。将会显示到首页的按日志类别区域。 游可 以从这里查找相关的感兴趣的内容 评论信息管理模块:评论管理功能分为评论审核和评论信息管理两部分。评论审核是当有游或自己发表了评论之后,主需 要在后台管理系统中审核评论。若想将此评论显示在页面上则点击审核通过,否则点击审核不通过。 个人信息管理模块:修改主的个人信息,可以修改昵称,个性签名,可以添加个人头像,修改个人简介; 系统管理功能模块:友情链接管理,修改密码,刷新系统缓存和安全退出,友情链接管理可以添加,修改,删除友情链接网址 (2)游端: 查询: 查询具体哪一篇 查看内容: 查看内容 查看个人信息:查看个人简介 发表评论: 可以评论具体某篇 友情链接: 查看友情链接
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值