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。

相关推荐
牛奔5 分钟前
Go 如何避免频繁抢占?
开发语言·后端·golang
想用offer打牌5 小时前
MCP (Model Context Protocol) 技术理解 - 第二篇
后端·aigc·mcp
崔庆才丨静觅6 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60616 小时前
完成前端时间处理的另一块版图
前端·github·web components
KYGALYX6 小时前
服务异步通信
开发语言·后端·微服务·ruby
掘了6 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅6 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅7 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
爬山算法7 小时前
Hibernate(90)如何在故障注入测试中使用Hibernate?
java·后端·hibernate
崔庆才丨静觅7 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端