🏐 ServletConfig 类的三大作用
1、可以获取 Servlet 程序的别名 servlet-name 的值
2、获取初始化参数 init-param
3、获取 ServletContext 对象
<servlet> <servlet-name>HelloServlet</servlet-name> <servlet-class>HelloServlet</servlet-class> <!-- 初始化参数 是一个键值对 --> <init-param> <!-- 初始化参数名 --> <param-name>username</param-name> <!-- 初始化参数值 --> <param-value>root</param-value> </init-param> <init-param> <param-name>password</param-name> <param-value>123456</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>
@Override public void init(ServletConfig servletConfig) throws ServletException { // System.out.println("2.初始化方法被调用"); // 1、可以获取 Servlet 程序的别名 servlet-name 的值 System.out.println("Servlet 程序的别名: " + servletConfig.getServletName()); // 2、获取初始化参数 init-param System.out.println("初始化参数username的值: " + servletConfig.getInitParameter("username")); System.out.println("初始化参数password的值: " + servletConfig.getInitParameter("password")); // 3、获取 ServletContext 对象 System.out.println("ServletContext 对象" + servletConfig.getServletContext()); }
⚽ ServletContext 类
- 1、ServletContext 是一个接口,它表示 Servlet 上下文对象
- 2、一个 web 工程,只有一个 ServletContext 对象实例。
- 3、ServletContext 对象是一个域对象。
- 什么是域对象?
- 域对象,是可以像 Map 一样存取数据的对象,叫域对象。
- 这里的域指的是存取数据的操作范围,整个 web 工程。
- 4、ServletContext 是在 web 工程部署启动的时候创建。在 web 工程停止的时候销毁。
🏐 ServletContext 类的四个作用
- 1、获取 web.xml 中配置的上下文参数 context-param
- 2、获取当前的工程路径,格式: /工程路径
- 3、获取工程部署后在服务器硬盘上的绝对路径
- 4、像 Map 一样存取数据
<web-app ... > <!--context-param 是上下文参数(它属于整个 web 工程)--> <context-param> <param-name>username</param-name> <param-value>context</param-value> </context-param> <!--context-param 是上下文参数(它属于整个 web 工程)--> <context-param> <param-name>password</param-name> <param-value>root</param-value> </context-param> ... <servlet> <servlet-name>ContextServlet</servlet-name> <servlet-class>ContextServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>ContextServlet</servlet-name> <url-pattern>/context</url-pattern> </servlet-mapping> </web-app>
@Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取ServletContext对象 ServletContext servletContext = getServletContext(); //- 1、获取 web.xml 中配置的上下文参数 context-param System.out.println("contest-param username: " + servletContext.getInitParameter("username")); System.out.println("contest-param password: " + servletContext.getInitParameter("password")); //- 2、获取当前的工程路径,格式: /工程路径 System.out.println("当前工程路径: " + servletContext.getContextPath()); //- 3、获取工程部署后在服务器硬盘上的绝对路径 // / 斜杠被服务器解析地址为:http://ip:port/工程名/ 映射到 IDEA 代码的 web 目录 System.out.println("工程部署后在服务器硬盘上的绝对路径" + servletContext.getRealPath("/")); System.out.println("工程下WEB-INF目录在服务器硬盘上的绝对路径" + servletContext.getRealPath("/WEB-INF")); //- 4、像 Map 一样存取数据 System.out.println("数据保存前获取" + servletContext.getAttribute("key1")); servletContext.setAttribute("key1", "value1"); System.out.println("数据保存后获取" + servletContext.getAttribute("key1")); }
⚽ HTTP 协议
协议是指双方,或多方,相互约定好,大家都需要遵守的规则,叫协议。所谓 HTTP 协议,就是指,客户端和服务器之间通信时,发送的数据,需要遵守的规则,叫 HTTP 协议。HTTP 协议中的数据又叫报文。
客户端给服务器发送数据叫请求。服务器给客户端回传数据叫响应。
🏐 请求的 HTTP 协议格式
🏐 常用请求头
- Accept: 表示客户端可以接收的数据类型
- Accpet-Languege: 表示客户端可以接收的语言类型
- User-Agent: 表示客户端浏览器的信息
- Host: 表示请求时的服务器 ip 和端口号
🏐 哪些是 GET 请求,哪些是 POST 请求
- GET 请求有哪些:
- 1、form 标签 method=get
- 2、a 标签
- 3、link 标签引入 css
- 4、Script 标签引入 js 文件
- 5、img 标签引入图片
- 6、iframe 引入 html 页面
- 7、在浏览器地址栏中输入地址后敲回车
- POST 请求有哪些:
- 8、form 标签 method=post
🏐 响应的 HTTP 协议格式
🏐 常用的响应码
- 200 表示请求成功
- 302 表示请求重定向
- 404 表示请求服务器已经收到了,但是你要的数据不存在(请求地址错误)
- 500 表示服务器已经收到请求,但是服务器内部错误(代码错误)
🏐 MIME 类型说明
MIME 是 HTTP 协议中数据类型。MIME 的英文全称是"Multipurpose Internet Mail Extensions" 多功能 Internet 邮件扩充服务。
MIME 类型的格式是“大类型/小类型”,并与某一种文件的扩展名相对应。
常见的 MIME 类型:
⚽ HttpServletRequest 类
🏐 HttpServletRequest 类的作用
每次只要有请求进入 Tomcat 服务器,Tomcat 服务器就会把请求过来的HTTP 协议信息解析好封装到 Request 对象中。然后传递到 service 方法(doGet 和 doPost)中给我们使用。我们可以通过 HttpServletRequest 对象,获取到所有请求的信息。
🏐 HttpServletRequest 类的常用方法
- getRequestURI() 获取请求的资源路径
- getRequestURL() 获取请求的统一资源定位符(绝对路径)
- getRemoteHost() 获取客户端的 ip 地址
- getHeader() 获取请求头
- getParameter() 获取请求的参数
- getParameterValues() 获取请求的参数(获取的请求参数有多个值的时候使用)
- getMethod() 获取请求的方式 GET 或 POST
- setAttribute(key, value); 设置域数据
- getAttribute(key); 获取域数据
- getRequestDispatcher() 获取请求转发对象
@Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //- getRequestURI() 获取请求的资源路径 System.out.println("URI =>" + request.getRequestURI()); //- getRequestURL() 获取请求的统一资源定位符(绝对路径) System.out.println("URL =>" + request.getRequestURL()); //- getRemoteHost() 获取客户端的 ip 地址 // 使用localhost访问得到的客户端IP地址为127.0.0.1 // 使用127.0.0.1访问得到的客户端IP地址为127.0.0.1 // 使用服务器真实的IP访问得到的客户端IP地址为真实的客户端IP System.out.println("客户端 IP =>" + request.getRemoteHost()); //- getHeader() 获取请求头 System.out.println("请求头 User-Agent =>" + request.getHeader("User-Agent")); //- getMethod() 获取请求的方式 GET 或 POST System.out.println("请求方式 =>" + request.getMethod()); // 设置请求体的字符集为UTF-8防止获取Post请求参数时中文乱码问题 // 获取请求参数前调用才有效 request.setCharacterEncoding("UTF-8"); //- getParameter() 获取请求的参数 System.out.println("请求参数 username =>" + request.getParameter("username")); //- getParameterValues() 获取请求的参数(获取的请求参数有多个值的时候使用) System.out.println("请求参数 =>" + request.getParameterValues("hobby").toString()); }
🏐 请求的转发
请求转发是指,服务器收到请求后,从一次资源跳转到另一个资源的操作叫请求转发。
public class Servlet1 extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取请求的参数(办事的材料)查看 String username = request.getParameter("username"); System.out.println("在 Servlet1(柜台 1)中查看参数(材料):" + username); // 给材料 盖一个章,并传递到 Servlet2(柜台 2)去查看 // 设置一个域数据 request.setAttribute("key1", "柜台 1 的章"); // 问路:Servlet2(柜台 2)怎么走 // 获取到Servlet2的请求转发路径 // 请求转发必须要以斜杠打头,/ 斜杠表示地址为:http://ip:port/工程名/ , 映射到 IDEA 代码的 web 目录 RequestDispatcher requestDispatcher = request.getRequestDispatcher("/servlet2"); // RequestDispatcher requestDispatcher = req.getRequestDispatcher("http://www.baidu.com"); // 走向 Sevlet2(柜台 2) // 并将请求对象和响应对象传递过去 requestDispatcher.forward(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }
public class Servlet2 extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取请求的参数(办事的材料)查看 String username = request.getParameter("username"); System.out.println("在 Servlet2(柜台 2)中查看参数(材料):" + username); // 查看 柜台 1 是否有盖章 Object key1 = request.getAttribute("key1"); System.out.println("柜台 1 是否有章:" + key1); // 处理自己的业务 System.out.println("Servlet2 处理自己的业务 "); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }
- 请求转发的特点:
- 浏览器地址栏没有变化
- 请求转发中处理的第二个servlet程序域第一个servlet程序为同一个请求
- 请求转发中不同的servlet程序共享request域中的数据
- 请求转发可以访问WEB-INF目录下的资源
- 请求转发不能访问工程以外的资源
⚽ base标签
base 标签可以设置页面相对路径工作时,参照哪个路径进行跳转。
在页面进行跳转时会先看页面中是否有base标签,如果页面中设置了base标签,则页面进行跳转会参照base标签href属性中的地址进行跳转。
<!DOCTYPE html> <html lang="zh_CN"> <head> <meta charset="UTF-8"> <title>Title</title> <!-- base 标签设置页面相对路径工作时参照的地址 href 属性就是参数的地址值 地址中的资源文件可以省略,但是最后的 / 不能省略,有 / 才表示b/是一层目录 --> <base href="http://localhost:8080/07_servlet/a/b/"> </head> <body> 这是 a 下的 b 下的 c.html 页面<br/> <a href="../../index.html">跳回首页</a><br/> </body> </html>
⚽ web 中 / 斜杠的不同意义
在 web 中 / 斜杠 是一种绝对路径。
- / 斜杠 如果被浏览器解析,得到的地址是:http://ip:port/
<a href="/">斜杠</a>
- / 斜杠 如果被服务器解析,得到的地址是:http://ip:port/工程路径
<url-pattern>/servlet1</url-pattern>中的 / servletContext.getRealPath(“/”); request.getRequestDispatcher(“/”);
- 特殊情况:
response.sendRediect(“/”);
(请求重定向) 把斜杠发送给浏览器解析。得到 http://ip:port/
⚽ HttpServletResponse 类
🏐 HttpServletResponse 类的作用
HttpServletResponse 类和 HttpServletRequest 类一样。每次请求进来,Tomcat 服务器都会创建一个 Response 对象传递给 Servlet 程序去使用。
HttpServletRequest 表示请求过来的信息,HttpServletResponse 表示所有响应的信息,我们如果需要设置返回给客户端的信息,都可以通过 HttpServletResponse 对象来进行设置。
🏐 两个响应流的说明
- 字节流
- 获取:response.getOutputStream();
- 常用于下载(传递二进制数据)
- 字符流
- 获取:response.getWriter();
- 常用于回传字符串(常用)
- 两个流同时只能使用一个。使用了字节流,就不能再使用字符流,反之亦然,否则就会报错。
🏐 往客户端回传数据
@Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取字符流 PrintWriter writer = response.getWriter(); // 向客户端传递字符串数据 writer.write("服务端回传的字符串数据"); }
🏐 响应的乱码解决
响应字符的默认编码为ISO-8859-1
@Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 响应字符的默认编码 System.out.println(response.getCharacterEncoding()); // 获取字符流 PrintWriter writer = response.getWriter(); // 向客户端传递字符串数据 writer.write("服务端回传的字符串数据"); }
解决响应中文乱码方案一(不推荐使用):
// 设置服务器字符集为 UTF-8 resp.setCharacterEncoding("UTF-8"); // 通过响应头,设置浏览器也使用 UTF-8 字符集 resp.setHeader("Content-Type", "text/html; charset=UTF-8");
解决响应中文乱码方案二(推荐):
// 它会同时设置服务器和客户端都使用 UTF-8 字符集,还设置了响应头 // 此方法一定要在获取流对象之前调用才有效 resp.setContentType("text/html; charset=UTF-8");
@Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 响应字符的默认编码 System.out.println(response.getCharacterEncoding()); // 它会同时设置服务器和客户端都使用 UTF-8 字符集,还设置了响应头 // 此方法一定要在获取流对象之前调用才有效 response.setContentType("text/html; charset=UTF-8"); System.out.println(response.getCharacterEncoding()); // 获取字符流 PrintWriter writer = response.getWriter(); // 向客户端传递字符串数据 writer.write("服务端回传的字符串数据"); }
⚽ 请求重定向
请求重定向,是指客户端给服务器发请求,然后服务器告诉客户端说。我给你一些地址。你去新地址访问。叫请求重定向(因为之前的地址可能已经被废弃)。
请求重定向的第一种方案:
// 设置响应状态码 302 ,表示重定向,(已搬迁) response.setStatus(302); // 设置响应头,说明 新的地址在哪里 response.setHeader("Location", "http://localhost:8080/JavaWeb01_war_exploded/servlet2");
public class Servlet1 extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("访问Servlet1"); // 设置响应状态码 302 ,表示重定向,(已搬迁) response.setStatus(302); // 设置响应头,说明 新的地址在哪里 response.setHeader("Location", "http://localhost:8080/JavaWeb01_war_exploded/servlet2"); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }
public class Servlet2 extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("访问Servlet2"); // 设置编码 response.setContentType("text/html; charset=UTF-8"); // 响应数据 response.getWriter().write("当前访问的为Servlet2"); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }
请求重定向的第二种方案(推荐使用):
public class Servlet1 extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("访问Servlet1"); // 设置响应状态码 302 ,表示重定向,(已搬迁) // response.setStatus(302); // 设置响应头,说明 新的地址在哪里 // response.setHeader("Location", "http://localhost:8080/JavaWeb01_war_exploded/servlet2"); response.sendRedirect("http://localhost:8080/JavaWeb01_war_exploded/servlet2"); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }
- 请求重定向的特点
- 浏览器地址栏会发生变化
- 会进行两次请求
- 两次请求不共享request域的数据,每次请求都会封装一个request对象
- 不能访问WEB-INF目录下的资源,WEB-INF目录在通过浏览器访问时受保护
- 可以访问工程外的资源
🏀 JSP
⚽ JSP概述
- jsp 的全称是 java server pages。Java 的服务器页面。
- jsp 的主要作用是代替 Servlet 程序回传 html 页面的数据。
- 因为 Servlet 程序回传 html 页面数据是一件非常繁锁的事情。开发成本和维护成本都极高。
public class PringHtml extends HttpServlet { @Override protected void doGet(HttpServletRequest req,HttpServletResponse resp) throws ServletException,IOException { // 通过响应的回传流回传 html 页面数据 // 设置编码格式 resp.setContentType("text/html; charset=UTF-8"); // 获取响应流 PrintWriter writer = resp.getWriter(); // 向浏览器回传响应html页面 writer.write("<!DOCTYPE html>\r\n"); writer.write(" <html lang=\"en\">\r\n"); writer.write(" <head>\r\n"); writer.write(" <meta charset=\"UTF-8\">\r\n"); writer.write(" <title>Title</title>\r\n"); writer.write(" </head>\r\n"); writer.write(" <body>\r\n"); writer.write(" 这是 html 页面数据 \r\n"); writer.write(" </body>\r\n"); writer.write("</html>\r\n"); writer.write("\r\n"); } }
- jsp 页面和 html 页面一样,都是存放在 web 目录下。访问也跟访问 html 页面一样。web 目录下,a.html 页面访问地址是 http://ip:port/工程路径/a.html;b.jsp 页面访问地址是 http://ip:port/工程路径/b.jsp。
- jsp 页面本质上是一个 Servlet 程序。当我们第一次访问 jsp 页面的时候。Tomcat 服务器会帮我们把 jsp 页面翻译成为一个 java 源文件。并且对它进行编译成为.class 字节码程序。jsp 翻译出来的 java 类,它间接了继
承了 HttpServlet 类。也就是说,翻译出来的是一个 Servlet 程序。 - jsp 翻译出来的 java 类,其底层实现,也是通过输出流,把 html 页面数据回传给客户端。
⚽ jsp 头部的 page 指令
jsp 的 page 指令可以修改 jsp 页面中一些重要的属性,或者行为。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
- language 属性:表示 jsp 翻译后是什么语言文件,暂时只支持 java。
- contentType 属性:表示 jsp 返回的数据类型是什么,也是源码中response.setContentType()参数值
- pageEncoding 属性:表示当前 jsp 页面文件本身的字符集。
- import 属性:跟 java 源代码中一样,用于导包,导类。
- autoFlush 属性:该属性是给 out 输出流使用,设置当 out 输出流缓冲区满了之后,是否自动刷新缓冲区。默认值是 true。
- buffer 属性:该属性是给 out 输出流使用,设置 out 缓冲区的大小。默认是 8kb
- errorPage 属性:设置当 jsp 页面运行时出错,自动跳转去的错误页面路径。这个路径一般都是以斜杠打头,它表示请求地址为 http://ip:port/工程路径/,(斜杠由服务器解析)映射到代码的 Web 目录。
- isErrorPage 属性:设置当前 jsp 页面是否是错误信息页面。默认是 false。如果是 true 可以获取异常信息。
- session 属性:设置访问当前 jsp 页面,是否会创建 HttpSession 对象。默认是 true。
- extends 属性:设置 jsp 翻译出来的 java 类默认继承谁。
⚽ jsp 中的常用脚本
🏐 声明脚本
- 声明脚本的格式是:
<%! 声明 java 代码 %>
- 作用:可以给 jsp 翻译出来的 java 类定义属性和方法甚至是静态代码块。内部类等。
<%@ page import="java.util.HashMap" %> <%@ page import="java.util.Map" %><%-- Created by IntelliJ IDEA. User: cw Date: 2023-01-01 Time: 17:15 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>$Title$</title> </head> <body> <h1>HELLO WORLD!!!</h1> <%--1、声明类属性--%> <%! private Integer id; private String name; private static Map<String, Object> map; %> <%--2、声明 static 静态代码块--%> <%! static { map = new HashMap<String, Object>(); map.put("key1", "value1"); map.put("key2", "value2"); map.put("key3", "value3"); } %> <%--3、声明类方法--%> <%! public int abc() { return 12; } %> <%--4、声明内部类--%> <%! public static class A { private Integer id = 12; private String abc = "abc"; } %> </body> </html>
声明脚本代码翻译对照:
🏐 表达式脚本
- 表达式脚本的格式是:
<%= 表达式 %>
- 表达式脚本的作用是:在 jsp 页面上输出数据。
- 表达式脚本的特点:
- 1、所有的表达式脚本都会被翻译到_jspService() 方法中
- 2、表达式脚本都会被翻译成为 out.print()输出到页面上
- 3、由于表达式脚本翻译的内容都在_jspService() 方法中,所以_jspService()方法中的对象都可以直接使用。
- 4、表达式脚本中的表达式不能以分号结束。
<%@ page import="java.util.HashMap" %> <%@ page import="java.util.Map" %><%-- Created by IntelliJ IDEA. User: cw Date: 2023-01-01 Time: 17:15 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>$Title$</title> </head> <body> <h1>HELLO WORLD!!!</h1> <%! private Integer id; private String name; private static Map<String, Object> map; %> <%! static { map = new HashMap<String, Object>(); map.put("key1", "value1"); map.put("key2", "value2"); map.put("key3", "value3"); } %> <!-- 表达式脚本 --> <%= 12 %> <br> <%= 12.12 %> <br> <%= "我是字符串" %> <br> <%= map %> <br> <%= request.getParameter("username") %> </body> </html>
翻译对照:
🏐 代码脚本
- 代码脚本的格式是:
<% java 语句 %>
- 代码脚本的作用是:可以在 jsp 页面中,编写我们自己需要的功能(写的是 java 语句)。
- 代码脚本的特点是:
- 1、代码脚本翻译之后都在_jspService 方法中
- 2、代码脚本由于翻译到_jspService()方法中,所以在_jspService()方法中的现有对象都可以直接使用。
- 3、还可以由多个代码脚本块组合完成一个完整的 java 语句。
- 4、代码脚本还可以和表达式脚本一起组合使用,在 jsp 页面上输出数据
<%@ page import="java.util.HashMap" %> <%@ page import="java.util.Map" %><%-- Created by IntelliJ IDEA. User: cw Date: 2023-01-01 Time: 17:15 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>$Title$</title> </head> <body> <%--1.代码脚本----if 语句--%> <% int i = 13; if (i == 12) { %> <h1>Hello</h1> <% } else { %> <h1>World</h1> <% } %> <br> <%--2.代码脚本----for 循环语句--%> <table border="1" cellspacing="0"> <% for (int j = 0; j < 10; j++) { %> <tr> <td>第 <%=j + 1%>行</td> </tr> <% } %> </table> <%--3.翻译后 java 文件中_jspService 方法内的代码都可以写--%> <% String username = request.getParameter("username"); System.out.println("用户名的请求参数值是:" + username); %> </body> </html>
🏐 jsp 中的三种注释
- html 注释:
<!-- 这是 html 注释 -->
- html 注释会被翻译到 java 源代码中。在_jspService 方法里,以 out.writer 输出到客户端。
- java 注释:
- java 注释一般写在声明脚本或代码脚本中。
<% // 单行 java 注释 /* 多行 java 注释 */ %>
- java 注释会被翻译到 java 源代码中。
- jsp 注释
<%-- 这是 jsp 注释 --%>
- jsp 注释可以注掉,jsp 页面中所有代码。
⚽ jsp 九大内置对象
jsp 中的内置对象,是指 Tomcat 在翻译 jsp 页面成为 Servlet 源代码后,内部提供的九大对象,叫内置对象。
- jsp 九大内置对象
- request:请求对象
- response:响应对象
- pageContext:jsp的上下文对象
- session:会话对象
- application:ServletContext对象
- config:ServletConfig对象
- out:jsp输出流对象
- page:指向当前jsp的对象
- exception:异常对象
⚽ jsp 四大域对象
- 四个域对象分别是
- pageContext (PageContextImpl 类):当前 jsp 页面范围内有效
- request (HttpServletRequest 类):一次请求内有效
- session (HttpSession 类):一个会话范围内有效(打开浏览器访问服务器,直到关闭浏览器)
- application (ServletContext 类):整个 web 工程范围内都有效(只要 web 工程不停止,数据都在)该对象在web工程开始运行时创建,在web工程结束时销毁
- 域对象是可以像 Map 一样存取数据的对象。
- 四个域对象功能一样。不同的是它们对数据的存取范围。
- 虽然四个域对象都可以存取数据,但是在使用上它们是有优先顺序的。四个域在使用的时候,优先顺序分别是(范围从小到大的顺序)。pageContext ====>>> request ====>>> session ====>>> application。有效范围小的优先使用,可以使得不需要使用的对象或数据及时被释放,减小服务器压力。
⚽ jsp 中的 out 输出和 response.getWriter 输出的区别
- response表示响应,经常用于设置返回给客户端的内容(输出),out 也是给用户做输出使用的。
- 由于 jsp 翻译之后,底层源代码都是使用 out 来进行输出,所以一般情况下,我们在 jsp 页面中统一使用 out 来进行输出。避免打乱页面输出内容的顺序。
- out.write() 用于输出字符串,out.print() 用于输出任意数据(底层都会将数据转换成为字符串后调用的 write 输出,write在底层会将数据的每个组成元素转化为字符放入缓冲区,有些数据转化可能会出现问题)
- 在 jsp 页面中,可以统一使用 out.print()来进行输出
⚽ jsp 的常用标签
🏐 jsp 静态包含
- 语法:
<%@ include file=""%>
,file 属性指定你要包含的 jsp 页面的路径,地址中第一个斜杠 / 表示为 http://ip:port/工程路径/ 映射到代码的 web 目录。 - jsp 静态包含,可以实现将页面进行模块的拆分,在需要使用的位置进行引入,提高代码的复用与可维护性
🏐 jsp 动态包含
- 语法:
<jsp:include page=""></jsp:include>
,page 属性是指定你要包含的 jsp 页面的路径 - 动态包含也可以实现将页面进行模块的拆分,在需要使用的位置进行引入
- 动态包含会把包含的 jsp 页面也翻译成为 java 代码,而静态包含不会
- 静态包含其实是把被包含的 jsp 页面的代码拷贝到包含的位置执行输出,动态包含底层代码使用如下代码去调用被包含的 jsp 页面执行输出,
JspRuntimeLibrary.include(request, response, "/include/footer.jsp", out, false);
- 动态包含的底层原理:
- 动态包含可以传递参数
<jsp:include page="/include/footer.jsp"> <jsp:param name="username" value="bbj"/> <jsp:param name="password" value="root"/> </jsp:include> // 获取传递的参数 request.getParameter("参数的name")
🏐 jsp 标签 - 请求转发
语法:<jsp:forward page=""></jsp:forward>
,是请求转发标签,它的功能就是请求转发,page 属性设置请求转发的路径。
<jsp:forward page="/scope2.jsp"></jsp:forward>
🏐 jsp 请求转发说明
客户端浏览器将请求发给servlet程序,servlet程序进行相应的数据处理,将数据保存在request域中给jsp页面,然后再请求转发给jsp页面,jsp页面从request域中取出数据展示到页面上。
servlet程序用于数据处理,jsp页面用于数据的展示。
🏀 Listener 监听器
- Listener 监听器它是 JavaWeb 的三大组件之一。JavaWeb 的三大组件分别是:Servlet 程序、Filter 过滤器、Listener 监听器。
- Listener 它是 JavaEE 的规范,就是接口
- 监听器的作用是,监听某种事物的变化,然后通过回调函数,反馈给客户(程序)去做一些相应的处理。
⚽ ServletContextListener 监听器
- ServletContextListener 它可以监听 ServletContext 对象的创建和销毁。
- ServletContext 对象在 web 工程启动的时候创建,在 web 工程停止的时候销毁。
- 监听到创建和销毁之后都会分别调用 ServletContextListener 监听器的方法反馈。两个方法分别是:
- contextInitialized(ServletContextEvent sce):在 ServletContext 对象创建之后马上调用,可以用于做初始化
- contextDestroyed(ServletContextEvent sce):在 ServletContext 对象销毁之后调用
- 如何使用 ServletContextListener 监听器监听 ServletContext 对象。
- 1、编写一个类去实现 ServletContextListener
- 2、实现其两个回调方法
- 3、到 web.xml 中去配置监听器
public class MyServletContextListenerImpl implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { System.out.println("ServletContext 对象被创建了"); } @Override public void contextDestroyed(ServletContextEvent sce) { System.out.println("ServletContext 对象被销毁了"); } }
<?xml version="1.0" encoding="UTF-8"?> <web-app ...> <!--配置监听器--> <listener> <listener-class>MyServletContextListenerImpl</listener-class> </listener> ... </web-app>
🏀 EL 表达式
- EL 表达式的全称是:Expression Language,表达式语言。
- EL 表达式的作用:EL 表达式主要是代替 jsp 页面中的表达式脚本在 jsp 页面中进行数据的输出。因为 EL 表达式在输出数据的时候,要比 jsp 的表达式脚本要简洁很多。
- EL 表达式的格式是:
${表达式}
- EL 表达式在输出 null 值的时候,输出的是空串。jsp 表达式脚本输出 null 值的时候,输出的是 null 字符串。
<body> <% // 向request域中存储数据 request.setAttribute("key","value"); Object num = null; %> <%=num%><br/> ${num}<br/> 表达式脚本输出 key 的值是: <%=request.getAttribute("key")==null?"":request.getAttribute("key")%><br/> <!--EL表达式取出request域中的数据直接使用键名即可--> EL 表达式输出 key 的值是:${key} </body>
⚽ EL 表达式搜索域数据的顺序
- EL 表达式主要是在 jsp 页面中输出数据。主要是输出域对象中的数据。
- EL 表达式搜索域数据的顺序:当四个域(pageContext、request、session、application)中都有相同的 key 的数据的时候,EL 表达式会按照四个域有效的范围从小到大的顺序去进行搜索,找到就输出。
<% //往四个域中都保存了相同的 key 的数据。 pageContext.setAttribute("key", "pageContext"); request.setAttribute("key", "request"); session.setAttribute("key", "session"); application.setAttribute("key", "application"); %> <p>key:${key}</p>