AI🔥助我!三分钟实现丐版前后端注册登录需求

Java Web 系列文章:

前言

上篇进入了Java Web的世界,本篇将使用Servlet/JSP来实现简单的注册登录功能,当然我们需要与AI结对编程,AI输出框架代码,我们修缮细节即可。

通过本篇文章,你将了解到:

  1. Servlet 注解请求路径
  2. Servlet 过滤请求
  3. Servlet/JSP 转发和重定向
  4. Servlet Session保持登录态
  5. 小结

1. Servlet 注解请求路径

在上一篇里,请求路径与Servlet之间的映射是通过在web.xml编写映射关系体现的,此种方式比较麻烦,更简洁的方式是通过注解的方式建立映射。

比如,我们创建一个处理登录的Servlet,当浏览器访问登录页面时通过该Servlet处理。

如下:

java 复制代码
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
}

使用@WebServlet注解访问路径,当在浏览器里访问:

http://localhost:8080/java_web_war_exploded/login

请求将会分发给LoginServlet处理。

同样的,登录后跳转首页:

java 复制代码
@WebServlet("/main")
public class MainServlet extends HttpServlet {
}

对应的访问路径:

http://localhost:8080/java_web_war_exploded/main

当然访问的路径不是永久不变的,之前访问的是"main",后面访问变为"home",但处理逻辑又是一样的,想要同时兼容"main"和"home"路径的访问,此时注解也是支持多路径:

java 复制代码
@WebServlet(urlPatterns = {"/main", "/home"})
public class LoginServlet extends HttpServlet {
}

2. Servlet 过滤请求

现在有个需求:

用户先登录后才能进入主页查看学校列表信息,点击列表的item,进入具体学校的详情页

我们不能预判和控制用户在浏览器输入的地址,但可以对用户的请求进行过滤。比如用户在未登录的场景下直接访问了主页和详情页,此时应该将用户的访问路径重定向到登录页,登录完成后再跳转到主页/详情页。

于是我们需要对访问主页和详情页的请求进行过滤。

java 复制代码
@WebFilter(urlPatterns = {"/main", "/school_detail"}) // 过滤请求
public class AuthFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
    }
}

如上,先定义一个认证Filter类AuthFilter,实现了Filter接口,主要实现doFilter方法。

在该方法里对请求路径进行处理和分发。

过滤类建立好之后,需要指定其需过滤的路径。

如上,我们需要过滤首页和详情页的地址,则添加@WebFilter注解,并表明对应的路径。

此时当访问如下地址时:

http://localhost:8080/java_web_war_exploded/main http://localhost:8080/java_web_war_exploded/school_detail

请求将被优先分发到AuthFilter过滤器。

当然现在只有两个页面需要先登录再访问,若后续有N个页面需要先登录呢?我们也不可能穷举所有的页面,当然有更好的处理方式:

java 复制代码
@WebFilter("/*") // 过滤所有请求
public class AuthFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        String path = httpRequest.getRequestURI();

        // 1. 白名单路径放行(避免循环重定向)
        if (path.endsWith("/login") || path.endsWith("/register") || path.endsWith(".css") || path.endsWith(".js")) {
            chain.doFilter(request, response);
            return;
        }
    }
}

使用"/*"过滤所有请求,当然有些页面确实不需要登录就可以访问,可以设置白名单进行放过。

3. Servlet/JSP 转发和重定向

当过滤器发现用户未登录但访问了其它页面时如何处理呢?

java 复制代码
@WebFilter("/*") // 拦截所有请求
public class AuthFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        String path = httpRequest.getRequestURI();

        // 1. 白名单路径放行(避免循环重定向)
        if (path.endsWith("/login") || path.endsWith("/register")|| path.endsWith(".css") || path.endsWith(".js")) {
            chain.doFilter(request, response);
            return;
        }

        // 2. 检查登录态
        HttpSession session = httpRequest.getSession(false);
        if (session == null || session.getAttribute("user") == null) {
            //未登录,重定向到登录页
            httpResponse.sendRedirect(httpRequest.getContextPath() + "/login");
        } else {
            //不处理,继续处理后续过滤器或目标资源
            chain.doFilter(request, response);
        }
    }
}

处理步骤:

  1. 先从session里获取登录状态,判断当前用户是否登录
  2. 若未登录,则将请求转发到登录页面
  3. 若已登录,则不做额外处理

httpResponse.sendRedirect(xx),表示将请求重定向,httpResponse是发给浏览器的,因此当浏览器收到sendRedirect(xx)动作后,将取出参数xx,并重新向服务端发起请求。

此处重定向到servlet。

来看看实际表现,浏览器访问地址:http://localhost:8080/java_web_war_exploded/main 浏览器F12查看请求:

实际产生了两个请求:main和login。
我们请求了main,此时过滤器发现未登录,将请求重定向到login。


对于浏览器来说,它收到http的响应,状态码为302,于是取出响应头里的Location(/java_web_war_exploded/login)字段进行访问。

当浏览器访问:http://localhost:8080/java_web_war_exploded/login

交由LoginServlet处理:

java 复制代码
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.getRequestDispatcher("/school/login.jsp").forward(req, resp);
    }
}

此处是将请求转发到了JSP页面,最终展示:

以上涉及到两个概念:请求重定向和请求转发。

重定向:HttpServletResponse.sendRedirect(xx),通知浏览器重新请求xx路径,此时地址栏上的地址将发生变化 请求转发:RequestDispatcher.forward(req, resp),在服务器内部将请求转发到另一个Servlet或JSP,与浏览器没有交互,地址栏上的地址未发生变化。

4. Servlet Session保持登录态

用户被重定向到登录页面,输入信息进行登录后,第二次请求还会被重定向吗?当然不需要,因此我们需要记录用户的登录态。

通过Session记录用户的状态。

当用户通过form表单提交登录信息时:

向login发起了post请求,对应的是LoginServlet:

java 复制代码
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String phone = request.getParameter("phone");
        String captcha = request.getParameter("captcha");
        // 记录用户的登录态
        HttpSession session = request.getSession();
        session.setAttribute("user", phone);
        response.sendRedirect("main");
    }
}

LoginServlet 处理Post请求:

  1. 取出session
  2. 往session里存储登录信息

如此,服务端就记录了用户的登录信息。

当用户再次访问main页面时,在过滤器里判断session里是否有对应的登录信息从而判定用户是否处于登录态。

session存放在cookie里。

演示gif如下:

完整的工程请查看登录/注册模块

如果觉得有些许帮助,不要忘了一键三连哦~

下篇我们将对接数据库,进行传说中的CRUD。

相关推荐
We་ct几秒前
LeetCode 1. 两数之和:两种高效解法(双指针 + Map)
前端·算法·leetcode·typescript·哈希算法
LYFlied6 分钟前
边缘智能:下一代前端体验的技术基石
前端·人工智能·ai·大模型
1024小神7 分钟前
用css的clip-path裁剪不规则形状的图片展示
前端·css
铅笔侠_小龙虾12 分钟前
Flutter 组件层级关系
前端·flutter·servlet
梵得儿SHI15 分钟前
Vue 高级特性:渲染函数与 JSX 精讲(h 函数语法、JSX 在 Vue 中的应用)
前端·javascript·vue.js·jsx·模板语法·渲染函数·底层视图生成机制
GGGG寄了16 分钟前
CSS——文字控制属性
前端·javascript·css·html
菜鸟茜22 分钟前
ES6核心知识解析01:什么是ES6以及为什么需要ES6
前端·javascript·es6
人道领域26 分钟前
SSM从入门到入土(Spring Bean实例化与依赖注入全解析)
java·开发语言·spring boot·后端
C澒28 分钟前
FE BLL 架构:前端复杂业务的逻辑治理方案
前端·架构·前端框架·状态模式
long31630 分钟前
Z算法(线性时间模式搜索算法)
java·数据结构·spring boot·后端·算法·排序算法