从零开始的胎教“ 个人博客 ”项目搭建 —— 登陆,个人文章列表

三、用户登陆功能实现

  • 接着之前的项目

  • 先简述一下登录功能的具体实现流程:
    ① 在前端页面输入用户名和密码之后;
    ② 将所输入的对象(用户名和密码)传递给后端;
    ③ 后端将这个对象的信息与服务器的数据库中的信息进行比对,当发现存在数据库中时,则给前端返回登陆成功的信息,前端则弹出登录成功(可进行跳转)

  • 我们需要根据我们服务器中用户表中有的信息建立一个模板类,当前端登录页面输入信息后,我们用这个信息根据我们固定的模板生成一个用户对象,把这这个对象和数据库中的用户数据进行比对。在models文件夹下创建一个UserInfo

package models;

import java.util.*;
public class UserInfo {
    private int id;
    private Date createtime;
    private Date updatetime;
    private String username;
    private String password;
    private int state;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Date getCreatetime() {
        return createtime;
    }

    public void setCreatetime(Date createtime) {
        this.createtime = createtime;
    }

    public Date getUpdatetime() {
        return updatetime;
    }

    public void setUpdatetime(Date updatetime) {
        this.updatetime = updatetime;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
    }
}

  • 要实现登录页面,则需要在webapp下创建登录的前端页面login.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录页面</title>
    <script src="jquery-1.9.1.min.js"></script>
    <script>
        function mysub(type) {
            var username = jQuery("#username");
            var password = jQuery("#password");
            if(type == 2){
                username.val("");
                password.val("");
                return false;
            }
            // 1、非空校验
            if(username.val().trim() == ""){
                alert("请先输入用户名");
                username.focus();
                return false;
            }
            if(password.val().trim() == ""){
                alert("请先输入密码");
                password.focus();
                return  false;
            }

            // 2、请求后端,实现登陆验证
            jQuery.getJSON("login",{
                "username":username.val(),
                "password":password.val()
            },function (data) {
                if(data != null && data.succ != null && data.succ == 1){
                    alert("登陆成功,这里进行跳转");
                    // location.href = "myartlist.html";
                    // 这里先注释掉,这个是我们下一部分实现的功能,这是一个跳转
                }else{
                    alert("登录失败" + data.msg);
                }
            });
        }
    </script>
</head>
<body>
<div style="margin-top: 70px;text-align: center">
    <h1>登录</h1>
    用户名:<input id="username" name="username" type="text"><p></p>
    密码:<input id="password" name="password" type="password"><p></p>
    <input type="button" onclick="mysub(1)" value=" 提 交 ">
    <input type="button" onclick="mysub(2)" value=" 清 空 ">
</div>
</body>
</html>
  • 然后根据前端jQuery.getJSON()的第一个参数(路由地址),新建一个服务类,也是类似于模板化的代码
    服务类需要改的部分目前开来基本只有:
    ① 前端传给后端的参数,具体况使用不同的类型接收
    ② 具体的业务逻辑,这部分是通过是实例化dao文件下的类,具体根据所需情况编写具体的方法操作(找到对应的厨师,做对应的饭)
    ③ 返回给前端的结果部分有时也会改动,不过目前不改,因为当前我们给前端的信息只有是否成功(succ)和可能会出现的错误信息(msg)
package service;

import dao.UserInfoDao;
import models.UserInfo;
import utils.ResultJSONUtils;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.sql.SQLException;
import java.util.HashMap;

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        int succ = -1; // 1:登录成功
        String msg = "";// 错误信息
        // 1.得出前端传递的参数
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        // 2.去数据库验证用户名和密码【业务】
        if (username != null && !username.equals("") &&
                password != null && !password.equals("")
        ) {
            // 参数正确,执行数据库查询
            UserInfoDao userInfoDao = null;
            try {
                userInfoDao = new UserInfoDao();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
            try {
                // 查询数据库
                UserInfo userInfo = userInfoDao.getUser(username, password);
                if (userInfo.getId() > 0) {
                    // 查到用户了,也就是用户名和密码是正确
                    succ = 1;
                    // 将用户信息存放到 session
                    HttpSession session = request.getSession(); // 用来创建会话
                    // 将用户信息存放到当前session(方便后面查询文章列表时使用)
                    session.setAttribute("userinfo", userInfo);
                } else {
                    succ = 0;
                    msg = "用户名或密码输出错误!";
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        } else {
            // 参数不完整,非法请求
            msg = "非法请求,参数不完整";
        }
        // 3.返回结果
        HashMap<String, Object> result = new HashMap<>();
        result.put("succ", succ);
        result.put("msg", msg);
        ResultJSONUtils.write(response, result);
    }
}
  • 在服务类的代码中有一部分需要说明一下:
// 将用户信息存放到 session
 HttpSession session = request.getSession(); // 用来创建会话
 // 将用户信息存放到当前session(方便后面查询文章列表时使用)
 session.setAttribute("userinfo", userInfo);
  • 在成功登陆后,因为http是属于无状态协议,所以网页本身并不会保存我们访问后的信息,所以要使用Session将我们的用户信息暂时保存起来,这样当我们频繁访问各种信息时就不用每次都去验证一遍
  • 上面服务类下的LoginServlet写完后,会发现有报红,是我们的操作类UserInfoDao下没有我们要的的具体操作,之后在我们每次添加一个新功能时,基本也都要对操作类的具体方法进行添加,如下图:
    在这里插入图片描述
  • 把以下代码放进去,这步其实也相对比较模板,需要改的基本就是数据库的查询语句sql
// 查询用户(登录功能使用)
    public UserInfo getUser(String username, String password) throws SQLException {
        UserInfo userInfo = new UserInfo();
        // 使用JDBC查询数据库
        Connection connection = DBUtils.getConnection();
        String sql = "select * from userinfo where username=? and password=?";
        PreparedStatement statement = connection.prepareStatement(sql);
        statement.setString(1,username);
        statement.setString(2,password);
        // 查询数据库
        ResultSet resultSet = statement.executeQuery(); // 此处查找到的是username=root,password=123的所有用户
        while(resultSet.next()){
            userInfo.setId(resultSet.getInt("id"));
            userInfo.setUsername(resultSet.getString("username"));
            userInfo.setPassword(resultSet.getString("password"));
        }
        // 关闭数据库
        DBUtils.close(connection,statement,resultSet);
        return userInfo;
    }
  • 跟之前的注册有些不同的是,因为注册至于要将前端给到的用户名和密码写入数据库就好,所以只需要在数据库中添加即可;但登录功能需要将数据库中的用户数据(生成一个对象)拿到,并且返回给前端,所以会多了ResultSet这一步
  • 接下来就可以运行了,运行IEDA,并且登录http://localhost:8080/untitled_war/login.html
  • 根据我们之前注册的用户名和密码,登录,就可以看到以下页面了,当然你也可以试一下输入错误的账号和密码看看有什么反馈。
    在这里插入图片描述
  • OK,登录的功能也实现了ヽ(✿゚▽゚)ノ

四、个人文章列表功能实现

  • 惯例描述一下功能概述:
    在前端的登陆页面登陆成功后,跳转到一个文章页面myartlist.html,文章页面中会根据用户在数据库中的文章表(文章表是和用户表有逻辑相关的,比如每个文章有一个uid属性代表这个文章属于哪个id的用户)显示出文章
1、数据库表的准备
  • 我们先在服务器的数据库里把文章表创建了,并且把文章也添加进这个表
-- 创建文章表
drop table if exists articleinfo;
create table articleinfo(
    id int primary key auto_increment,
    createtime datetime default now(),
    updatetime datetime default now(),
    title varchar(100) not null,
    content text not null,
    rcount int default 1,
    state int default 1,
    uid int not null
);


-- 插入测试数据
insert into userinfo(id,username,password) values(1,'admin','123');

insert into articleinfo(title,content,uid)
    values('JavaWeb文章','内容:这里是文章1',1),  // 这里的1是用户,根据你服务器中你想给哪个用户添加文章,就这个值改成那个用户
    ('传世圣经','内容:任天堂是这个世界的主宰',1);

insert into articleinfo(title,content,uid)
    values('JavaWeb文章','内容:这里是文章1',2),  
    ('传世圣经','内容:任天堂是这个世界的主宰',2);
  • 添加完后可以看看自己的数据库,我因为之前有添加,所以有两个用户和四篇文章
    在这里插入图片描述
  • 这样准备工作就做完了,可以开始进行前后端的代码部分了
2、前端页面部分代码书写
  • webapp下创建一个myartlist.html文件,显示文章列表
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文章列表</title>
    <script src="jquery-1.9.1.min.js"></script>
    <script>
        // 查询文章列表功能
        jQuery(function () {
            // 1、去后台查询我的文章列表
            // 因为是从session中那用户的uid,所以前端不需要给后端发送键值对
            jQuery.getJSON("myartlist",{},function (data) {
                // 2、将table中的信息替换成后台的数据
                if(data != null && data.succ ==1){
                    var html = "";
                    for (var i = 0; i < data.list.length; i++) {
                        var article = data.list[i];
                        html += "<tr>\n" +
                            "<td>\n" +
                            article.id + "\n" +
                            "</td>" +
                            "<td>\n" +
                            article.title + "\n" +
                            "</td>" +
                            "<td>\n" +
                            article.createtime + "\n" +
                            "</td>" +
                            "<td>\n" +
                            article.rcount + "\n" +
                            "</td>" +
                            "<td>\n" +
                            "修改" +
                            "删除\n" +
                            "</td>" +
                            "</tr>\n"
                    }
                    jQuery("#tab1").append(html);
                }else{
                    alert("操作失败:" + data.msg);
                }
            })
        })
    </script>
</head>
<body>
<div style="margin-top: 70px; text-align: center">
    <h1>我的文章列表</h1>
    <a href="addart.html">添加文章</a>
    <table id="tab1" style="width: 80%;margin-left: 100px;" border="1">
        <tr>
            <td>
                编号
            </td>
            <td>
                标题
            </td>
            <td>
                发布时间
            </td>
            <td>
                阅读数
            </td>
            <td>
                操作
            </td>
        </tr>
    </table>
</div>
</body>
</html>

  • 前端页面的实现和功能不多做解释,主要看后端,值得一提的是:
    该部分的jQuery.getJSON()功能中并没有从前端给后端发送键值对,这是因为之前在登录之后,用户的信息都保存在Session中了,我们直接从后端调取Session中的当前用户信息就好;
    还有这个function(data){}回调函数在之前我们实现的功能中返回的只是标识是否成功的succ和有可能出现的错误信息msg,但在此功能里,需要将用户数据库中的文章表的文章信息也返回给前端
  • 前端代码就这样了,但我们需要从登陆页面跳转到当前页面,还记得在用户登录功能的前端代码里注释掉的那条跳转代码吗,现在可以把那个注释取消掉了;location.href = "myartlist.html";代码的意思就是跳转到myartlist.html页面
3、后端服务与具体操作类代码
  • 跟用户注册登录时一样,我们也需要专门处理文章的dao类(厨师),因此在dao文件夹下创建ArticleInfoDao类;同时也需要存放文章信息的模板即在model文件夹下创建ArticleInfo类;
  • 根据数据库中文章表的信息,先把模板ArticleInfo类写了:
package models;

import java.util.Date;

public class ArticleInfo {
    private int id;
    private Date createtime;
    private Date updatetime;
    private String title;
    private String content;
    private int rcount;
    private int state;
    private int uid;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Date getCreatetime() {
        return createtime;
    }

    public void setCreatetime(Date createtime) {
        this.createtime = createtime;
    }

    public Date getUpdatetime() {
        return updatetime;
    }

    public void setUpdatetime(Date updatetime) {
        this.updatetime = updatetime;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public int getRcount() {
        return rcount;
    }

    public void setRcount(int rcount) {
        this.rcount = rcount;
    }

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
    }

    public int getUid() {
        return uid;
    }

    public void setUid(int uid) {
        this.uid = uid;
    }
}
  • 而厨师ArticleInfoDao类下的具体方法我们稍后写
  • 接下来根据前端页面中jQuery.getJSON()的路由地址创建后端服务类MyArtListServlet
package service;

import dao.ArticleInfoDao;
import models.ArticleInfo;
import models.UserInfo;
import utils.ResultJSONUtils;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
@WebServlet
public class MyArtListServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        int succ = -1;
        String msg = "";
        List<ArticleInfo> list = null;
        // 1、拿到前端给的参数(在Session中存放)
        HttpSession session = request.getSession(false); // 如果是true,则会在没有session的情况下自动创建一个,为了实现登录才能访问的功能,所以设置为false
        if(session == null){
            //用户未登录
            msg = "非法请求,请先登录!";
        }else{
            // 用户已登录
            UserInfo userInfo = (UserInfo) session.getAttribute("userinfo");
            // 那userInfo去查询数据库
            int uid = userInfo.getId(); // 从登陆的用户信息中,拿到该用户在数据库中的id号
            ArticleInfoDao articleInfoDao = new ArticleInfoDao();
            try {
                // 根据该id号,在文章表中找到对应的列表
                list = articleInfoDao.getListByUID(uid);
                succ = 1;
            }catch (SQLException throwables){
                throwables.printStackTrace();
            }
        }

        // 3、构建和返回后端结果
        HashMap<String, Object> result = new HashMap<>();
        result.put("succ", succ);
        result.put("msg", msg);
        result.put("list", list);
        ResultJSONUtils.write(response,result);
    }
}
  • 这里也看以看到一个区别,就是这里在返回后端结果给前端时多了一个list列表,这个list里面存放的就是文章表的一些信息。
  • 同样,我们去具体操作里面去书写:
    在这里插入图片描述
  • 从这里开始其实就是套路化的东西了
// 拿到数据库中该uid用户下的文章列表
    public List<ArticleInfo> getListByUID(int uid) throws SQLException {
        List<ArticleInfo> list = new ArrayList<>();
        Connection connection = DBUtils.getConnection();
        String sql = "select * from articleinfo where uid=?";
        PreparedStatement statement = connection.prepareStatement(sql);
        statement.setInt(1,uid);
        // 查询并返回结果
        ResultSet resultSet = statement.executeQuery();
        // 将查询的结果存放在list列表中
        while(resultSet.next()){
            ArticleInfo articleInfo = new ArticleInfo();
            articleInfo.setId(resultSet.getInt("id"));
            articleInfo.setRcount(resultSet.getInt("rcount"));articleInfo.setTitle(resultSet.getString("title"));
            articleInfo.setContent(resultSet.getString("Content"));
            articleInfo.setCreatetime(resultSet.getDate("createtime"));
            list.add(articleInfo);
        }
        return list;
    }
  • 这样我们前后端的代码就写完了,IDEA运行一下试试
  • 访问http://localhost:8080/untitled_war_exploded/login.html后输入我们之前注册的用户名和密码
  • 登陆成功会发现此时跳转了URL也变成了http://localhost:8080/untitled_war_exploded/myartlist.html
  • 并且属于该用户的文章也显示在网页上了
    在这里插入图片描述
  • OK,结束♪(*)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值