JSP

一、 什么是 JSP

JSP 和 Servlet

Servlet 有两个缺点是无法克服的:首先,写在 Servlet 中的所有 HTML 标签必须包含 Java 字符串,这使得处理HTTP响应报文的工作十分繁琐;第二,所有的文本和 HTML 标记是硬编码,导致即使是表现层的微小变化,如改变背景颜色,也需要重新编译。

JavaServer Pages(JSP)解决了上述两个问题。同时,JSP 不会取代 Servlet,相反,它们具有互补性。
JSP 页面本质上是一个 Servlet。然而,用 JSP 页面开发比使用 Servlet 更容易。首先,不必编译 JSP 页面;其次,JSP 页面是一个以 jsp 为扩展名的文本文件,可以使用任何文本编辑器来编写它们。

JSP 不需要添加注解或在部署描述符配置映射 URL。应用程序目录中的每一个JSP页面可以直接在浏览器中输入路径页面来访问。添加新的 JSP 界面后,无需重启 Tomcat。

二、 运行 JSP

JSP页面在JSP容器中运行,一个Servlet容器通常也是JSP容器。例如,Tomcat 就是一个 Servlet/JSP 容器。
当一个 JSP 页面第一次被请求时,Servlet/JSP 容器主要做以下两件事情:

1. 把 JSP 页面转换到 JSP 页面实现类,该实现类是一个实现 javax.servlet.jsp.JspPage 接口或子接口 javax.servlet.jsp.HttpJspPage 的 Java 类。JspPage 是 javax.servlet.Servlet 的子接口,这使得每一个 JSP 页面都是一个 Servlet。该实现类的类名由 Servlet/JSP 容器生成。如果出现转换错误,则相关错误信息将被发送到客户端。
2. 如果转换成功,Servlet/JSP 容器随后编译该 Servlet 类,并装载和实例化该类,像其他正常的 Servlet 一样执行生命周期操作。

对于同一个 JSP 页面的后续请求,Servlet/JSP 容器会先检查 JSP 页面是否被修改过。如果是,则该 JSP 页面会被重新转换、编译并执行。如果不是,则执行已经在内存中的 JSP Servlet。
这样一来,一个JSP页面的第一次调用的实际花费总比后来的花费多。

JSP页面可以包含模板数据和语法元素(如:'<%'元素表示Java代码块的开始)。除语法元素之外的一切都是模板数据。模板数据会原样发送给浏览器。例如,JSP页面中的HTML标记和文字都是模板数据。

在 Tomcat 中,welcome.jsp 页面在第一次请求时被转换成名为 welcome_jsp 的 Servlet。你可以在 Tomcat 工作目录下的子目录中找到生成的 Servlet,该 Servlet 继承自 org.apache.jasper.
runtime.HttpJspBase,这是一个抽象类,它继承自 javax.servlet.http.HttpServlet 并实现了 javax.
servlet.jsp.HttpJspPage。

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
<%@ page import="java.util.Date" %>
<%@ page import="java.text.DateFormat" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Date</title>
</head>
<body>
<%
DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.LONG);
out.println(dateFormat.format(new Date()));
%>
</body>
</html>

三、 注释

JSP支持两种不同的注释格式:

  • JSP注释。该注释记录页面中做了什么,不会被发送到浏览器。以"<%--"开始,以"--%>"结束
  • HTML/XHTML注释。这些注释不会被容器处理,会原样发送到浏览器。

四、 隐式对象

Servlet 容器会传递几个对象给它运行的 Servlet。例如,可以通过 Servlet 的 service 方法获取 HttpServletRequest 和 HttpServletResponse 对象。在 JSP 中,可以通过隐式对象来访问上述对象。

pageContext 提供了上下文信息,可以用于获取和设置属性(getAttribute, setAttribute)。属性值可被存储在4个范围之一:页面(JSP),请求(ServletRequest),会话(HttpSession),应用程序(ServletContext)。

public void setAttribute(String name, Object value); // page scope
public Object getAttribute(String name);        // page scope
public void setAttribute(String name, Object value, int scope);
public Object getAttribute(String name, int scope);

out 引用了一个 javax.servlet.jsp.JspWriter 对象,这类似于你在调用 HttpServletResponse 的 getWriter 方法时得到 java.io.PrintWriter。可以通过调用它的 print 方法将消息发送到浏览器。

五、 指令

指令指示 JSP 转换器如何把 JSP 页面转换为 Servlet。

page

<%@ page attribute1="value1" attribute2="value2" ... %>

attributes :

  • import:定义本页面中被导入的 java 类型。类型间可用','分隔。
  • session:值为 True,本页面加入会话管理;值为 False 则相反。默认值为True,访问该页面时,若当前不存在javax.servlet.http.HttpSession实例,则会创建一个。
  • buffer:以 kB 为单位,定义隐式对象 out 的缓冲大小。必须以 kB 后缀结尾。默认大小为8kB或更大(取决于JSP容器)。该值可以为 none,这意味着没有缓冲,所有数据将直接写入PrintWriter。
  • autoFlush:默认值为 True。若值为True,则当输出缓冲满时会自写入输出流。而值为 False,则仅当调用隐式对象的flush方法时,才会写入输出流。因此,若缓冲溢出,则会抛出异常。
  • isThreadSafe:定义该页面的线程安全级别。不推荐使用。
  • info:指定生成的 Servlet 类的 getServletlnfo 方法的返回值。
  • errorPage:定义当出错时用来处理错误的页面。
  • isErrorPage:标识本页是一个错误处理页面。
  • contentType:定义本页面隐式对象 response 的内容类型,默认是 "text/html"。
  • pageEncoding:定义本页面的字符编码,默认是"ISO-8859-1"。
  • isELIgnored:配置是否忽略 EL(Expression Language) 表达式。
  • language:定义本页面的脚本语言类型,默认是 Java,这在JSP2.2中是唯一的合法值。
  • extends:定义JSP实现类要继承的父类。较少使用,仅在非常特殊理由下使用。
  • deferredSyntaxAllowedAsLiteral:定义是否解析字符串中出现"#{"符号,默认是False。"{#"是一个表达式语言的起始符号,因而很重要。
  • trimDirectiveWhitespaces:定义是否不输出多余的空格/空行,默认是False。

大部分 page 指令可以出现在页面的任何位置,但当 contentType 或 pageEncoding 属性时,必须出现在 Java 代码发送任何内容之前。
page 指令也可以出现多次,但出现多次的指令属性必须具有相同的值,import 属性除外,多个包含 import 属性的 page 指令的结果是累加的。

include

include 指令将其他文件中的内容包含到当前JSP页面。

<%@ include file="url" %>

taglib

taglib 指令引入一个自定义标签集合的定义,包括库路径、自定义标签。

<%@ taglib uri="uri" prefix="prefixOfTag" %>

六、 脚本元素

脚本程序是 java 代码块,以"<%"符号开始,以"%>"符号结束。

Today is
<%
out. print(Calendar.getInstance().getTime());
%>

表达式会被JSP容器执行,并使用隐式对象 out 的打印方法输出结果。表达式以
"<%="开始,并由"%>"结束。表达式无需分号结尾。

Today is <%= Calendar.getInstance().getTime() %>

声明以"<%!"开始,以"%>"结束,声明页面中使用的变量和方法。

<%!
public String getTodaysDate() { return new Date().toString(); }
%>
<!DOCTYPE html>
<html>
<head><title>Declarations</title></head>
<body>
Today is <%= getTodaysDate() %>
</body>
</html>

在 JSP 页面中,一个声明可以出现在任何地方,并且一个页面可以有多个声明。
可以使用声明来重写 JSP 页面,实现类的 init 和 destroy 方法。通过声明 jsplnit 方法,来重写 init 方法。通过声明 jspDestroy 方法,来重写 destory 方法。

注意:尽量不要在 JSP 页面中编写 Java 代码。除非应用程序只包含一个或两个简单的 JSP 页面,并且永远不会增长;否则,你应该采用模型2,它规定 JSP 页面仅用于显示 Java 对象中的值。

七、 动作

动作是第三种类型的语法元素,它们被转换成 Java 代码来执行操作,如访问一个 Java 对象或调用方法。

useBean

useBean将创建一个关联 Java 对象的脚本变量。这是早期分离表示层和业务逻辑的努力之一。随着其他技术的发展,如自定义标签和表达语言,现在很少使用useBean方式。

setProperty 和 getProperty

setProperty 动作可对一个 Java 对象设置属性,而 getProperty 则会输出 Java 对象的一个属性。

include

include 动作用来动态地引入另一个资源。可以引入另一个 JSP 页面,也可以引入一个 Servlet 或一个静态的 HTML 页面。

<! DOCTYPE html>
<html><head>
<title>Include action</title>
</head>
<body>
<jsp:include page="menu.jsp">
<jsp:param name="text" value="How are you?"/>
</jsp:include>
</body></html>

对于 include 指令,资源引入发生在页面转换时,即当 JSP 容器把页面转换为生成的 Servlet 时。而 include 动作,资源引入发生在请求页面时。因此,使用 include 动作是可以传递参数的,而 include 指令不支持。

forward

forward 动作把当前页面转向到其他资源。

<jsp:forward page="login.jsp">
<jsp:param name="text" value="Please login"/>
</jsp:forward>

param

用于传递参数。可以通过 request.getParameter(String name) 取出参数值。

plugin

用于指定插件。

八、 错误处理

page 指令的 isErrorPage 属性标志一个 JSP 页面是否为错误页面。
page 指令的 errorPage 属性指向错误处理页面。

<%-- errorHandler.jsp --%>
<%@ page isErrorPage="true" %>
<! DOCTYPE html><html>
<head><title>Error</title></head>
<body>
An error has occurred.<br/>
Error message:
<%
out.print1n(exception. toString());
%>
</body></html>
<%@ page errorPage="errorHandler.jsp"%>
Deliberately throw an exception
<%
Integer. parseInt("Throw me");
%>

参考资料:《Spring MVC 学习指南》 Paul Deck 著

Java Web 学习(2) —— JSP的更多相关文章

  1. java web学习笔记-jsp篇

    1.java web简介 1.1静态页面与动态页面   表现形式 所需技术 静态网页 网页内容固定,不会更新 html,css 动态网页 网页内容由程序动态显示,自动更新 html,css,DB,ja ...

  2. java web 学习笔记 - JSP标签编程

    1.JSP标签编程简介 标签编程在开发中并不常见,主要是为了更好的理解struts等框架的标签而打基础,完善相关知识体系. 标签编程分为: 一个继承自TagSupport的标签类,一个在WEB-INF ...

  3. java web 学习笔记 jsp内置对象

    jsp2 表达式语言的内置对象 使用方式${object.attributename} 或者${object["attributename"]} pageContext pageS ...

  4. Java Web学习笔记--JSP for循环

    JSP for循环 <%@ page language="java" contentType="text/html; charset=UTF-8" %&g ...

  5. java web 学习笔记 - jsp用的文件上传组件 SmartUpload

    ---恢复内容开始--- 1. SmartUpload 此控件在jsp中被广泛的使用,而FileUpload控件主要是用在框架中 2. 如果想要使用,需要在tomcat的lib目录中,将SmartUp ...

  6. Java Web学习笔记之---JSP

    Java Web学习笔记之---JSP (一)JSP常用语法 (1)HTML注释 <!--所要注释的内容 --> 在客户端显示一个注释. (2)隐藏注释 <%--所要注释的内容--% ...

  7. Java Web 学习路线

    实际上,如果时间安排合理的话,大概需要六个月左右,有些基础好,自学能力强的朋友,甚至在四个月左右就开始找工作了.大三的时候,我萌生了放弃本专业的念头,断断续续学 Java Web 累计一年半左右,总算 ...

  8. Java web 学习之旅

    java web学习之旅 来公司十天了,感觉已经慢慢地融入了这个环境中,几个学长人都很好,都是在他们帮助下,我才能比较顺利的开始了学习java web的旅途. 来这里学习的第一个阶段是做一个简单的用户 ...

  9. [原创]java WEB学习笔记66:Struts2 学习之路--Struts的CRUD操作( 查看 / 删除/ 添加) 使用 paramsPrepareParamsStack 重构代码 ,PrepareInterceptor拦截器,paramsPrepareParamsStack 拦截器栈

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

随机推荐

  1. Exceptionless应用--自定义插件

    遇到的问题/需求 这里会把一些敏感的参数记录下来,我们需要屏蔽掉,如图 我们希望日志里面有当前登录用户的信息,如图: 处理方法 tip:这里用的是.net非.net core 第一个问题(屏蔽敏感参数 ...

  2. jvm虚拟机笔记<三> 类文件结构与类加载机制

    java虚拟机具有语言无关系,它只和“class文件“这种特定的二进制文件格式绑定. 不同语言的编译器将对应的程序编译成字节码文件(*.class),送给jvm执行. class文件本质上就是一张表, ...

  3. Ligg.EasyWinApp-102-Ligg.EasyWinForm:Function--ControlBox、Tray、Resize、Menu

    首先请在VS里打开下面的文件,我们将对源码分段进行说明: Function(功能):一个应用的功能界面,一个应用对应多个Function(功能):如某应用可分为管理员界面.用户界面. 首先我们来看一下 ...

  4. UML简单介绍—类图这么看就懂了

    如何看懂类图 1.类图简介 描述类的内部结构和类与类之间的关系,是一种静态结构图. 在UML类图中,常见的有以下几种关系: 泛化(Generalization),  实现(Realization),关 ...

  5. ES6 ... 展开&收集运算符

    ...展开&收集运算符,也就是说他可以干两件事情,展开和收集 一:收集,顾名思义把散列东西收集到一个地方,这个地方ES6规定收集在数组中 例如:下面函数fn将传递的参数收集在arg变量中,打印 ...

  6. mongodb主备配置

    前言:mongodb目前推荐的方式是副本集的方式实现,但是副本集需要三台服务器,目前配置为主备方式 假设你已经安装好了mongo,并配置好了响应的用户 下面修改mongodb.conf配置文件,开启认 ...

  7. StaticList

    到目前为止,我们还无法创建一个顺序存储结构线性表的对象出来,为什么呢?顺序存储空间究竟是什么,顺序存储空间的大小是多少? StaticList设计要点——类模板 使用原生数组作为顺序存储空间 使用模板 ...

  8. IT兄弟连 HTML5教程 HTML5文字版面和编辑标签 小结及试题

    小结 HTML标签包含结构标签和基础标签,基础标签是在页面制作最常使用的一些标签.基础标签包含标题标签(<h1>~<h6>).换行标签(<br>).段落标签(< ...

  9. adb devices无法连接mumu模拟器

    解决方案: 如果你的android环境能够直接访问 adb 的相关指令.只需要把mumu模拟器打开 然后打开cmd -> 输入 adb connect 127.0.0.1:7555 就能直接连上 ...

  10. 如何优雅规避NPE

    项目中尤其是在持久层,难免会有大量的针对集合,对象,字符串的操作,为了程序的健壮性,我们不得不进行判空,像下面箭头式编码吗? if(null!=person){ ... if(null!=addres ...