• 注册
  • 后端开发博客 后端开发博客 关注:0 内容:2357

    一文把Servlet整的明明白白

  • 查看作者
  • 打赏作者
  • 当前位置: 职业司 > 后端开发 > 后端开发博客 > 正文
    • 后端开发博客
    • 「本文已参与好文召集令活动,点击查看:后端、大前端双赛道投稿,2万元奖池等你挑战!」

      一、Servlet概述

      1.1、Servlet是什么

      一文把Servlet整的明明白白

      1. Servlet 是 JavaEE 规范之一。规范就是接口。
      2. Servlet 就 JavaWeb 三大组件之一。三大组件分别是:Servlet 程序、Filter 过滤器、Listener 监听器。
      3. Servlet 是运行在服务器上的一个 java 小程序,它可以接收客户端发送过来的请求,并响应数据给客户端。

      简单来说:Servlet 是运行在 Web服务器(如Tomcat服务器)的,使用 Java编写的小应用程序。

      1.2、Servlet的示范

      一文把Servlet整的明明白白

      public class HelloServlet implements Servlet {
      /**
      * service 方法是专门用来处理请求和响应的
      * @param servletRequest
      * @param servletResponse
      * @throws ServletException
      * @throws IOException
      */
      @Override
      public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
      System.out.println("Hello Servlet 被访问了");
      }
      }
      复制代码
      <?xml version="1.0"encoding="UTF-8"?>
      <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
       链接"
      version="4.0">
      <!--servlet 标签给 Tomcat 配置 Servlet 程序-->
      <servlet>
      <!--servlet-name 标签 Servlet 程序起一个别名(一般是类名) -->
      <servlet-name>HelloServlet</servlet-name>
      <!--servlet-class 是 Servlet 程序的全类名-->
      <servlet-class>com.servlet.HelloServlet</servlet-class>
      </servlet>
      <!--servlet-mapping 标签给 servlet 程序配置访问地址-->
      <servlet-mapping>
      <!--servlet-name 标签的作用是告诉服务器,我当前配置的地址给哪个 Servlet 程序使用-->
      <servlet-name>HelloServlet</servlet-name>
      <!--url-pattern 标签配置访问地址<br/>
      /斜杠在服务器解析的时候,表示地址为: 链接工程路径
      <br/>
      /hello 表示地址为: 链接工程路径/hello
      <br/>
      -->
      <url-pattern>/hello</url-pattern>
      </servlet-mapping>
      </web-app>
      复制代码

      1.3、常见错误

      1.3.1、url-pattern 中配置的路径没有以斜杠打头

      一文把Servlet整的明明白白

      1.3.2、servlet-name 配置的值不存在

      一文把Servlet整的明明白白

      二、Servlet生命周期

      2.1、Servlet生命周期

      ​ Servlet 对象的生命周期:Servlet 创建对象-->初始化操作--> 运行操作-->销毁操作

      ​ Web 服务器管理了 Servlet 的生命周期,Servlet 对象整个过程都是 Web 服务器来管理的。

      一文把Servlet整的明明白白

      2.2、Servlet 接口中生命周期方法

      生命周期方法 作用 运行次数
      构造方法 在对象实例化的时候执行
      必须有公共的无参数构造方法
      1次
      void init(ServletConfig config) 在初始化的时候执行 1次
      void service(ServletRequest req, ServletResponse res) 每次请求都会执行 n次
      void destroy() 在服务器正常关闭的时候 1次

      2.3、Servlet的请求流程

      一文把Servlet整的明明白白

      localhost:8080/one/hello
      # 1. 浏览器发送请求,Tomcat接收到请求并通过结息请求地址来获取到要访问的项目路径和资源路径。
      项目路径:/one
      资源路径:/hello
      # 2. Tomcat会扫描服务器内部的one项目下的所有Servlet,获取每一个Servlet的访问地址,并存储到一个集合中。资源路径作为ket,类的全限定名作为value。
      Map<String,String> map = new HashMap<>();
      map.put("/one","com.servlet.HelloServlet");
      # 3. 将资源路径/one作为key从map中获取value,得到了类的全限定名。
      # 4. 他会预先创建一个Servlet实例缓存池(key是Servlet的全限定名,value是Servlet的实例对象),拿着找到的key,去servletmap中寻找,如果找得到说明不是第一次访问,如果找不到,说明是第一次访问。
      Map<String,Servlet> servletmap = new HashMap<>();
      if(servletmap.get(“全限定名”) == null){
      		// 第一次访问,执行第5步
      } else{
      // 第N次,直接执行第7步
      }
      # 5. 通过反射实例化这个Servlet对象,并放入实例缓存池中。
      # 6. Tomcat创建ServletConfig对象,然后调用init方法,传入创建的Servlet对象
      # 7. 创建HttpRequest和HttpResponse对象,并调用service方法,传入HttpRequest和HttpResponse对象。
      # 8. 等待下一次访问。
      复制代码

      2.4、Servlet的继承体系

      一文把Servlet整的明明白白

      2.4.1、GenericServlet类

      一文把Servlet整的明明白白

      ​ 默认实现了 Servlet 和 ServletConfig 这两个接口,它的子类是 HttpServlet,如果我们写的Servlet使用的是 Http 协议。

      package cn.servlet;
      import javax.servlet.GenericServlet;
      import javax.servlet.ServletException;
      import javax.servlet.ServletRequest;
      import javax.servlet.ServletResponse;
      import javax.servlet.annotation.WebServlet;
      import java.io.IOException;
      @WebServlet(urlPatterns = "/demo")
      public class DemoServlet extends GenericServlet {
      @Override
      public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
      System.out.println("我是GenericServlet子类");
      }
      }
      复制代码

      2.4.2、HttpServlet类

      一文把Servlet整的明明白白

      package cn.httpservlet;
      import javax.servlet.ServletException;
      import javax.servlet.annotation.WebServlet;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      @WebServlet(urlPatterns = "/demo02")
      public class DemoServlet extends HttpServlet {
      @Override
      protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      System.out.println("我是HttpServlet的子类");
      }
      }
      复制代码

      2.4.3、小结

      1. GenericServlet 是一个通用的 Servlet,可以用来处理各种协议发出的请求和响应。

      2. HttpServlet 是专门用来处理 HTTP 协议发送的请求,现在所有的浏览器发请求都是使用 HTTP 协议,因此以后我们开发 Servlet 只需要继承 HttpServlet 即可,可以按照如下步骤开发:

      1. 创建类继承 HttpServlet
      2. 重写参数带着 Http 开头的 service 方法:在该方法中处理请求并响应数据。
      注意事项:不要在该方法中调用父类的 service 方法(405)
      复制代码

      2.5、ServletConfig 类

      ​ ServletConfig 类从类名上来看,就知道是 Servlet 程序的配置信息类。

      ​ Servlet 程序和 ServletConfig 对象都是由 Tomcat 负责创建,我们负责使用。
      ​ Servlet 程序默认是第一次访问的时候创建,ServletConfig 是每个 Servlet 程序创建时,就创建一个对应的 ServletConfig 对象。

      2.5.1、ServletConfig 类的三大作用

      1. 可以获取 Servlet 程序的别名 servlet-name 的值。
      2. 获取初始化参数 init-param。
      3. 获取 ServletContext 对象。

      2.5.2、常用方法

      ServletConfig接口常用方法 说明
      String getInitParameter("参数名") 通过指定的参数名得到参数

      2.5.3、使用演示

      ​ 根据不同的编码格式响应数据给浏览器,编码格式作为Servlet的初始化配置参数,在Servlet的service方法中读取初始化配置参数并输出。

      public class ServletConfigServlet extends HttpServlet {
      @Override
      protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      // 获得配置对象
      ServletConfig config = this.getServletConfig();
      // 获得初始化参数值
      String encoding = config.getInitParameter("encoding");
      if ("utf-8".equalsIgnoreCase(encoding)){
      // 模拟响应数据给浏览器
      System.out.println("执行utf-8编码操作");
      } else {
      // 模拟响应数据给浏览器
      System.out.println("执行gbk编码操作");
      }
      }
      }
      复制代码
      <servlet>
      <!--servlet名字-->
      <servlet-name>ServletConfigServlet</servlet-name>
      <!--servlet全限定名-->
      <servlet-class>com.servlet</servlet-class>
      <init-param>
      <!--参数名-->
      <param-name>encoding</param-name>
      <!--参数值-->
      <param-value>utf-8</param-value>
      </init-param>
      </servlet>
      <!--servlet的访问地址-->
      <servlet-mapping>
      <!--servlet名字:必须与上面的servlet名字相同-->
      <servlet-name>ServletConfigServlet</servlet-name>
      <!--浏览器访问的地址,必须以/打头-->
      <url-patten>ServletConfigServlet</url-patten>
      </servlet-mapping>
      复制代码

      2.6、ServletContext 类

      2.6.1、ServletContext概述

      ​ ServletContext 是一个接口,它表示 Servlet 上下文对象,**一个 web 工程,只有一个 ServletContext 对象实例。**ServletContext 对象是一个域对象。ServletContext 是在 web 工程部署启动的时候创建。在 web 工程停止的时候销毁。

      2.6.2、ServletContext 类的四个作用

      1. 获取 web.xml 中配置的上下文参数 context-param。
      2. 获取当前的工程路径,格式: /工程路径。
      3. 获取工程部署后在服务器硬盘上的绝对路径。
      4. 像 Map 一样存取数据

      2.7、域对象

      ​ 域对象,是可以像 Map 一样存取数据的对象,叫域对象。这里的域指的是存取数据的操作范围,整个 web 工程。

      ​ 他的作用是数据共享。

      存数据 取数据 删除数据
      map put() get() remove()
      域对象 setAttribute() getAttribute() removeAttribute()

      2.8、 loadOnStartup

      ​ 让 web 容器启动的时候创建并初始化 Servlet。取值范围1到10,值越小越先加载。默认值是-1:代表第1次访问时创建和初始化

      ​ 他可以在xml中进行配置:

      <load-on-startup>1</load-on-startup>
      复制代码

      ​ 他还可以利用注解配置的方法:

      @WebServlet(urlPatterns = "/response", loadOnStartup =1)
      复制代码

      三、请求对象

      3.1、HttpServletRequest 对象概述

      ​ HttpServletRequest 是一个接口,该接口的实现类对象称为请求对象,请求对象封装了所有的请求信息(请求行,请求头,请求体(请求参数))

      ​ HttpServletRequest 接口包含了大量的方法。由 Tomcat 去实现这个对象,并且在 servlet 启动的时候调用service() 将请求对象传递进来了。我们在 service 方法中直接使用即可。

      3.2、HttpServletRequest 对象常用方法

      request 与请求行相关方法 功能描述
      String getMethod() 获得请求方式 GET 或 POST
      String getRequestURI() Uniform Resource Identifier统一资源标识符,代表一个资源名字
      StringBuffer getRequestURL() Uniform Resource Locator 统一资源定位符,代表一个可以访问地址
      String getProtocol() 获得协议和版本
      String getContextPath() 获得上下文路径(项目名path)
      request 与请求头相关方法 功能描述
      String getHeader(String headName) 得到指定的请求头的值
      参数:键的名字
      返回:相应请求头的值
      request与请求参数相关方法 功能描述
      String getParameter(String name) 通过参数名得到一项参数值
      String[] getParameterValues(String name) 根据参数名得到一组同名的值
      复选框,下拉列表多选
      Enumeration getParameterNames() 获得所有的参数名
      Map getParameterMap() 得到表单所有的参数键和值,封装成Map对象
      Enumeration接口中方法 说明
      boolean hasMoreElements() 如果还有其它元素,返回true
      E nextElement() 返回下一个元素
      package com.servlet;
      import javax.servlet.ServletException;
      import javax.servlet.annotation.WebServlet;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      @WebServlet("/line")
      public class RequestLineServlet extends HttpServlet {
      @Override
      protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      // 获得请求行信息
      System.out.println("得到方法:" + request.getMethod());
      System.out.println("统一资源标识符:" + request.getRequestURI());
      System.out.println("统一资源定位符:" + request.getRequestURL());
      System.out.println("协议和版本:" + request.getProtocol());
      System.out.println("当前项目地址:" + request.getContextPath());
      // 得到一个请求头
      System.out.println("得到host的请求头值:" + request.getHeader("host"));
      }
      }
      复制代码

      3.3、请求参数乱码问题(POST)

      3.3.1、请求参数产生乱码的原因

      ​ 在浏览器发送数据给服务器的时候,使用 utf-8 编码,但服务器解码默认使用 ISO-8859-1 解码:欧洲码,不支持汉字的。

      如果是 GET 请求且 Tomcat 版本大于8.0.5,则不需要考虑乱码问题,否则 GET 请求也需要考虑乱码问题。

      3.3.2、POST方式乱码解决方案

      1. 解决方法:request.setCharacterEncoding("utf-8") 设置请求参数的编码为UTF-8。
      2. 代码位置:设置请求的编码这句话一定放在获取请求参数之前。
      3. 页面的编码:这个编码一定要与页面的编码相同。如果页面使用的是 GBK,则这里也要用GBK。

      四、响应对象

      4.1、HttpServletResponse对象概述

      ​ HttpServletResponse 是一个接口,该接口的实现类对象称为响应对象,用于响应数据(响应行,响应头,响应体)给浏览器。HttpServletResponse 接口包含了大量的方法。由 Tomcat 去实现这个对象,并且在 servlet 启动的时候调用 service() 将请求对象和响应对象传递进来了。我们在 service 方法中直接使用即可。

      4.2、响应数据相关方法

      响应体相关的方法 功能描述
      OutputStream getOutputStream() 如果服务器端返回的是二进制数据
      则使用这个方法,比如图片
      PrintWriter getWriter() 如果服务器端返回的是字符的文本数据,使用这个方法
      @WebServlet(urlPatterns = "/response")
      public class ResponseServlet extends HttpServlet {
      @Override
      protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      // 获得字符打印流对象
      PrintWriter out = response.getWriter();
      // 响应数据给浏览器显示
      out.print("<h1>hello browser<h1>");
      }
      }
      复制代码

      4.3、响应内容中文乱码问题

      4.3.1、乱码原因

      ​ 因为 Tomcat 中响应体默认的是欧洲码表,ISO-8859-1 不支持中文。

      4.3.2、解决办法

      4.3.2、方法一

      在获得打印流对象之前,通过下面方法设置打印流的编码为utf-8

      response方法 说明
      response.setCharacterEncoding("字符集") 用于设置响应体的字符集
      设置打印流使用的码表
      @WebServlet(urlPatterns = "/response")
      public class ResponseServlet extends HttpServlet {
      @Override
      protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      // 设置打印流编码
      response.setCharacterEncoding("utf-8");
      // 获得字符打印流对象
      PrintWriter out = response.getWriter();
      // 响应数据给浏览器显示
      out.print("<h1>你好 browser<h1>");
      }
      }
      复制代码

      4.3.3、方法二

      通过下面方法告诉浏览器返回数据类型和编码

      响应对象的方法 功能描述
      void setContentType(String type) 1. 告诉浏览器返回内容类型
      2. 设置打印流编码
      注意: 必须在获取流之前设置,否则无效
      @WebServlet(urlPatterns = "/response")
      public class ResponseServlet extends HttpServlet {
      @Override
      protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      // 设置打印流编码
      // response.setCharacterEncoding("utf-8");
      // 告诉浏览器返回内容类型并设置打印流编码
      response.setContentType("text/html;charset=utf-8");
      // 获得字符打印流对象
      PrintWriter out = response.getWriter();
      // 响应数据给浏览器显示
      out.print("<h1>你好 browser<h1>");
      }
      }
      复制代码

      五、JSP

      5.1、JSP的作用

      ​ JSP——Java Server Page运行在服务器端的 Java 页面,以前学习的 HTML 运行在浏览器端。JSP 是运行在服务器上,最终还是解析成静态的HTML,运行在浏览器。我们在浏览器上看到的HTML页面,其实是 JSP 在服务器上运行的结果。

      JSP 的主要作用是代替 Servlet 程序回传 html 页面的数据。因为 Servlet 程序回传 html 页面数据是一件非常繁锁的事情。开发成本和维护成本都极高。

      一文把Servlet整的明明白白

      5.2、JSP的优势

      技术 特点
      HTML 静态页面 优点:方便页面美化操作,写JS脚本和CSS代码都比较方便。
      缺点:不能写动态的内容。
      Servlet 运行在服务器上小 Java 程序
      优点:制作动态内容
      缺点:不方便写 HTML 以及 CSS 和 JS 代码
      JSP JSP = HTML + Servlet
      特点:既有 HTML 的优点:方便美化和编写 JS 代码。
      又有 Servlet 优点:可以在页面写 Java 代码,可以制作动态内容(不建议)。

      5.3、JSP的原理

      ​ **JSP页面本质上是一个 Servlet 程序。**当我们第一次访问 jsp 页面的时候。Tomcat 服务器会帮我们把 jsp 页面翻译成为一个 java 源文件。并且对它进行编译成为.class 字节码程序。我们打开 java 源文件不难发现其里面的内容是:

      一文把Servlet整的明明白白

      ​ 我们跟踪原代码发现,HttpJspBase 类。它直接地继承了 HttpServlet 类。也就是说。jsp 翻译出来的 java 类,它间接了继承了 HttpServlet 类。也就是说,翻译出来的是一个 Servlet 程序。

      一文把Servlet整的明明白白

      ​ 翻译出来的 Servlet 程序的源代码,不难发现。其底层实现,也是通过输出流。把 html 页面数据回传

      给客户端。

          out.write("\r\n");
      out.write("\r\n");
      out.write("<html>\r\n");
      out.write("<head>\r\n");
      out.write("
      <title>Title</title>\r\n");
      out.write("</head>\r\n");
      out.write("<body>\r\n");
      out.write("
      a.jsp 页面\r\n");
      out.write("</body>\r\n");
      out.write("</html>\r\n");
      复制代码

      5.4、JSP运行过程

      ​ JspServlet 首先会将 jsp 文件代码翻译成 Servlet 的 Java 代码,然后再编译成字节码文件执行,其底层就是一个 Servlet。

      一文把Servlet整的明明白白

      1. 浏览器请求 JSP 页面,Tomcat 中的 JspServlet 会先 JSP 文件翻译成 Servlet 文件:xxx_jsp.java。
      2. 将 xxx_jsp.java 文件编译产生字节码文件:xxx_jsp.class。
      3. 加载字节码文件 xxx_jsp.class 并创建 xxx_jsp 对象。
      4. 调用 xxx_jsp 的 service 方法处理请求并响应数据。

      浏览器第一次访问 JSP 的时候,由 Tomcat 将 JSP 翻译成了 Servlet,并且编译成字节码文件,只生成1次。如果这期间修改了JSP内容,就会重新翻译。

      六、转发和重定向

      6.1、转发和重定向的作用

      ​ 用于 web 组件的跳转,从A 组件跳到另一个组件B。

      6.2、转发

      一文把Servlet整的明明白白

      6.2.1、跳转位置

      ​ 请求转发是指,服务器收到请求后,从一次资源跳转到另一个资源的操作叫请求转发。在服务器端进行的组件(资源)的跳转。

      一文把Servlet整的明明白白

      6.2.2、转发的方法

      request.getRequestDispatcher("/要跳转到的地址").forward(request, response);
      复制代码

      6.3、重定向

      一文把Servlet整的明明白白

      6.3.1、跳转的位置

      ​ 在浏览器端进行的页面(组件/资源)跳转。

      一文把Servlet整的明明白白

      6.3.2、重定向的方法

      response.sendRedirect("要跳转的地址")
      复制代码

      6.4、转发和重定向的区别

      区别 转发 forward 重定向 redirect
      目录 可以访问WEB-INF目录下的资源 不可以访问WEB-INF目录下的资源
      地址栏 地址栏不会发生变化,还是上一个地址 会变化,显示新的地址
      跳转位置 在服务端进行跳转 在浏览器端跳转
      请求对象(域) 请求域数据不会丢失,因为是同一个请求 请求域数据会丢失,因为不是同一个请求

      6.5、注意

      1. 无论是重定向还是转发,后续代码都会执行,但一般转发或重定向后面不会有代码,没有执行的意义了,因为不管是转发还是重定向浏览器最终显示的都是跳转后页面的数据。
      2. 如果需要保留请求域中的数据,必须使用转发。
      3. 如果需要跳转到WEB-INF目录中的资源,必须使用转发。
      4. 如果需要跨域,必须使用重定向。

      七、三大作用域

      7.1、什么是作用域

      ​ 用于 Servlet 之间数据共享的服务器内存区域,作用域结构是一个Map<String, Object>。

      一文把Servlet整的明明白白

      7.2、作用域类型

      作用域 类型 作用范围
      请求域 HttpServletRequest 只在同一次请求中起作用
      会话域 HttpSession 同一个会话中起作用
      浏览器第1次访问服务器直到浏览器关闭
      的整个过程称为1次会话
      上下文域 ServletContext 同一个应用中起作用
      服务器启动直到服务器关闭的整个过程都起作用

      7.3、作用域方法

      与作用域有关的方法 作用
      Object getAttribute("键") 从中得到一个值
      void setAttribute("键",Object数据) 向作用域中存储键值对数据
      void removeAttribute("键") 删除作用域中的键值对数据

      7.4、如何选择作用域

      先考虑作用范围小的作用域,如果小作用范围的作用域能满足需求就使用小作用范围的作用域。

      八、EL表达式

      8.1、什么是EL表达式

      ​ EL 表达式的全称是:Expression Language。是表达式语言。

      ​ EL 表达式主要是代替 jsp 页面中的表达式脚本在 jsp 页面中进行数据的输出。因为 EL 表达式在输出数据的时候,要比 jsp 的表达式脚本要简洁很多。

      8.2、EL表达式运算

      8.2.1、算数运算

      算术运算符 说明 举例 结果
      + 加法 ${12+18} 30
      - 减法 ${18-8} 10
      * 乘法 ${12*12} 144
      /(div) 除法

      6/3{6/3}或

      {6 div 3}

      2
      %(mod) 取模 {10%3} 或{10 mod 3} 1

      8.2.2、逻辑运算

      逻辑运算符 说明 举例 结果
      && 或 and 与运算 { 12 == 12 && 12 < 11 } 或 { 12 == 12 and 12 < 11 } false
      | 或 or 或运算

      12==1212<11{ 12 = = 12 \|\| 12<11}或

      {12= =12 or 12<11}

      true
      ! 或 not 取反运算

      !true{!true} 后

      {not true}

      false

      8.2.3、关系运算

      关系运算 说明 举例 结果
      == 或 eq 等于

      5==5{5 == 5} 或

      {5 eq 5}

      true
      != 或 ne 不等于

      5!=5{5 !=5} 或

      {5 ne 5}

      false
      < 或 lt 小于

      3<5{3 < 5} 或

      {3 lt 5}

      true
      > 或 gt 大于

      2>10{2 > 10} 或

      {2 gt 10}

      false
      <= 或 le 小于等于

      5<=12{ 5 <= 12 } 或

      { 5 le 12 }

      true
      >= 或 ge 大于等于

      3>=5{ 3 >= 5 }或

      { 3 ge 5 }

      false

      8.2.4、三元运算

      表达式 1?表达式 2:表达式 3

      ​ 如果表达式 1 的值为真,返回表达式 2 的值,如果表达式 1 的值为假,返回表达式 3 的值。

      一文把Servlet整的明明白白

      8.2.5、判空运算

      ​ 判空:判断的是内容是否为空,不是对象是否为空。

      一文把Servlet整的明明白白

      8.3、EL 从四个作用域中取值

      EL 获取数据的方式是从 4 个作用域对象中,从小到大的去获取,如果需要指定作用域获取数据,可使用以下 EL 的内置对象来指定。

      8.3.1、PageContext 对象

      ​ JSP 本质是 Servlet,但比 Servlet 多了一个作用域:页面域,在 JSP 中有四大作用域。页面域是只在一个JSP页面中起作用,不同的JSP之间不能实现数据的共享,比请求域范围还要小。

      PageContext 操作有关的方法 说明
      void setAttribute(String key, Object value) 向页面域中添加键和值
      Object getAttribute(String key) 从页面域中得到值
      void removeAttribute(String key) 删除四个域中同名的键
      Object findAttribute(String key) 自动从四个作用域中去查某个键,
      从小到大的范围来查找,如果找到就停止。
      如果没有找到,返回null
      <%
      //向页面域中添加一个字符串    
      pageContext.setAttribute("name","我是页面域");
      %>
      复制代码

      8.3.2、 EL 指定域获取数据

      作用域 EL的写法
      页面域 ${pageScope.键名}
      请求域 ${requestScope.键名}
      会话域 ${sessionScope.键名}
      上下文域 ${applicationScope.键名}
      <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <html>
      <head>
      <title>EL指定域获取数据</title>
      </head>
      <body>
      <%
      // 向页面域中添加一个字符串
      pageContext.setAttribute("name", "页面域");
      // 请求域
      request.setAttribute("name", "请求域");
      // 会话域
      session.setAttribute("name", "会话域");
      // 上下文域
      application.setAttribute("name", "上下文域");
      %>
      从页面域获取:${pageScope.name}
      <hr>
      从请求域获取:${requestScope.name}
      <hr>
      从会话域获取:${sessionScope.name}
      <hr>
      从上下文域获取:${applicationScope.name}
      <hr>
      自动查找作用域获取:${name}
      <hr>
      </body>
      </html>
      复制代码

      九、JSTL 标签库

      ​ JSTL 标签库 全称是指 JSP Standard Tag Library JSP 标准标签库。是一个不断完善的开放源代码的 JSP 标签库。EL 表达式主要是为了替换 jsp 中的表达式脚本,而标签库则是为了替换代码脚本。这样使得整个 jsp 页面变得更佳简洁。JSTL 由五个不同功能的标签库组成。

      功能范围 URL 前缀
      核心标签库 java.sun.com/jsp/jstl/co… c
      格式化 java.sun.com/jsp/jstl/fm… fmt
      函数 java.sun.com/jsp/jstl/fu… fn

      9.1、使用步骤

      9.1.1、导入jar包

      taglibs-standard-impl-1.2.1.jar
      taglibs-standard-spec-1.2.1.jar
      复制代码

      9.1.2、引入标签库

      <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
      复制代码

      9.1.3、使用标签

      9.2、核心标签库常用标签

      9.2.1、<c:if />

      ​ 用于页面上单条件判断。

      属性名 是否支持EL 属性类型 属 性 描 述
      test 支持,必须是 EL boolean值 EL 中条件为真则执行标签体内容
      注意:没有对应 else 标签
      <%--
      ii.<c:if />
      if 标签用来做 if 判断。
      test 属性表示判断的条件(使用 EL 表达式输出)
      --%>
      <c:if test="${ a == b }">
      <h1>如果a等于b</h1>
      </c:if>
      <c:if test="${ a != b }">
      <h1>如果a不等于b</h1>
      </c:if>
      复制代码

      9.2.2、<c:choose>

      ​ 用于多分支判断(多条件判断),类似于跟 switch ... case .... default 。

      标签名 作用
      choose 类似于 java 中swtich, choose只是一个容器,包含下面两个元素
      when 可以出现多个,用于每个判断条件,类似于 switch 中 case。有一个 test 属性,与 if 功能相同
      otherwise 如果上面所有的条件都不满足,执行 otherwise 内容。类似于 switch 中 default

      9.2.3、<c:forEach>

      ​ 用于遍历集合或数组(最为常用)。

      属性名 是否支持EL 属性类型 属性描述
      items true 数组或集合 使用 EL 表达式,代表集合或数组
      var false String var 的变量名代表集合中的每一个元素
      varStatus false String 代表每个元素的状态对象,
      一共有4个属性,属性的含义见下表

      ​ varStatus属性表:

      属性 数据类型 含义
      index int 当前遍历到的这个元素索引号,从 0 开始
      count int 遍历到当前为止,一共遍历了多少个元素,从1 开始
      first boolean 如果当前遍历的是第1个元素,则返回true
      last boolean 如果当前遍历的是最后1个元素,则返回true
      <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
      <html>
      <head>
      <title>学生信息表</title>
      <style>
      tr {
      text-align: center;
      }
      </style>
      </head>
      <body>
      <table align="center" border="1" cellspacing="0" cellpadding="0" width="80%">
      <caption>学生信息列表</caption>
      <tr>
      <th>序号</th>
      <th>学号</th>
      <th>姓名</th>
      <th>性别</th>
      <th>成绩</th>
      </tr>
      <%--
      forEach标签:用于JSP页面遍历集合和数组
      items属性:设置要遍历的集合或数组:一般从作用域中获取
      var属性:设置一个变量名:用来接收遍历到的每一个元素
      varStatus属性:设置一个变量名:记录当前遍历元素的状态(状态对象)
      index 属性:当前遍历元素的在集合中的索引值:从0开始
      count 属性:遍历到当前元素为止已经遍历了多少个元素,从 1 开始
      --%>
      <c:forEach items="${stus}" var="stu" varStatus="status">
      <!-- 给偶数行设置背景颜色 -->
      <tr style="background-color:${status.count % 2 == 0 ? 'gray;' : ''}">
      <td>${status.count}</td>
      <td>${stu.id}</td>
      <td>${stu.name}</td>
      <td>${stu.gender? "男":"女"}</td>
      <td>${stu.score}</td>
      </tr>
      </c:forEach>
      </table>
      </body>
      </html>
      复制代码

      9.3、格式化标签库常用标签

      9.3.1、<fmt:formatDate>

      ​ 用于对日期进行格式化。

      属性名 属性类型 属 性 描 述
      test Date 要格式化的日期对象
      pattern String 指定日期格式

      请登录之后再进行评论

      登录

      手机阅读天地(APP)

      • 微信公众号
      • 微信小程序
      • 安卓APP
      手机浏览,惊喜多多
      匿名树洞,说我想说!
      问答悬赏,VIP可见!
      密码可见,回复可见!
      即时聊天、群聊互动!
      宠物孵化,赠送礼物!
      动态像框,专属头衔!
      挑战/抽奖,金币送不停!
      赶紧体会下,不会让你失望!
    • 实时动态
    • 签到
    • 做任务
    • 发表内容
    • 偏好设置
    • 到底部
    • 帖子间隔 侧栏位置:
    • 还没有账号?点这里立即注册