聊JSP就不得不提它和Servlet之间的技术渊源。许多刚接触Java Web的开发者容易把这两个概念混淆,但实际上它们本质上是同一种技术。简单来说,Servlet是用Java代码包裹HTML内容,而JSP恰好相反——它用HTML代码包裹Java代码。
归根结底,JSP就是一个Java类。例如,当你编写了一个index.jsp文件,编译后它会变成index_jsp.java这个Java源文件。因此,千万不要把JSP误认为是超文本之类的其他内容,它实实在在就是一个Java类。更准确地说,JSP本质上就是一个Servlet。JSP继承自Servlet,Servlet所具备的能力,JSP一个都不少。

JSP的转换流程是:首先将JSP文件转为.java源码,然后再编译成.class字节码文件。在这一过程中还有一个特别实用的特性——热部署。当你更新了JSP文件后,服务器会自动检测到变更并重新编译,无需手动重启服务。
总而言之,JSP之所以被设计出来,就是为了让开发者能够更便捷地编写HTML代码。如果使用Servlet直接开发前端页面,那将是非常繁琐的工作。JSP恰好解决了这一痛点。
页面指令:配置的核心入口
首先来介绍页面指令,也就是<%@ page %>这个标签。它负责配置JSP页面的各种属性。
<%@ page import="ja va.util.Date" contentType="text/html;charset=UTF-8" %>
这一行完成了两个任务:导入所需的包(例如ja va.util.Date),同时设置网页输出的字符编码。UTF-8编码几乎是默认标准,实际开发中很少会使用其他编码。
<%@ page session="true" %>
这个指令用于控制Session的开启与关闭。设置为true表示自动启用Session,false则表示禁用。在绝大多数应用场景下,我们都需要使用Session,因此默认值就是true。
<%@ page isThreadSafe="true" %>
该指令用于控制线程安全,实现请求的排队处理。设置为true时,多个请求将按顺序串行执行。
<%@ page buffer="8kb" %>
这里的buffer(缓冲区)需要重点说明。它指的是服务器向客户端传输数据时使用的缓存池。如果没有缓冲区,服务器每次只能以字节为单位进行传输,效率非常低下。设置成8kb后,数据会先在这个缓存池中累积,直到达到8kb再一次性发送给客户端。在实际项目中,可以根据具体情况调整缓存大小,从而有效提升整体响应速度。
<%@ include file="A.jsp" %>
需要注意——这里的include指令属于静态包含,它会将A.jsp文件的全部内容原封不动地复制到当前页面,而不是复制运行后的结果。这在处理重复内容时非常有用。例如,网站的头部、底部等公共部分,可以抽取到单独的JSP文件中,然后多个页面通过include方式引用。后续修改时,只需改动这一个公共文件,所有引用该文件的页面都会自动更新。除了页面片段,常量值也可以采用这种方式统一管理。
JSP代码书写方式详解
JSP提供了三种代码书写形式,分别对应不同的作用范围。
<%! String s="嘻嘻哈哈"; %>
这种声明格式中的代码会被复制到JSP类的成员属性中,声明的变量与格式保持不变。可以理解为定义了全局的类级别变量。
<% %>
脚本段中编写的代码会被放置到_jspService方法内部。也就是说,这里编写的是真正在方法中执行的逻辑代码。
<%= %>
这是一个简化输出的表达式。例如,<% out.println("111"); %>是常规的输出方式,而<%="111" %>可以直接输出变量或字符串,省去了out.println的步骤。
错误页面设置与处理
在JSP中,错误处理需要两个步骤配合完成。
第一步,在容易发生错误的页面中指定错误跳转目标:<%@ page errorPage="error.jsp" %>。
第二步,在错误页面中声明自己为错误处理器:isErrorPage="true"。只有将该属性设为true,当前页面才能访问exception对象。
一个完整的错误处理页面示例如下:
<%@ page contentType="text/html;charset=UTF-8" isErrorPage="true" %>
然后,可以通过<%=exception.printStackTrace(out);%>来输出具体的错误信息。
反过来,在可能出错的页面中写入:<%@ page contentType="text/html;charset=UTF-8" errorPage="error.jsp" %>。这样,只要该JSP页面发生任何运行时异常,就会自动跳转到error.jsp进行处理。
内置对象一览
JSP提供了一些内置对象,无需声明即可直接使用:
- request —— 用于获取请求头及相关信息
- response —— 用于设置响应头及相关信息
- session —— 会话对象,需配合
<%@ session="true"%>开启 - application —— 全局对象,对应于ServletContext
- config —— 配置信息对象(日常开发中使用频率较低)
- out —— 输出流对象
- pageContext —— 页面上下文,可访问全局配置
- exception —— 异常对象,需要
<%@ page isErrorPage="true"%>才能访问 - page —— 当前页面的配置信息
