使用session和cookie维持数据,jfinal登录案例,

关于本话题最基本的应用就是登录了,个人今天做了一个登录的小案例,有些小心得分享一下。

基本知识

  1. 首先,cookie是我们用来发送到客户端的数据,由于http协议本身是无状态的,即服务器无法判断用户身份。Cookie实际上是一小段的文本信息(key-value格式)。客户端向服务器发起请求,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态
  2. sessionsession机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(key-value)来保存信息。 一般来说,服务器第一次接收到请求时,开辟了一块Session空间(创建了Session对象),同时生成一个Session id,并通过响应头的Set-Cookie:“JSESSIONID=XXXXXXX”命令(此处的cookietomcat或者undertow示例的cookie),向客户端发送要求设置cookie的响应。
  3. 维持一段会话靠的是cookiesession都存在的情况下,如果cookie设置了维持的时间,则到时间后会自动清空,session如果删除了所存储的sessionId,则也是。

基本操作

  1. 基于上面的方式,我们对于一个登录成功的用户,可以使用加密方式获得一个sessionId,将sessionId和对应的用户信息可以放入session中,也可以放入类似redis的缓存共享空间中,加上其对应的过期时间,或者某些情况下手动删除。
  2. 将此sessionId设置到cookie中,这样每次请求都会附带上这些信息,我们就可以在服务端查找该id对应的信息了,再简单加上拦截器即可判断是否登录。

jfinal简单案例代码

@Before(LoginValidator.class)
    public void login() {
        // 如果从session中获取到当前cookie所对应的对象,则直接返回登录后的主页
        String cookie = getCookie(LoginService.SESSION_ID);
        if (cookie != null && getSessionAttr(cookie) != null) {
            render("/index/index.html");
        }

        // 获取本次请求的对象并转换为User类型
        User user = getBean(User.class, "");

        Ret ret = service.login(user);
        if (ret.isOk()) {
            // 设置sessionId为得到当前请求的全球通用唯一识别码
            String sessionId = StrKit.getRandomUUID();

            setSessionAttr(sessionId, ret.get(LoginService.CACHE_KEY));
            setCookie(LoginService.SESSION_ID, sessionId, 1 * 60 * 60, true);
            set("name", user.getName());

            render("/index/index.html");
        } else {
            // 设置错误信息
            set("mes", ret.get("mes"));

            render("login.html");
        }
    }

public class LoginInterceptor implements Interceptor {
    @Override
    public void intercept(Invocation inv) {
        User user;
        // 获取当前控制器
        Controller controller = inv.getController();

        // 获取本次请求中的cookie中的sessionId
        String sessionId = controller.getCookie(LoginService.SESSION_ID);

        if (sessionId != null) {
            // 获取session中的sessionId
            user = controller.getSessionAttr(sessionId);
            if (user != null) {
                // 隐藏字段
                user.hide();
                // 设置全局需要渲染的数据,即用户姓名
                controller.set("name", user.getName());
            } else {
                // 如果根据当前id没有获得到用户,则证明session已经过期,删掉cookie存储的sessionId即可。
                controller.removeCookie(LoginService.SESSION_ID);
            }
        }
        inv.invoke();
    }
}

public class LoginService {
    private User dao = new User().dao();

    public static final String SESSION_ID = "sessionId";
    public static final String CACHE_KEY = "user";

    public Ret login(User user) {
        User result = dao.findFirst("select * from user where name = ?",
                user.getName());

        if (result != null) {
            if (result.getPwd().equals(user.getPwd())) {
                return Ret.ok().set(LoginService.CACHE_KEY, user);
            } else {
                return Ret.fail("mes", "密码不正确");
            }
        } else {
            return Ret.fail("mes", "不存在此用户");
        }
    }
}

小提示
  1. 基本的httpservletRequesthttpservletResponseJava只提供了接口,所以这些具体实现类需要服务器自己写,例如Tomcatundertow服务器,这些实现类是它们实现的。
发布了76 篇原创文章 · 获赞 53 · 访问量 4163

猜你喜欢

转载自blog.csdn.net/qq_42254247/article/details/103058336