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 小时前
大模型输出的“隐性结构塌缩”问题及对策
前端·后端
小江的记录本5 小时前
【网络安全】《网络安全常见攻击与防御》(附:《六大攻击核心特性横向对比表》)
java·网络·人工智能·后端·python·安全·web安全
这儿有一堆花5 小时前
前端三件套真的落后了吗?揭开现代 Web 开发的底层逻辑
前端·javascript·css·html5
努力的小雨5 小时前
龙虾量化实战法(QClaw)
后端
.Cnn6 小时前
JavaScript 前端基础笔记(网页交互核心)
前端·javascript·笔记·交互
橙露6 小时前
SpringBoot 整合 MinIO:分布式文件存储上传下载
spring boot·分布式·后端
醉酒的李白、6 小时前
Vue3 组件通信本质:Props 下发,Emits 回传
前端·javascript·vue.js
anOnion6 小时前
构建无障碍组件之Window Splitter Pattern
前端·html·交互设计
NotFound4866 小时前
实战分享Python爬虫,如何实现高效解析 Web of Science 文献数据并导出 CSV
前端·爬虫·python
徐小夕7 小时前
PDF无限制预览!Jit-Viewer V1.5.0开源文档预览神器正式发布
前端·vue.js·github