1.概述
首先我们说一下JSP的概念(以下内容来自百度百科):
JSP(全称JavaServer Pages)是由[Sun Microsystems](https://baike.baidu.com/item/Sun Microsystems)公司主导创建的一种动态网页技术标准。JSP部署于网络服务器上,可以响应客户端发送的请求,并根据请求内容动态地生成HTML、XML或其他格式文档的Web网页,然后返回给请求者。JSP技术以Java语言作为脚本语言,为用户的HTTP请求提供服务,并能与服务器上的其它Java程序共同处理复杂的业务需求。
由上我们可以知道:
- JSP是java程序。(JSP本质还是一个Servlet)
- JSP是:JavaServer Pages的缩写。(基于Java语言实现的服务器端的页面。)
- Servlet是JavaEE的13个子规范之一,那么JSP也是JavaEE的13个子规范之一。
- JSP是一套规范。所有的web容器/web服务器都是遵循这套规范的,都是按照这套规范进行的“翻译”
- 每一个web容器/web服务器都会内置一个JSP翻译引擎。
2.本质
为了更好的了解JSP,我们可以在idea部署tomcat的项目中中手写一个jsp文件名为index.jsp,如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>这是由JSP翻译器翻译过来的Servlet</title>
</head>
<body>
<%="什么也不做"%>
</body>
</html>
启动服务器,再通过URL访问我们的服务器上的index.jsp,这个时候我们的jsp文件就已经被我们的JSP翻译器翻译为Servlet了。我们可以通过下面的路径找到翻译完成的Servlet。(下面关于翻译完成的Servlet的路径不是重点,看不懂可以略过)
C:\Users\?1\?2\system\tomcat\?3\Catalina\localhost\?4\org\[apache](https://so.csdn.net/so/search?q=apache&spm=1001.2101.3001.7020)\jsp
?1:在计算机上使用IDEA的用户的用户名 ;
?2:.IntelliJIdea2018.2 + IDEA的版本日期(下载使用的IDEA的版本不一样日期也不一样);
?3:此web应用在IDEA上使用的tomcat的名字(自己取的) + 项目名;
?4:项目名;
比如我自己的路径就是C:\Users\少不入川。\AppData\Local\JetBrains\IntelliJIdea2021.3\tomcat\82919bbd-7058-4746-851f-6389e107e42a\work\Catalina\localhost\xmm\org\apache\jsp
在这个文件目录下我们可以发现名为index_jsp.java、index_jsp.class文件。这个就是由我们JSP文件翻译过来的Servlet以及编译过后生成的字节码文件。index_jsp.java的内容如下:
package org.apache.jsp;
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import jakarta.servlet.jsp.*;
public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent,
org.apache.jasper.runtime.JspSourceImports {
private static final jakarta.servlet.jsp.JspFactory _jspxFactory =
jakarta.servlet.jsp.JspFactory.getDefaultFactory();
private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;
private static final java.util.Set<java.lang.String> _jspx_imports_packages;
private static final java.util.Set<java.lang.String> _jspx_imports_classes;
static {
_jspx_imports_packages = new java.util.HashSet<>();
_jspx_imports_packages.add("jakarta.servlet");
_jspx_imports_packages.add("jakarta.servlet.http");
_jspx_imports_packages.add("jakarta.servlet.jsp");
_jspx_imports_classes = null;
}
private volatile jakarta.el.ExpressionFactory _el_expressionfactory;
private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;
public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
return _jspx_dependants;
}
public java.util.Set<java.lang.String> getPackageImports() {
return _jspx_imports_packages;
}
public java.util.Set<java.lang.String> getClassImports() {
return _jspx_imports_classes;
}
public jakarta.el.ExpressionFactory _jsp_getExpressionFactory() {
if (_el_expressionfactory == null) {
synchronized (this) {
if (_el_expressionfactory == null) {
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
}
}
}
return _el_expressionfactory;
}
public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
if (_jsp_instancemanager == null) {
synchronized (this) {
if (_jsp_instancemanager == null) {
_jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
}
}
}
return _jsp_instancemanager;
}
public void _jspInit() {
}
public void _jspDestroy() {
}
public void _jspService(final jakarta.servlet.http.HttpServletRequest request, final jakarta.servlet.http.HttpServletResponse response)
throws java.io.IOException, jakarta.servlet.ServletException {
if (!jakarta.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
final java.lang.String _jspx_method = request.getMethod();
if ("OPTIONS".equals(_jspx_method)) {
response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
return;
}
if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) {
response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允许 GET、POST 或 HEAD。Jasper 还允许 OPTIONS");
return;
}
}
final jakarta.servlet.jsp.PageContext pageContext;
jakarta.servlet.http.HttpSession session = null;
final jakarta.servlet.ServletContext application;
final jakarta.servlet.ServletConfig config;
jakarta.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
jakarta.servlet.jsp.JspWriter _jspx_out = null;
jakarta.servlet.jsp.PageContext _jspx_page_context = null;
try {
response.setContentType("text/html;charset=UTF-8");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.write("\r\n");
out.write("\r\n");
out.write("<html>\r\n");
out.write("<head>\r\n");
out.write(" <title>这是由JSP翻译器翻译过来的Servlet</title>\r\n");
out.write("</head>\r\n");
out.write("<body>\r\n");
out.write(" ");
out.print("什么也不做");
out.write("\r\n");
out.write("</body>\r\n");
out.write("</html>\r\n");
} catch (java.lang.Throwable t) {
if (!(t instanceof jakarta.servlet.jsp.SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try {
if (response.isCommitted()) {
out.flush();
} else {
out.clearBuffer();
}
} catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
else throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
由上我们可以看到我们在jsp文件中手动编写的两行内容被翻译到由jsp文件生成的Servlet文件中了,所以我们可以知道jsp的本质也是就是Servlet。
3.JSP与Servlet的区别
从架构上说,JSP可以被看作是从Servlets高级提炼而作为JAVA Servlet2.1 API的扩展而应用。Servlets和JSP最早都是由Sun Microsystems(升阳公司)开发的。从JSP1.2版本以来,JSP处于Java Community Process(有人译为:JAVA社区组织)开发模式下。JSR-53规定了JSP 1.2和Servlet 2.4的规范,JSR-152规定了JSP 2.0的规范。2006年5月,JSP 2.1的规范作为Java EE5的一部份,在JSR-245中发布。
更加直观的说,JSP和Servlet的职责不同:
- Servlet的职责是什么:收集数据。(Servlet的强项是逻辑处理,业务处理,然后链接数据库,获取/收集数据。)
- JSP的职责是什么:展示数据。(JSP的强项是做数据的展示)
这样的目的也是为了让我们的代码更加的清晰。
4.JSP的常用基础语法
- JSP中直接编写普通字符串
- 会被翻译到由jsp文件生成的Servlet类的service方法的中的out.write(“这里”)语句当中。
- <%%>
- 会被翻译到由jsp文件生成的Servlet类的service方法体内部,里面是一条一条的java语句。
- <%! %>
- 会被翻译到由jsp文件生成的Servlet类的service方法之外。
- <%= %>
- 会被翻译到由jsp文件生成的Servlet类的service方法体内部,翻译为:out.print();
- 主要是用来输出Java变量与字符串的组合
- <%@page contentType=“text/html;charset=UTF-8”%>
- page指令,通过contentType属性用来设置响应的内容类型。
- jsp中的指令还有很多,我也不了解,我也就不细说了
5.JSP指令
-
指令的作用:指导JSP的翻译引擎如何工作(指导当前的JSP翻译引擎如何翻译JSP文件。)
-
指令包括哪些呢?
- include指令:包含指令,在JSP中完成静态包含,很少用了。(这里不讲)
- taglib指令:引入标签库的指令。这个到JJSTL标签库的时候再学习。现在先不管。
- page指令:目前重点学习一个page指令。
-
指令的使用语法是什么?
- <%@指令名 属性名=属性值 属性名=属性值 属性名=属性值…%>
-
关于page指令当中都有哪些常用的属性呢?
-
<%@page session="true|false" %> true表示启用JSP的内置对象session,表示一定启动session对象。没有session对象会创建。 如果没有设置,默认值就是session="true" session="false" 表示不启动内置对象session。当前JSP页面中无法使用内置对象session。
-
<%@page contentType="text/json" %> contentType属性用来设置响应的内容类型 但同时也可以设置字符集。 <%@page contentType="text/json;charset=UTF-8" %>
-
<%@page pageEncoding="UTF-8" %> pageEncoding="UTF-8" 表示设置响应时采用的字符集。
-
<%@page import="java.util.List, java.util.Date, java.util.ArrayList" %> <%@page import="java.util.*" %> import语句,导包。
-
<%@page errorPage="/error.jsp" %> 当前页面出现异常之后,跳转到error.jsp页面。 errorPage属性用来指定出错之后的跳转位置。
-
<%@page isErrorPage="true" %> 表示启用JSP九大内置对象之一:exception 默认值是false。
-
6.JSP的九大内置对象
-
jakarta.servlet.jsp.PageContext pageContext 页面作用域
-
jakarta.servlet.http.HttpServletRequest request 请求作用域
-
jakarta.servlet.http.HttpSession session 会话作用域
-
jakarta.servlet.ServletContext application 应用作用域
- pageContext < request < session < application
- 以上四个作用域都有:setAttribute、getAttribute、removeAttribute方法。
- 以上作用域的使用原则:尽可能使用小的域。
-
java.lang.Throwable exception
-
jakarta.servlet.ServletConfig config
-
java.lang.Object page (其实是this,当前的servlet对象)
-
jakarta.servlet.jsp.JspWriter out (负责输出)
-
jakarta.servlet.http.HttpServletResponse response (负责响应)