作为JSP

JSP变成Servlet。这个servlet不用你来创建。容器会查看你的JSP,把它转换成Java源代码,在编译成完整的Java servlet类。


JSP技术模型

6.1 识别或描述以下元素,或为以下元素编写JSP代码:

  1. 模板文本
  2. 脚本元素(注释、指令、声明、scriptlet和表达式)
  3. 标准动作和制定动作
  4. 表达式语言元素

6.2 编写使用以下指令的JSP代码:

  1. page(带有属性import、session、contentType和isELIgnored)
  2. include
  3. taglib

6.3 编写使用了正确语法的JSP文档(基于XML的文档)

6.4 描述页面生命周期的作用和事件序列:

  1. JSP页面转换
  2. JSP页面编译
  3. 加载类
  4. 创建实例
  5. 调用jspInit方法
  6. 调用_jspService方法
  7. 调用_jspDestroy方法

6.5 给定一个设计目标,使用适当地隐式对象编写JSP代码:

  1. request
  2. response
  3. out
  4. session
  5. config
  6. application
  7. page
  8. pageContext
  9. exception

6.6 配置部署描述文件来声明一个或多个标记库,禁用计算(表达式)语言,以及禁用脚本语言

6.7 给定一个特定的设计目标,要求将一个JSP片段包含在另一个页面中,编写JSP代码使用最合适的包含机制(include指令或jsp:include标准动作)


JSP变成一个servlet

这一章将解决下面几个问题:

  1. JSP文件中的各个部分最后会放在servlet源代码中的说明位置?
  2. 能访问JSP页面的“servlet性”吗?例如,JSP中有ServletConfig或ServletContext的概念吗?
  3. JSP中可以放哪些类型的元素?
  4. JSP中的不同元素有什么语法?
  5. JSP的生命周期是怎样的?能介入到JSP生命周期中吗?
  6. JSP中的不同元素在最后的servlet中如何交互?

建立一个JSP显示被访问了多少次

开发环境:

BasicCounter.jsp文件代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
The page count is:
<% //JSP不认识Counter类,所以需要foo.Counterout.println(foo.Counter.getCount());
%>
</body>
</html>

Counter.java文件代码:

package foo;public class Counter {private static int count = 0;public static synchronized int getCount() {count++;return count;}
}

XML文件代码:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://java.sun.com/xml/ns/javaee"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"id="WebApp_ID" version="3.0"><welcome-file-list><welcome-file>/BasicCounter.jsp</welcome-file></welcome-file-list></web-app>

实验结果:


使用page指令导入包

我们发现写foo有点麻烦。所以,使用page指令导入包。将JSP文件代码更改为:

<%@ page import="foo.*" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
The page count is:
<% out.println(Counter.getCount());
%>
</body>
</html>

实验结果:

指令有3种:

  1. page
  2. include
  3. taglib

page允许你导入包。导入多个包<%@ page import="foo.*,java.util.*" %>

记住:<%@ page import = ? %>中的page是指令,import是page的属性,?是属性的值


表达式

我们在JSP代码里面使用了out.println(),我们应该尽量的避免这样的做法。所以可以更改JSP代码:

<%@ page import="foo.*" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
The page count is:
<%= Counter.getCount() %>
</body>
</html>

实验结果:

我们已经看到3种不同类型的JSP元素:

  1. Scriptlet:<% %>
  2. 指令:<%@ %>
  3. 表达式:<%= %>

容器看到<%= Counter.getCount()%>就会把它转换为out.print(Counter.getCount());

如果看到的是<%= Counter.getCount();%>,注意最后一个分号,容器会转换成out.print(Counter.getCount(););这种样子,明显会报错

要记住:不要在表达式的最后加分号(还有要注意的地方就是,表达式不能输出一个void的类型,想想如果调用一个返回值为void的方法,就会报错)。


一个炸弹

修改JSP文件代码如下:

<%@ page import="foo.*" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
//定义一个变量是count,JSP是一个servlet
<% int count = 0; %>
The page count is:
//count+1
<%= ++count %>
</body>
</html>

我们认为JSP是一个servlet,用scriptlet声明一个变量,然后去使用它。结果刚刚开始的时候还不错,如下:

第二次访问:

发现怎么和结果1等同呢?

于是我们查看jsp最后会变成一个什么样的servlet代码。如下:

/** Generated by the Jasper component of Apache Tomcat* Version: Apache Tomcat/9.0.4* Generated at: 2018-08-02 12:04:37 UTC* Note: The last modified time of this file was set to*       the last modified time of the source file after*       generation to assist with modification tracking.*/
package org.apache.jsp;import javax.servlet.*;
import javax.servlet.http.*;
//与servlet的差别
import javax.servlet.jsp.*;
//导入的包
import foo.*;//继承也不一样
public final class BasicCounter_jsp extends org.apache.jasper.runtime.HttpJspBaseimplements org.apache.jasper.runtime.JspSourceDependent,org.apache.jasper.runtime.JspSourceImports {private static final javax.servlet.jsp.JspFactory _jspxFactory =javax.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("javax.servlet");_jspx_imports_packages.add("javax.servlet.http");_jspx_imports_packages.add("foo");_jspx_imports_packages.add("javax.servlet.jsp");_jspx_imports_classes = null;}private volatile javax.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 javax.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() {}//service方法public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)throws java.io.IOException, javax.servlet.ServletException {final java.lang.String _jspx_method = request.getMethod();if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method) && !javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSPs only permit GET POST or HEAD");return;}//下面是隐式对象final javax.servlet.jsp.PageContext pageContext;javax.servlet.http.HttpSession session = null;final javax.servlet.ServletContext application;final javax.servlet.ServletConfig config;javax.servlet.jsp.JspWriter out = null;final java.lang.Object page = this;javax.servlet.jsp.JspWriter _jspx_out = null;javax.servlet.jsp.PageContext _jspx_page_context = null;try {response.setContentType("text/html");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("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n");out.write("<html>\r\n");out.write("<head>\r\n");out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\r\n");out.write("</head>\r\n");out.write("<body>\r\n");//我们写的代码,定义一个变量int count = 0; out.write("\r\n");out.write("The page count is:\r\n");//我们写的代码,然count+1out.print( ++count );out.write("\r\n");out.write("</body>\r\n");out.write("</html>");} catch (java.lang.Throwable t) {if (!(t instanceof javax.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);}}
}

由上面代码的注释就知道了,原来我们定义的count是局部变量。因此我们知道了我们的原因。


另一个JSP元素

我们想要声明一个全局变量。

将JSP代码修改为(<%! %>设置全局变量):

<%@ page import="foo.*" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
//设置全局变量
<%! int count = 0; %>
The page count is:
<%= ++count %>
</body>
</html>

我们在看看JSP.java文件的代码:

/** Generated by the Jasper component of Apache Tomcat* Version: Apache Tomcat/9.0.4* Generated at: 2018-08-02 12:20:55 UTC* Note: The last modified time of this file was set to*       the last modified time of the source file after*       generation to assist with modification tracking.*/
package org.apache.jsp;import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import foo.*;public final class BasicCounter_jsp extends org.apache.jasper.runtime.HttpJspBaseimplements org.apache.jasper.runtime.JspSourceDependent,org.apache.jasper.runtime.JspSourceImports {//count变成了全局变量int count = 0; private static final javax.servlet.jsp.JspFactory _jspxFactory =javax.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("javax.servlet");_jspx_imports_packages.add("javax.servlet.http");_jspx_imports_packages.add("foo");_jspx_imports_packages.add("javax.servlet.jsp");_jspx_imports_classes = null;}private volatile javax.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 javax.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 javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)throws java.io.IOException, javax.servlet.ServletException {final java.lang.String _jspx_method = request.getMethod();if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method) && !javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSPs only permit GET POST or HEAD");return;}final javax.servlet.jsp.PageContext pageContext;javax.servlet.http.HttpSession session = null;final javax.servlet.ServletContext application;final javax.servlet.ServletConfig config;javax.servlet.jsp.JspWriter out = null;final java.lang.Object page = this;javax.servlet.jsp.JspWriter _jspx_out = null;javax.servlet.jsp.PageContext _jspx_page_context = null;try {response.setContentType("text/html");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("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n");out.write("<html>\r\n");out.write("<head>\r\n");out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\r\n");out.write("</head>\r\n");out.write("<body>\r\n");out.write("\r\n");out.write("The page count is:\r\n");out.print( ++count );out.write("\r\n");out.write("</body>\r\n");out.write("</html>");} catch (java.lang.Throwable t) {if (!(t instanceof javax.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);}}
}

正如上面代码所看见的,count变成了全局变量。实验效果很好,会一直累计访问次数。


方法声明

修改JSP文件代码:

<%@ page import="foo.*" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
//JSP中定义方法
<%! int doubleCount(){count = count*2;return count;
} %>
<%! int count = 0; %>
The page count is:
<%= ++count %>
</body>
</html>

JSP.java文件在int count的上方增加了下面这样的一段代码:

//方法定义
int doubleCount(){count = count*2;return count;
}
//全局变量
int count = 0;

于是乎,我们好像知道了JSP就是一个servlet。


容器如何处理JSP

  1. 查看指令,得到转换时可能需要的信息。(比如导包)
  2. 创建一个HttpServlet子类,所生成的servlet会拓展:org.apache.jasper.runtime.HttpJspBase
  3. 如果有声明,容器会将这些声明写到类文件中,通常放在类声明下面,并在服务方法前面。(正如我们所看到的Tomcat声明了好多静态变量和好多方法)
  4. 建立服务方法。服务方法的具体方法名是_jspService()。这个方法由servlet超类被覆盖的service()方法调用,要接收HttpServletRequest和HttpServletResponse参数在建立这个方法时,容器会声明并初始化所有隐式对象
  5. 将普通的HTML(称为模板文本)、scriptlet和表达式放到服务方法中,完成格式化,并写至PrintWriter响应输出。

隐式对象

API 隐式对象
JspWriter out
HttpServletRequest request
HttpServletResponse response
HttpSession session
ServletContext application
ServletConfig config
Throwable exception
PageContext pageContext
Object page

我们这里说说第4个作用域:pageContext(页面级作用域)

其中PageContext封装了其他隐式对象,所以如果向某些辅助对象提供一个PageContext引用,这些辅助对象就可以使用这个PageContext引用得到其他隐式对象的引用以及所有作用域的属性。

再说说exception,只有指定“错误页面”才能用到这个隐式对象


练习

开发环境:

hobby.html代码:

<%@ page import="java.util.*" %>
<html>
<body>The friends who share your hobby of<%= request.getParameter("hobby") %>are:<br><% ArrayList al = (ArrayList)request.getAttribute("names");%><% Iterator it = al.iterator(); %><% while(it.hasNext()){         %><%= it.next() %>    <br><% } %>
</body>
</html>

Hobby.java这个servlet代码:

package foo;import java.io.IOException;
import java.util.ArrayList;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class Hobby extends HttpServlet{private static final long serialVersionUID = 1L;@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("html/text");ArrayList<String> al = new ArrayList<String>();al.add("Fred");al.add("Pradeep");al.add("Philippe");request.setAttribute("names", al);request.getRequestDispatcher("/BasicCounter.jsp").forward(request, response);}
}

BasicCounter.jsp代码:

<%@ page import="java.util.*" %>
<html>
<body>The friends who share your hobby of<%= request.getParameter("hobby") %>are:<br><% ArrayList al = (ArrayList)request.getAttribute("names");%><% Iterator it = al.iterator(); %><% while(it.hasNext()){         %><%= it.next() %>    <br><% } %>
</body>
</html>

XML代码:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://java.sun.com/xml/ns/javaee"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"id="WebApp_ID" version="3.0"><servlet><servlet-name>hobby</servlet-name><servlet-class>foo.Hobby</servlet-class></servlet><servlet-mapping><servlet-name>hobby</servlet-name><url-pattern>/HobbyPage.do</url-pattern></servlet-mapping><welcome-file-list><welcome-file>/hobby.html</welcome-file></welcome-file-list></web-app>

实验结果:

点击提交后:


所生成servlet的API

JSP的UML图:

3个关键方法:

  1. jspInit(),这个方法由init()方法调用。可以覆盖这个方法。
  2. jspDestroy(),这个方法由servlet的destroy()方法调用。可以覆盖这个方法。
  3. _jspService(),这个方法由servlet的service()方法调用,这说明,对于每个请求,它会在一个单独的线程中运行。容器将Request和Response对象传递给这个方法。不能覆盖这个方法。

JSP生命周期

  1. 部署.jsp文件,此时不做任何事情
  2. 客户请求.jsp文件,将.jsp文件转换成一个servlet.java文件
  3. 容器尝试这把这个.java文件被编译为.class文件
  4. 容器加载servlet类
  5. 容器实例化servlet并调用jspInit()方法
  6. 容器创建一个新线程来处理这个请求,通过调用_jspService()方法
  7. 调用jspDestroy()方法销毁servlet实例

这里指出:Web应用包含JSP,部署这个应用时,在JSP生命周期中,整个转换和编译步骤只发生一次


初始化JSP

我们想着既然JSP也是servlet,那么我们能不能能不能像初始化Servlet一样初始化JSP呢?该怎么做呢?

开发环境:

配置servlet初始化参数(DD)

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://java.sun.com/xml/ns/javaee"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"id="WebApp_ID" version="3.0"><servlet><servlet-name>MyTestInit</servlet-name><jsp-file>/TestInit.jsp</jsp-file><init-param><param-name>email</param-name><param-value>ikickedbutt@wickedlysmart.com</param-value></init-param></servlet><servlet-mapping><servlet-name>MyTestInit</servlet-name><!-- 注意这里的url名字,映射而已 --><url-pattern>/TestInit.do</url-pattern></servlet-mapping></web-app>

覆盖jspInit()

<html>
<body><%! public void jspInit(){ServletConfig sConfig = getServletConfig();String emailAddr = sConfig.getInitParameter("email");ServletContext ctx = getServletContext();ctx.setAttribute("mail", emailAddr);}%><%= config.getInitParameter("email") %><%= application.getAttribute("mail") %>
</body>
</html>

实验结果如下:


JSP中的属性

- servlet中 JSP中(隐式对象)
应用 getServletContext() application
请求 request request
会话 request.getSession() session
页面 不适用 pageContext

通常我们不需要关系页面作用域,除非我们在开发定制标记

PageContext的UML图:


使用pageContext的实例

设置一个页面作用域属性

<%  Float one = new Float(42,5);pageContext.setAttribute("foo",one);
%>

获取一个页面作用域属性

<%= pageContext.getAttribute("foo")%>

使用pageContext设置一个会话作用域属性

<%Float two = new Float(22.4);pageContext.setAttribute("foo",two,PageContext.SESSION_SCOPE);
%>

使用pageContext获得一个会话作用域属性(等价于session.getAttribute(“foo”))

<%= pageContext.getAttribute("foo",PageContext.SESSION_SCOPE)%>

使用pageContext获得一个应用作用域属性(等价于application.getAttribute(“mail”))

<%= pageContext.getAttribute("mail",PageContext.APPLICATION_SCOPE)%>

使用pageContext,即使不知道作用域也可以查找一个属性(查找顺序:先从请求作用域查找,再查找会话作用域,最后查找应用作用域。先找到哪一个就算“赢”)

<%= pageContext.findAttribute("foo")%>

JSP的3个指令

指令 格式 说明
page指令 <%@ page import=”foo.*” session=”false”%> 定义页面特定的属性,如字符编码、页面响应的内容类型,已经这个页面是否要有隐式对象。page指令可以使用至多13个不同属性(如import属性)
taglib指令 <%@ taglib tagdir=”/WEB-INF/tags/cool” prefix=”cool”%> 定义JSP可以使用标记库
include指令 <%@ include file=”wickedHeader.html”%> 定义在转换时增加到当前页面的文本和代码。从而允许你建立可重用的块,这些可重用的块能增加到各个页面上,而不必在每个JSP中重复写所有这些代码

page指令的属性

属性 说明
import 导包
isThreadSafe 定义生成的servlet是否需要实现SingleThreadModel(最好不要这样做)
contentType 定义JSP响应的MIME内容
isELIgnored 定义转换(.jsp到.java)这个页面时是否忽略EL表达式
errorPage 定义一个资源的URL,如果有未捕获到的Throwable,就会发送到这个资源。如果这个属性指定了一个JSP,该JSP的page指令中就会有isErrorPage=”true”属性
language 定义scriptlet、表达式和声明中使用的脚本语言(现在就只有一个值,就是”java”)
extends JSP会变成一个servlet类,这个属性则定义了这个类的超类(一般不会使用这个属性)
session 定义页面是否有一个隐式的session对象。默认值为”true”
buffer 定义隐式out对象如何处理缓存
autoFlush 定义缓存的输出是否自动刷新输出。默认值为”true”
info 定义放到转换后页面中的串,这样就能使用所生成servlet继承的getServletInfo()方法来得到这个信息
pageEncoding 定义JSP的字符编码。默认为”ISO-8859-1”

EL

HTML开发员不懂Java,所以不能再JSP里面写这种Java代码。

于是,EL出现了,它的出现完美的解决下面2个问题:

  1. 不应该要求Web页面设计人员必须懂Java
  2. JSP中的Java代码很难修改和维护

EL小试牛刀

EL表达式:${applicationScope.mail}等价于<%= application.getAttribute("mail")%>


禁用scriptlet

在DD中配置:

<web-app ...><jsp-config><jsp-property-group>//作用于所有的.jsp文件<url-pattern>*.jsp</url-pattern>//只要配置上这个就行了,记住true是禁用scriptlet<scripting-invalid>true</scripting-invalid></jsp-property-group></jsp-config>
</web-app>

禁用EL表达式

两种方式:

(1)在DD中配置:

<web-app ...><jsp-config><jsp-property-group>//作用于所有的.jsp文件<url-pattern>*.jsp</url-pattern><el-ignored>true</el-ignored></jsp-property-group></jsp-config>
</web-app>

(2)在JSP中用page指令(注意前面还有一个is):

<%@ page isELIgnored="true"%>

初见JSP的“动作”

标准动作:<jsp:include page="wickedFooter.jsp">
其他动作:<c:set var="rate" value="32">

看看动作的语法,把它与其他类型JSP元素的语法做个比较。我们回答下面问题:

(1)动作元素与scriptlet有什么区别?
本质上没有区别,只是代码形式改变了。

(2)看到一个动作时,怎么才能认出来?
不知道= =


本章完

Head First JSP---随笔五相关推荐

  1. JSP(五):属性范围

    定义:设置一个属性后,可以经过多少个其他页面后仍然可以保存的范围. 所有存在JSP里面的属性都有四种范围:page.request.session.pageContext 转载于:https://ww ...

  2. 随笔 | 五楼西区17架b面1列3层

    昨晚跟某人聊起图书馆,一下子勾起了好多回忆. 悠悠北洋,书海无疆,理一理身旁旧事,别往我来时模样.每天晚上闭馆音乐响起的时候,都会自己碎碎念一句,男生版本的似乎更好听一点hhh,然后收拾好自己的书包下 ...

  3. jsp随笔-工作使用-直播功能

    1.状态功能 <div class="form-group"> <label for="" class="col-md-3 cont ...

  4. 3D数学基础:图形与游戏开发---随笔五

    向量运算 5.1 线性代数与几何 数学中专门研究向量的分支称作线性代数. 5.2 符号约定 变量是代表未知量的占位符.本书用不同的字体来区分不同的变量: 标量,用斜体的小谢罗马或者希腊字母表示,如a. ...

  5. 阅读javascript高级程序设计随笔(五)

    2.5 操作符 操作符包括算术操作符.位操作符.关系操作符合相等操作符.ECMAScript操作符与众不同的是,它们能够适用很多值,例如字符串.数字值.布尔值甚至对象.在应用于对象时,相应的操作符通常 ...

  6. 实验三 JSP应用开发进阶

    全部:https://download.csdn.net/download/weixin_42859280/11218260 实验三 JSP应用开发进阶:PDF版本[已经完成所有代码] 想看文档上面有 ...

  7. JSP基本语法、3个编译指令、7个动作指令、9个内置对象

    一.jsp概述 JSP是java server page的缩写,其本质是一个简化的servlet,是一种动态网页技术标准.jsp页面是在HTML页面中嵌入java程序段,使用jsp开发的应用程序可以跨 ...

  8. Spring+SpringMvc+Hibernate(SSH)+bootstrap/Jsp整合

    文章目录 前言: 准备工作: 最终项目的目录结构: 源码 一.使用idea创建web app项目 二.导包 三.SpringMVC配置 第一步:配置spring-mvc.xml 第二步:配置 web. ...

  9. java基础学习之JSP动态web开发技术

    一 JSP是什么? jsp 页面允许在标准的HTML 页面中包含Java代码 目标:是支持表现和业务逻辑的分离. 表现:由前端人员实现. 业务逻辑: 有后台程序员处理 二JSP页面的运行原理 第一步 ...

  10. jsp页面跳转的几种方式

    一, 使用href超链接标记 (客户端跳转) 二, 提交表单 (客户端跳转) <form name="form" method="post" action ...

最新文章

  1. windows远程ssh与scp操作linux
  2. shell中的条件语句
  3. jq的ajax和模块引擎
  4. 基于Java的RDMA高性能通信库(六):SDP - Java Socket Direct Protocol
  5. Springboot+Docker+RabbitMQ教程来了。
  6. abap--REUSE_ALV_GRID_DISPLAY事件子过程和cl_gui_grid类的事件对应关系
  7. mysql索引失效_MySQL索引失效的底层原理
  8. 文档 笔记 我全都要
  9. Workaround for Search for my account in MyAppointment
  10. 实习生解雇_我们解雇了我们的顶尖人才。 我们做出的最佳决定。
  11. 2021年看得见的粉丝价值——五大平台KOL粉丝分析研究报告
  12. WCF服务编程 学习笔记(1)
  13. js实现一键复制到剪切板上_js实现各种复制到剪贴板的方法(分享)
  14. 编译原理实验-用FLEX自动构造词法分析程序
  15. ZPL指令打印标签时出现白色窄条的坑
  16. 大数据平台架构包含哪些功能
  17. 医疗管理系统软件 linux系统,MyPatients 4.0.2 发布,医疗信息管理系统
  18. Cannot run program jad
  19. synchronized同步机制——如果你愿意一层一层剥开我的心
  20. WPF 中Combox的使用

热门文章

  1. NYOJ 301 递推求值(矩阵快速幂)
  2. Android开发 - 设置DialogFragment全屏显示
  3. C# Linq to SQL — Group by
  4. sql server 提示无法彻底删除_复制-而无法删除数据库或重新配置发布订阅
  5. Eclipse 3.7 3.x SWT/Jface 开发环境搭建
  6. 在asp.net中控制回车键
  7. 关于CheckBoxList和RadioButtonList的几个问题
  8. 软件如何控制硬件、编译器和操作系统是否需要编译
  9. SCons命令 之 从入门到精通
  10. jdbc获取结果行数_如何获取JDBC中的行数?