当前位置: 首页 > news >正文

JSP入门详解

JSP

Servlet基本概念

1.Servlet是什么

  1. Servlet是JavaEE Web组件,必须运行在Web容器(tomcat)中,需要容器为其提供运行的环境,课程中使用Tomcat作为容器。

  2. 本质上,Servlet就是一个Java类,不过这个Java类要遵守一定的规范,即继承HttpServlet类

  3. HttpServlet类中定义了很多方法,自定义的Servlet类需要覆盖其中的方法,一般情况下,只覆盖doGet或doPost。使用GET方式访问时,自动调用doGet,使用POST方式访问时,自动调用doPost

2.HttpServletRequest (req) - 读数据

拿参数

String value = req.getParameter("name");         // 拿单个
String[] values = req.getParameterValues("hobby"); // 拿多个

看信息

String method = req.getMethod();          // GET/POST
String ip = req.getRemoteAddr();          // 客户端IP
String url = req.getRequestURI();         // 请求路径

存东西(请求域)

req.setAttribute("key", object);          // 存
Object obj = req.getAttribute("key");     // 取

会话相关

HttpSession session = req.getSession();   // 获取Session

3.HttpServletResponse (resp) - 写响应

  1. 设响应头(防乱码必备)

    resp.setContentType("text/html;charset=UTF-8");
  2. 写数据

    PrintWriter out = resp.getWriter();       // 字符流(文本)
    out.println("<h1>内容</h1>");
    ​
    ServletOutputStream out = resp.getOutputStream(); // 字节流(文件)
  3. 重定向

    resp.sendRedirect("新页面.html");         // 地址栏会变
  4. 设Cookie

    Cookie cookie = new Cookie("name", "value");
    resp.addCookie(cookie);

    经典场景

    • 登录验证req.getParameter()拿账号密码 → 验证 → resp.sendRedirect()跳转

    • 数据显示:查询数据 → req.setAttribute()存数据 → 转发到JSP显示

    • 文件下载resp.getOutputStream()写文件流

4.doGet 和 doPost 的区别与例子

特性doGetdoPost
HTTP 方法处理 GET 请求处理 POST 请求
参数传递参数附加在 URL 之后(如:?name=张三&age=20参数放在 请求体 (Request Body)
安全性,参数在地址栏明文显示,可能被浏览器历史记录缓存较好,参数不在地址栏显示,也不会被缓存
数据长度限制(因浏览器和服务器对URL长度有限制)理论上无限制(实际上服务器可配置)
幂等性幂等(多次执行同一请求,效果相同)不幂等(多次提交可能会产生不同效果,如重复下单)
用途用于获取数据(如:搜索、查询页面)用于提交/修改数据(如:登录、注册、支付)

总结

  • 你用 method="get",表单数据就会显示在地址栏(LoginServlet?username=admin&password=123456),非常不安全,且doGet方法会被调用。

  • 你用 method="post",地址栏只有 LoginServlet,数据隐藏传输,doPost方法被调用。所以登录、注册等操作必须用POST

5.HttpServletRequest (req) 和 HttpServletResponse (resp) 的作用与例子

可以把一次HTTP请求和响应想象成一次顾客和服务员的对话

  • HttpServletRequest req (请求对象): 就像是顾客对服务员说的话。它包含了客户发来的所有信息。

  • HttpServletResponse resp (响应对象): 就像是服务员准备回复顾客的工具。你用它来组织你要返回给客户的内容。

总结

核心功能例子
req顾客获取信息:参数、URL、IP等;传递数据String name = req.getParameter("name");
resp服务员设置回应:内容类型、编码、状态码;发送数据resp.getWriter().println("Hello");

6.Servlet跳转到其他组件

1)第一种跳转方式:响应重定向

HttpServletResponse中定义了响应重定向的方法

– sendRedirect(String path)

响应重定向是向目标资源重新发送请求,生成新的响应

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {// 1. 获取参数String username = req.getParameter("username"); // 这里能拿到 "admin"String password = req.getParameter("password"); // 这里能拿到 "123456"// 2. 验证登录(假设成功)
// 3. 重定向到欢迎页面
resp.sendRedirect("WelcomeServlet"); // 问题就出在这里!}
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {// 尝试获取用户名String username = req.getParameter("username"); // 这里得到的是 null!resp.getWriter().println("欢迎你:" + username); // 显示"欢迎你:null"
}

为什么是 null?

1)因为 重定向的本质是让浏览器发起一个新的GET请求

  1. 第一次请求:浏览器 POST 提交表单到 LoginServlet,携带参数 username=admin&password=123456

  2. LoginServlet处理:收到参数,验证通过

  3. 响应重定向LoginServlet 返回302状态码和 Location: WelcomeServlet 头信息

  4. 浏览器动作:浏览器看到302,自动发起一个新的GET请求WelcomeServlet

  5. 第二次请求:这个新请求没有任何参数,就是单纯的访问 WelcomeServlet

  6. WelcomeServlet处理req.getParameter("username") 自然就拿不到值了

2)第二种跳转方式:请求转发
  1. 请求转发

    能够把当前的请求对象转发到目标资源,是最常用的跳转方法

  2. 使用步骤

    先使用请求中getRequestDispatcher(String path)方法获得请求转发器对象RequestDispatcher

    然后调用RequestDispatcher的forward(request,response)方法进行跳转 forward传参数

  3. 修改LoginServlet中的跳转方法

  4. 使用请求转发后,当前的请求对象被转发到下一个资源,因此可以得到请求对象中的数据,包括请求参数,请求方法等。在doPost中调用该方法,将调用下一个资源的doPost方法;在doGet方法中调用该方法,调用下一个资源的doGet方法

例子

请求转发简单例子

场景:用户登录成功后跳转到欢迎页面

LoginServlet.java

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 1. 设置编码req.setCharacterEncoding("UTF-8");// 2. 获取参数String username = req.getParameter("username");String password = req.getParameter("password");// 3. 模拟登录验证if ("admin".equals(username) && "123456".equals(password)) {// 登录成功,把用户名存到请求中req.setAttribute("welcomeMsg", "欢迎回来," + username + "!");// 4. 使用请求转发跳转到欢迎页面RequestDispatcher rd = req.getRequestDispatcher("WelcomeServlet");rd.forward(req, resp); // 关键代码!} else {// 登录失败resp.getWriter().println("登录失败!");}
}

WelcomeServlet.java

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("text/html;charset=UTF-8");PrintWriter out = resp.getWriter();// 可以直接获取LoginServlet中设置的属性String welcomeMsg = (String) req.getAttribute("welcomeMsg");// 也可以直接获取原始请求的参数(因为是一次请求)String username = req.getParameter("username"); // 这里能拿到值!out.println("<h1>" + welcomeMsg + "</h1>");out.println("<p>用户名: " + username + "</p>");
}

重定向 vs 转发(Forward)
特性重定向 (Redirect)转发 (Forward)
请求次数2次1次
地址栏变化(显示新URL)不变(显示原URL)
数据传递丢失原始请求参数保留原始请求参数和属性
实现方式resp.sendRedirect("url")req.getRequestDispatcher("url").forward(req, resp)

为什么浏览器地址栏显示的是 /login 而不是JSP路径?

因为:请求转发是服务器内部的行为,浏览器完全不知道发生了什么!

整个流程是这样的:
  1. 你在浏览器输入http://localhost:8080/login(访问Servlet)

  2. 浏览器向服务器发送请求:GET /login

  3. 服务器收到请求LoginServletdoGet() 方法被执行

  4. Servlet内部处理:验证登录、查询数据等

  5. Servlet决定转发req.getRequestDispatcher("welcome.jsp").forward(req, resp);

  6. 服务器内部跳转:服务器直接调用 welcome.jsp 来生成HTML内容

  7. 服务器返回响应:把JSP生成的HTML内容返回给浏览器

  8. 浏览器显示结果:显示JSP的内容,但地址栏仍然显示最初的 /login

这是正常且正确的行为!

优点:

  1. 隐藏技术细节:用户看不到JSP路径,更安全

  2. 保持URL整洁:逻辑URL(/login)和物理文件路径(welcome.jsp)分离

  3. 更好的SEO:统一的URL结构

http://www.dtcms.com/a/345166.html

相关文章:

  • Leetcode—1148. 文章浏览 I【简单】
  • AI重构消费决策:从AI试衣间降退货率到预判式复购,购物效率提升新逻辑
  • FROM Buggy_Code SELECT Liability_Causes # 民法典之故障代码责任溯源
  • Prompt工程完全指南:从基础结构到AI时代的上下文革命
  • 意识上传与智能增强:脑机接口与AI共塑的人类未来图景
  • 如何用批量钱包实现链上“身份伪装”?
  • PADS Logic软件及相关工具
  • s3cmd使用方法
  • 常见整流电路总结
  • 当我们想用GPU(nlp模型篇)
  • MySQL诊断系列(6/6):系统监控——实时掌握数据库“生命体征”
  • 【jar包启动,每天生成一个日志文件】
  • 本地 Graph-RAG(图 + RAG) 部署与使用落地方案
  • Unreal Engine AActor
  • 机器学习--线性回归
  • K8S - NetworkPolicy的使用
  • Spring发布订阅模式详解
  • 国产CANFD芯片技术特性与应用前景综述:以ASM1042系列为例
  • 宝可梦:去吧皮卡丘/去吧伊布 PC/手机双端(Pokemon-Lets Go Pikachu)免安装中文版
  • MeterSphere接口自动化共享cookie
  • 开发避坑指南(33):Mybatisplus QueryWrapper 自定义查询语句防注入解决方案
  • 【Cmake】Cmake概览
  • C2039 “unref“:不是“osgEarth::Symbology::Style”的成员 问题分析及解决方法
  • 【RA-Eco-RA4E2-64PIN-V1.0 开发板】步进电机驱动
  • 育教大师广州专插本培训机构指南
  • STM32项目分享:基于STM32的焊接工位智能排烟系统
  • 视频编码异常的表现
  • 【Linux系列】Linux 中替换文件中的字符串
  • 基于SpringBoot的考研学习交流平台【2026最新】
  • Nginx 创建和配置虚拟主机