【Java Web编程 四】深入理解JSP内置对象

简介: 【Java Web编程 四】深入理解JSP内置对象

上文提到JSP的基本技术,包括:JSP的基本概念、JSP的执行流程、JSP的文件元素、JSP的生命周期以及JSP的语法标识,重点了解了JSP的语法标识里的:脚本标识、注释标识、指令标识以及动作标识。接下来这篇Blog来重点了解下JSP的内置对象。

JSP内置对象概述

JSP隐式对象是JSP容器为每个页面提供的Java对象,开发者可以直接使用它们而不用显式声明。JSP隐式对象也被称为预定义变量。

JSP所支持的九大内置对象,也叫隐式对象,从本质上讲,JSP的这些内置对象其实都是由特定的Java类所产生的,在服务器运行时根据情况自动生成。基于它们的主要作用可以分为四类:输入输出对象、作用域对象、Servlet对象以及异常错误对象

输入输出对象

输入输出对象共有两个,一个是我们最常用的用作向客户端输出各种数据的out对象,一个是主要用作页面重定向的response对象。

out对象

out 对象主要用于向客户端输出各种数据类型的内容,默认缓冲区8K,可以通过page指令设置,out 对象被封装为 javax.servlet.jsp.JspWriter 类,在实际应用中 out 对象会通过 JSP 容器变换为 java.io.PrintWriter 类,常用方法如下:

out对象有点类似我们之前的表达式脚本<%="我是一个跳转后的表达式语句"%>,用于像客户端输出信息,和System.out.println()语句服务端本地打印不同,out是向客户端浏览器打印数据,利用out对象还可以输出html代码,比如<br /> 让浏览器解析

response对象

response 对象用于响应客户请求,封装了 JSP 产生的响应,并发送到客户端以响应客户端的请求,response对象常用功能如下:处理 HTTP 文件头和页面重定向,但我们一般不会设置返回的文件头,我们一般使用respnse做页面重定向:

  • response 对象提供的 sendRedirect() 方法将网页重定向到另一个页面

这里简单解释下请求转发和重定向:

  • 请求转发:客户端发起的请求被转发到了另一个地址进行处理,但这依然发生在一个request作用域里,地址栏显示的也是原来的地址。
  • 重定向:重定向操作支持将地址重定向到另一个地址进行处理,这是由目标服务器返回的客户端再次发起的一个请求,不在一个request作用域里,在客户端浏览器上将会得到跳转的地址,并重新发送请求链接,且地址栏显示新地址

好简单了解后我们来看一个重定向的写法:

// 如果用户没有输入用户名,则重定向到 redirect.jsp
    if (username == null || "".equals(username.trim())) {
        response.sendRedirect("redirect.jsp");//如果用户名不存在,则转向第一个界面
    }

四大作用域对象

共有四种级别的通信域,每一种通信域作用的范围不同,也都有些各自的作用对象,列举如下:

通信域 对象 作用范围 失效情况
Page pageContext 当前jsp页面 请求转发即失效
Request request 一次请求 请求转发公用request,重定向即失效
Session session 一次会话 浏览器关闭即失效
Application application 项目启动期间 项目关闭即失效

在正式聊四大作用域对象前我们先了解下表单提交,通过表单提交来看作用域的作用范围

表单提交

网页中表单是用户填写信息并提交的组件,JSP 引擎会将客户端的请求信息封装在request 对象中,调用request 对象相应的方法就可以获取对应的封装信息,first.jsp:

<%--
  Created by IntelliJ IDEA.
  User: tianmaolin
  Date: 2021/7/15
  Time: 8:02 下午
  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>
<form action="second.jsp" method="get">
    <table>
        <tr>
            <td> 用户名:</td>
            <td><input type="text" name="username"></td>
            <td> 密码:</td>
            <td><input type="text" name="password"></td>
        </tr>
        <tr>
            <td colspan="2">
                <input type="submit" value=" 注册 ">
            </td>
        </tr>
    </table>
</form>
</body>
</html>

这样当我们提交时,表单就会传递到second.jsp页面:

提交后就可以在second.jsp页面获取到填写的信息:

second.jsp的代码清单如下,我会在代码清单里加一些判断逻辑,来完成一些作用域的探索second.jsp:

<%--
  Created by IntelliJ IDEA.
  User: tianmaolin
  Date: 2021/7/15
  Time: 8:02 下午
  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>
<%
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    pageContext.setAttribute("password",password);
    session.setAttribute("password",password);
    application.setAttribute("password",password);
    pageContext.setAttribute("username",username);
    session.setAttribute("username",username);
    application.setAttribute("username",username);
    // 如果用户没有输入用户名,则重定向到 redirect.jsp
    if (username == null || "".equals(username.trim())) {
        response.sendRedirect("redirect.jsp");//如果用户名不存在,则转向第一个界面
    }
    // 如果用户没有输入密码,则请求转发到forward.jsp
    if (password == null || "".equals(password.trim())) {
        request.getRequestDispatcher("forward.jsp").forward(request,response);
    }
%>
<%
    out.println("输出注册信息");
%>
<%="您的用户名为:" + username + " 密码为: " + password%>
</body>
</html>

pageContext对象

pageContext页面上下文对象可以获取其他作用域对象,并提供方法用于访问内建对象在页面上定义的所有属性,从而保持同一页面组件之间的数据共享,pageContext常用方法如下:

请求转发【pageContext失效】

在上文的代码清单里我预置了一些条件,当用户没有输入密码的时候我们执行请求转发,请求转发的代码清单如下forward.jsp:

<%--
  Created by IntelliJ IDEA.
  User: tianmaolin
  Date: 2021/7/15
  Time: 8:38 下午
  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>
[pageContext]未填写密码信息,只填写了用户名:<%=pageContext.getAttribute("username")%></br>
[request]未填写密码信息,只填写了用户名:<%=request.getParameter("username")%></br>
[session]未填写密码信息,只填写了用户名:<%=session.getAttribute("username")%></br>
[application]未填写密码信息,只填写了用户名:<%=application.getAttribute("username")%>
</body>
</html>

此时我们在页面只输入用户名观察浏览器:

request对象

request对象是javax.servlet.http.HttpServletRequest 类的实例。每当客户端请求一个JSP页面时,JSP引擎就会制造一个新的request对象来代表这个请求。request对象提供了一系列方法来获取HTTP头信息,cookies,HTTP方法等等,最重要的作用就是:封装用户提交的表单信息,通过如下方法可以获取对应数据

request也可以帮助我们执行请求转发:

request.getRequestDispatcher("forward.jsp").forward(request,response);

重定向【request失效】

同样在上文的代码清单里我预置了一些条件,当用户没有输入用户名的时候我们执行重定向,重定向的代码清单如下redirect.jsp:

<%--
  Created by IntelliJ IDEA.
  User: tianmaolin
  Date: 2021/7/15
  Time: 8:20 下午
  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>
[pageContext]未填写用户名信息,只填写了密码:<%=pageContext.getAttribute("password")%></br>
[request]未填写用户名信息,只填写了密码:<%=request.getParameter("password")%></br>
[session]未填写用户名信息,只填写了密码:<%=session.getAttribute("password")%></br>
[application]未填写用户名信息,只填写了密码:<%=application.getAttribute("password")%>
</body>
</html>

那么我们打开页面可以观察到:

session对象

session在JSP中被称为会话,目的是保存不同用户在web程序多个页面之间跳转时的数据信息,直到浏览器关闭,每个客户端会对应同一个session对象:

  • session对象存储数据方法:session.setAttribute(“字符串名称”,要存入的数据); 向session中存入数据,并且起名,要存入的数据可以是任意类型,名称必须是字符串类型,例如:在这里插入代码片
  • session对象取出数据方法: session.getAttribute(“存入时的名称”);,取出数据时是Object类型,如需要可以转为需要类型
  • session对象移除数据方法如下:session.removeAttribute(“存入时的名称”);

示例如下:

session.setAttribute("password",password);

需要注意的是:服务器不知道客户端何时关闭浏览器,为了节省内存开销,默认超时时间为30分钟,即30分钟用户没有再次发出请求,则session自动销毁,超时时间可以在Tomcat配置文件中修改

浏览器关闭【session失效】

我们把请求地址粘贴到另一个新用户浏览器上来观察session的存活状态,发现session在切换了会话后失效了。

application对象

application 对象用于保存应用中的公有数据,服务器启动自动创建 application 对象,只要没有关闭服务器,application 对象将一直存在,所有用户可以共享,application 对象常用于记录缓存项目中的全局数据,常用方法如下:

示例如下:

application.setAttribute("password",password);

关闭服务器【application失效】

我们关闭tomcat服务,可以观察到application的作用域也失效了,当然不光是失效了,服务器都没了。

我们这里要说的就是再重启服务器后application里也是不会有值的。

异常错误对象

exception 对象包装了从先前页面中抛出的异常信息。它通常被用来产生对出错条件的适当响应,通常和page指令里的errorPage和isErrorPage一起使用。一般常用方法如下:

我们来看下我们的异常页面为test.jsp:

<%--
  Created by IntelliJ IDEA.
  User: tianmaolin
  Date: 2021/7/14
  Time: 12:30 下午
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8"  errorPage="error.jsp" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%! int day = 3; %>
if语句输出练习:
<br/>
<% if (day == 1 || day == 7) { %>
<p>今天是周末</p>
<% } else { %>
<p>今天不是周末</p>
<% }
    ;
%>
<br/>
for语句输出练习;
<br/>
<%for (int fontSize = 1; fontSize <= 3; fontSize++) { %>
<span style="color: green; ">
    循环第 <%=fontSize%> 遍<br/>
</span><br/>
<%}%>
<%
    int b=0;
    if(b==0){
        int a=5/b;
        throw new Exception("不能做除0运算");
    }
%>
</body>
</html>

在这个页面我们通过指令指定如果出现异常要处理异常的页面是哪个:errorPage="error.jsp",然后我们来编写下错误的处理页面error.jsp:

<%--
  Created by IntelliJ IDEA.
  User: tianmaolin
  Date: 2021/7/15
  Time: 8:44 下午
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isErrorPage="true"%>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%
        out.print(" 异常信息: "+ exception.getMessage()); //从exception对象中获取异常信息
%>
</body>
</html>

这样当我们访问问题页面时就会自动展示错误信息:

Servlet对象

还有几个我们不常用到的对象这里也一并了解下,包括config对象和page对象

config对象

config对象是 javax.servlet.ServletConfig 类的实例,直接包装了servlet的ServletConfig类的对象。这个对象允许开发者访问Servlet或者JSP引擎的初始化参数,比如文件路径等。以下是config对象的使用方法,不是很重要,所以不常用:

config.getServletName();

它返回包含在<servlet-name>元素中的servlet名字,注意,<servlet-name>元素在 WEB-INF\web.xml 文件中定义。

page对象

这个对象就是页面实例的引用。它可以被看做是整个JSP页面的代表。page 对象就是this对象的同义词

总结一下

好了以上就是JSP的内置对象相关内容,我觉得其中最重要的包含以下三个内容:

  • pageContext、request、Session以及application这四个作用域作用的范围,这对以后学习框架也有帮助
  • 理解表单提交的基本方式
  • 理解请求转发和重定向的含义

好了这期学习和练习就到这里,下一期我们详细学习下JavaBean以及深入理解下动作标识。

相关文章
|
8天前
|
JSON Java Apache
非常实用的Http应用框架,杜绝Java Http 接口对接繁琐编程
UniHttp 是一个声明式的 HTTP 接口对接框架,帮助开发者快速对接第三方 HTTP 接口。通过 @HttpApi 注解定义接口,使用 @GetHttpInterface 和 @PostHttpInterface 等注解配置请求方法和参数。支持自定义代理逻辑、全局请求参数、错误处理和连接池配置,提高代码的内聚性和可读性。
|
9天前
|
存储 安全 Java
Java多线程编程的艺术:从基础到实践####
本文深入探讨了Java多线程编程的核心概念、应用场景及其实现方式,旨在帮助开发者理解并掌握多线程编程的基本技能。文章首先概述了多线程的重要性和常见挑战,随后详细介绍了Java中创建和管理线程的两种主要方式:继承Thread类与实现Runnable接口。通过实例代码,本文展示了如何正确启动、运行及同步线程,以及如何处理线程间的通信与协作问题。最后,文章总结了多线程编程的最佳实践,为读者在实际项目中应用多线程技术提供了宝贵的参考。 ####
|
10天前
|
Java Maven Spring
Java Web 应用中,资源文件的位置和加载方式
在Java Web应用中,资源文件如配置文件、静态文件等通常放置在特定目录下,如WEB-INF或classes。通过类加载器或Servlet上下文路径可实现资源的加载与访问。正确管理资源位置与加载方式对应用的稳定性和可维护性至关重要。
|
6天前
|
监控 安全 Java
Java中的多线程编程:从入门到实践####
本文将深入浅出地探讨Java多线程编程的核心概念、应用场景及实践技巧。不同于传统的摘要形式,本文将以一个简短的代码示例作为开篇,直接展示多线程的魅力,随后再详细解析其背后的原理与实现方式,旨在帮助读者快速理解并掌握Java多线程编程的基本技能。 ```java // 简单的多线程示例:创建两个线程,分别打印不同的消息 public class SimpleMultithreading { public static void main(String[] args) { Thread thread1 = new Thread(() -> System.out.prin
|
8天前
|
存储 缓存 安全
在 Java 编程中,创建临时文件用于存储临时数据或进行临时操作非常常见
在 Java 编程中,创建临时文件用于存储临时数据或进行临时操作非常常见。本文介绍了使用 `File.createTempFile` 方法和自定义创建临时文件的两种方式,详细探讨了它们的使用场景和注意事项,包括数据缓存、文件上传下载和日志记录等。强调了清理临时文件、确保文件名唯一性和合理设置文件权限的重要性。
22 2
|
9天前
|
Java UED
Java中的多线程编程基础与实践
【10月更文挑战第35天】在Java的世界中,多线程是提升应用性能和响应性的利器。本文将深入浅出地介绍如何在Java中创建和管理线程,以及如何利用同步机制确保数据一致性。我们将从简单的“Hello, World!”线程示例出发,逐步探索线程池的高效使用,并讨论常见的多线程问题。无论你是Java新手还是希望深化理解,这篇文章都将为你打开多线程的大门。
|
10天前
|
安全 Java 编译器
Java多线程编程的陷阱与最佳实践####
【10月更文挑战第29天】 本文深入探讨了Java多线程编程中的常见陷阱,如竞态条件、死锁、内存一致性错误等,并通过实例分析揭示了这些陷阱的成因。同时,文章也分享了一系列最佳实践,包括使用volatile关键字、原子类、线程安全集合以及并发框架(如java.util.concurrent包下的工具类),帮助开发者有效避免多线程编程中的问题,提升应用的稳定性和性能。 ####
37 1
|
1月前
|
XML JSON API
ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
101 3
|
17天前
|
设计模式 前端开发 数据库
Python Web开发:Django框架下的全栈开发实战
【10月更文挑战第27天】本文介绍了Django框架在Python Web开发中的应用,涵盖了Django与Flask等框架的比较、项目结构、模型、视图、模板和URL配置等内容,并展示了实际代码示例,帮助读者快速掌握Django全栈开发的核心技术。
103 45
|
13天前
|
前端开发 API 开发者
Python Web开发者必看!AJAX、Fetch API实战技巧,让前后端交互如丝般顺滑!
在Web开发中,前后端的高效交互是提升用户体验的关键。本文通过一个基于Flask框架的博客系统实战案例,详细介绍了如何使用AJAX和Fetch API实现不刷新页面查看评论的功能。从后端路由设置到前端请求处理,全面展示了这两种技术的应用技巧,帮助Python Web开发者提升项目质量和开发效率。
28 1