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. 一个神奇的HTML标签-----marquee

    今天无意中发现了一个html标签 - <marquee></marquee>可以实现多种滚动效果,无需js控制. 语法:<marquee>...</marqu ...

  2. Abusing SUDO Advance for Linux Privilege Escalation

    Index What is SUDO? Scenario. Sudoer FIle Syntax. Exploiting SUDO zip tar strace tcpdump nmap scp ex ...

  3. SAP GUI Security notice

    出现错误提示: Failed to load administrator rule file.Check your Installation. 原因: 电脑缺少MS XML4.0,导致SAP客户端无法 ...

  4. Android项目实战之高仿网易云音乐项目介绍

    这一节我们来讲解这个项目所用到的一些技术,以及一些实现的效果图,让大家对该项目有一个整体的认识,推荐大家收藏该文章,因为我们发布文章后会在该文章里面加入链接,这样大家找着就很方便. 目录 第1章 前期 ...

  5. MySQL数据库~~~~~锁和事务

    一 锁 innodb存储引擎默认是行级锁 行级锁定最大的特点就是锁定对象的颗粒度很小,也是目前各大数据库管理软件所实现的锁定颗粒度最小的.由于锁定颗粒度很小,所以发生锁定资源争用的概率也最小,能够给予 ...

  6. C# 让你解决方案乱七八糟的DLL放入指定文件夹

    嗯,大家的解决方案可能会有许多dll,这样不美观,而且也麻烦. 很多小白都不知道如何将这些dll放到如自己程序的bin文件夹下. 本渣今天来试着将dll复制到指定的文件夹下~ 比如我之前做的一个Win ...

  7. make && make install的区别

    ./configure 配置环境make 是编译的意思.就是把源码包编译成二进制可执行文件make install 就是安装的意思. make && make install 的意思是 ...

  8. java之匿名内部类

    Person.java package insof; public class Person extends Object{ String name; static int age; public P ...

  9. 《Netty Redis Zookeeper 高并发实战》 勘误

    <Netty Redis Zookeeper 高并发实战> 勘误与申明 疯狂创客圈 Java 高并发[ 亿级流量聊天室实战]实战系列 [博客园总入口 ] 勘误一 文字问题: Page1 J ...

  10. flex布局使用

    什么是flex布局 flex是flexible Box的缩写,意味"弹性盒子",用来为盒子状模型提供最大的灵活性 任何一个盒子都可以指定为flex布局 .box{ display: ...