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。

相关推荐
Tony Bai5 分钟前
Go 的 AI 时代宣言:我们如何用“老”原则,解决“新”问题?
开发语言·人工智能·后端·golang
卤代烃17 分钟前
🦾 可为与不可为:CDP 视角下的 Browser 控制边界
前端·人工智能·浏览器
_XU31 分钟前
AI工具如何重塑我的开发日常
前端·人工智能·深度学习
C_心欲无痕1 小时前
vue3 - defineExpose暴露给父组件属性和方法
前端·javascript·vue.js·vue3
鹿人戛1 小时前
HarmonyOS应用开发:相机预览花屏问题解决案例
android·前端·harmonyos
用户47949283569151 小时前
性能提升 40 倍!实战 PostgreSQL FDW 解决微服务跨库查询难题
数据库·后端
萌萌哒草头将军1 小时前
绿联云 NAS 安装 AudioDock 详细教程
前端·docker·容器
计算机毕设VX:Fegn08951 小时前
计算机毕业设计|基于springboot + vue宠物医院管理系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
GIS之路2 小时前
GIS 数据转换:使用 GDAL 将 GeoJSON 转换为 Shp 数据
前端
朴shu2 小时前
Luckysheet 远程搜索下拉 控件开发 : 揭秘二开全流程
前端