发布于2021-05-30 12:53 阅读(1293) 评论(0) 点赞(11) 收藏(5)
请求:
POST /login
{
name: xxx,
password: xxx
}
响应:
HTTP/1.1 200 OK
{
ok: true,
reason: xxx,
userId: xxx,
name: xxx,
nickName: xxx,
signature: xxx
}
loginAccount() {
console.log("login");
$.ajax({
url: 'login',
type: 'post',
contentType: 'application/json',
data: JSON.stringify({
name: app.login.inputUsername,
password: app.login.inputPassword,
}),
success: function(data, status) {
if (!data.ok) {
alert('登陆失败! ' + data.reason);
app.login.isLogin = false;
return;
}
app.user.userId = data.userId;
app.user.name = data.name;
app.user.nickName = data.nickName;
app.user.signature = data.signature;
app.login.isLogin = true;
app.login.showLoginDialog = false;
app.getChannels();
app.initWebSocket();
}
})
},
根据前后端接口编写Servlet
package org.example.servlet;
import org.example.dao.UserDao;
import org.example.exception.AppException;
import org.example.model.User;
import org.example.util.Util;
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;
/**
* Created with IntelliJ IDEA.
* Description:登录接口
* User: starry
* Date: 2021 -05 -22
* Time: 18:52
*/
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
//检测登陆状态接口
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
//登录接口
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置编码格式和内容类型
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("application/json");
//相应的数据:根据接口文档,user类中都包含了约定的字段
User user = new User();
try {
//1. 解析请求数据:根据接口文档,需要使用反序列化操作
User input = Util.deserialize(req.getInputStream(),User.class);
//2. 业务处理:数据库验证账号密码,如果验证通过,创建session,保存用户信息
//根据账号查询用户
User query = UserDao.queryByName(input.getName());
if (query == null) {
throw new AppException("用户不存在");
}
if (!query.getPassword().equals(input.getPassword())) {
throw new AppException("账号或密码错误");
}
//账号密码校验成功
HttpSession session = req.getSession(true);
session.setAttribute("user",query);
user = query;
//构造操作成功的正常返回数据:ok-true,业务字段
user.setOk(true);
}catch (Exception e) {
e.printStackTrace();
//构造操作失败的错误信息:ok-false,reason:错误信息
user.setOk(false);
//自定义异常,自己抛,为中文信息,可以给用户看
if (e instanceof AppException) { //e捕获到的异常是不是自定义异常
user.setReason(e.getMessage());
}else { //非自定义异常,英文信息,给前端看“未知错误”
user.setReason("未知的错误,请联系管理员");
}
}
//3. 返回响应数据:从响应对象获取输出流,打印输出到响应体body中
resp.getWriter().println(Util.serialize(user));
}
}
这里的doget方法先放置,给与报错信息捕获,之后完成doget接口
在Dao文件夹下创建用户相关数据库操作的类UserDao
编写根据姓名查询用户所有信息的queryByName方法
public class UserDao {
/**
* 根据姓名查询用户所有信息
*/
public static User queryByName(String name) {
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
//定义返回数据
User user = null;
try {
//1. 获取数据库连接Connection
connection = Util.getConnection();
//2. 通过Connection+sql 创建操作命令对象Statement
String sql = "select userId,name,password,nickName,iconPath,signature,lastLogout from user where name = ?";
statement = connection.prepareStatement(sql);
statement.setString(1,name);
//3. 执行sql:执行前替换占位符
resultSet = statement.executeQuery();
//如果是查询操作,处理结果集
if (resultSet.next()) {//移动到下一行,有数据返回true
user = new User();
//设置结果集字段到用户对象的属性中
user.setUserId(resultSet.getInt("userid"));
user.setName(resultSet.getString("name"));
user.setPassword(resultSet.getString("password"));
user.setNickName(resultSet.getString("nickName"));
user.setIconPath(resultSet.getString("iconPath"));
user.setSignature(resultSet.getString("signature"));
java.sql.Timestamp lastLogout = resultSet.getTimestamp("lastLogout");
user.setLastLogout(new Date(lastLogout.getTime()));
}
return user;
}catch (Exception e) {
throw new AppException("查询用户账号出错", e);
}finally {
//释放资源
Util.close(connection,statement,resultSet);
}
}
}
前端展示
数据库查询
可以看到此时我们登录成功后,左上角也变成了“阿星你好”
然后我们抓取login的包,可以看到包中的内容与数据查询到的结果一致,该登录接口完成。
请求:
GET /login
响应:
HTTP/1.1 200 OK
{
ok: true,
userId: xxx,
name: xxx,
nickName: xxx,
signature: xxx
}
checkLogin() {
// 页面最初加载时先访问服务器判定自身的登陆状态.
console.log("checkLogin");
$.ajax({
url: 'login',
type: 'get',
success: function(data, status) {
if (!data.ok) {
// 未登录
app.login.isLogin = false;
app.user = {};
return;
}
// 已经登陆
app.login.isLogin = true;
app.user.userId = data.userId;
app.user.name = data.name;
app.user.nickName = data.nickName;
app.user.signature = data.signature;
app.getChannels();
app.initWebSocket();
}
});
},
这里把刚才没有完善的doget方法(也就是检测登录接口)完善,代码如下
这里先获取session,如果获取到了,则给前端响应session中的user对象(为什么session能获取到user对象:因为session没有过期,生命周期为关闭客户端/浏览器前,所以可以获取到)
//检测登陆状态接口:页面初始化时执行
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置编码格式和内容类型
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("application/json");
//返回的数据,用户信息
User user = new User();
//获取当前请求的session,并再获取用户信息,如果获取不到,返回ok:false
HttpSession session = req.getSession(false);
if (session != null) {
User get = (User)session.getAttribute("user");
if (get != null) {
//已经登录,并获取到用户信息
user = get;
user.setOk(true);
resp.getWriter().println(Util.serialize(user));
return;
}
}
user.setOk(false); //可以不用设置,默认为false
user.setReason("用户未登录");
//3. 返回响应数据:从响应对象获取输出流,打印输出到响应体body中
resp.getWriter().println(Util.serialize(user));
}
我们如果登录后点击刷新,它还是登录状态
但是如果我们手动删除session
然后再点击刷新,那么可以看到,就退出到登录界面了
ok,我们登录检测接口也完成了
原文链接:https://blog.csdn.net/starry1441/article/details/117170148
作者:小猪佩奇身上纹
链接:http://www.qianduanheidong.com/blog/article/116139/7a4d3cd8a9b20486e8af/
来源:前端黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 前端黑洞网 All Rights Reserved 版权所有,并保留所有权利。 京ICP备18063182号-3
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!