文章目录

  • 第七章 作为JSP:使用JSP
  • 第八章 没有脚本的页面:无脚本的JSP
  • 第九章 强大的定制标记:使用JSTL
  • 第十章 定制标记开发

第七章 作为JSP:使用JSP

在JSP中可以使用scriptlet(即放在<%…%>标记中的java代码)放入常规的java代码;
使用page指令导入包;
表达式元素自动打印放在标记之间的内容;

<%@ page import="foo.*,java.util.*"%>
<html>
<body>
The page count is:
//不要在表达式的最后加上分号
<%=Counter.getCount()%>
</body>
</html>

三种JSP元素:

  • Scriptlet: <% %>
  • 指令: <%@ %>
  • 表达式: <%=%>(表达式会成为out.print()的参数)

所有scriptlet和表达式代码都放在服务方法中,scriptlet中声明的变量总是局部变量——在scriptlet中声明变量意味着每次运行服务方法时这个变量都会重新初始化;
JSP元素:<%!和%>标记之间的所有内容都会增加到类中——变量和方法都可以声明;
容器把JSP转换为servlet时,服务方法最前面有一堆隐式对象声明和赋值。
JSP中两种不同类型的注释:
<!–HTML注释–>:容器把它直接传递给客户,在客户端浏览器会把它解释为注释;
<%–JSP注释–%>:原文注释;
容器根据你的JSP生成一个类,这个类实现了HttpJspPage接口,关于容器生成的servlet的API:

  • jspInit():这个方法由init()方法调用可以覆盖;
  • jspDestroy():这个方法由servlet的destroy()方法调用,也可覆盖;
  • _jspService():这个方法由servlet的service()方法调用,不能覆盖;
    如果 一个Web应用包含JSP,部署这个应用时,在JSP生命周期中,整个转换和编译步骤只发生一次
    初始化JSP:
    配置servlet初始化参数,必须在<servlet>标记中增加一个<jsp-file>元素;
    为一个JSP定义servlet时,还必须为JSP页面定义一个servlet映射;
    覆盖jspInit()
<%!//使用声明覆盖jspInit()方法public void jspInit(){ServletConfig sConfig=getServletConfig();//在一个servelt中可以调用继承的方法String eamilAddr=sConfig.getInitParamenter("email");ServletContext ctx=getServletContext();//得到Servlet的一个引用,并设置一个应用作用域属性ctx.setAttribute("mail",eamilAddr);

JSP使用4个隐式对象得到和设置对应JSP中4个属性作用域的属性;

可以使用PageContext引用来得到任意作用域的属性,包括从页面作用域得到绑定到PageContext的属性;
三个指令:

指令 作用
<%@ page import=“foo.*” session=“false”%> 定义页面特定的属性
<%@ taglib tagdir=“WEB-INF/tags/cool” prefix=“cool”%> 定义JSP可以使用的标记库
<%@ include file=“wickedHeader.html” %> 定义在转换时增加到当前页面的文本和代码

EL:用途是提供一种更简单的方法来调用java代码,但是代码本身放别的地方;
使用<scripting-invalid>标记让JSP禁用脚本元素;

第八章 没有脚本的页面:无脚本的JSP

使用表达式语言(EL)和标准动作构建JSP页面
使用几个标准动作——消除JSP中的脚本代码(包括声明、scriplet和表达式);

//使用标准动作(不使用脚本)
<html><body>
<jsp:useBean id="person" class="foo.Person" scope="request"/>
Person created by servlet:<jsp:getProperty name="person" property="name"/>
</body></html>

<jsp:useBean>用来声明和初始化在<jsp:getProperty>中使用的具体bean对象;
用<jsp:getProperty>得到bean属性的性质值;
如果<jsp:useBean>找不到对应名的属性对象,会新建一个:

利用<jsp:useBean>体,可以有条件地运行代码,只有找不到bean属性,而且创建了一个新bean时才会运行体中的代码;(bean没有带参数的构造函数)
建立多态的引用,向标记增加type属性,例如:

<jsp:useBean id="person" type="foo.person" class="foo.Employee" scope="page">

如果在<jsp:useBean>或<jsp:getProperty>标记中没有指定作用域,容器会使用默认作用域"page";

利用param属性,可以把bean的性质值设置为一个请求参数的值。只需指定请求参数;
如果请求参数名与bean性质名匹配,就不需要在<jsp:setProperty>标记中为该性质指定值;
Bean标记会自动转换基本类型的性质;

利用<jsp:getProperty>,只能访问bean属性的性质,不能访问嵌套性质——使用EL(JSP表达式语言);
EL表达式:

${person.name}//放在大括号里,且前面有一个美元前缀符

表达式中的第一个命名变量可以是一个隐式对象,也可以是一个属性;

使用点号(.)操作符访问性质和映射值;
如果表达式变量后有一个点号,点号左边的变量必须是一个Map或一个bean;
点号右边必须是一个Map键或一个bean性质;
或者使用中括号:

数组和List中的String索引会强制转换为int;

EL有一些隐式对象。x想从请求得到HTTP请求方法,使用requestScope会得到请求性质,而不是request性质,要得到request性质,需要通过pageContext;

Method is:${pageContext.request.method}


可以编写简单的EL表达式,调用自己写的普通Java类的静态方法;

  • 编写一个有公共静态方法的Java类;
  • 编写一个标记库描述文件(TLD)——提供了定义函数的Java类与调用函数的JSP之间的一个映射;
  • 在JSP中放一个taglib指令,定义命名空间;
  • 使用EL调用函数:按照${prefix:name()}的形式从表达式调用函数;

例如:

<%@ taglib prefix="mine" uri="WEB-INF/foo.tld"%>

对于可重用的模板部件,JSP有一个处理机制——包含(include);
inlcude指令告诉容器:复制所包含文件的内同并粘贴到这个文件中;
<jsp:include>标准动作内部原理不同于include指令——include在转换时发生,<jsp:include>标准动作在运行时发生;
不要把开始和结束HTML和BODY标记放在可重用部件中;
使用<jsp:param>定制包含的内容:
完成包含的JSP:

<html><body>
<jsp:include page="Header.jsp">//没有结束反斜线jsp:param name="subTitle" value="Whatever"/>
</jsp:include>
</body></html>

使用新参数的被包含页眉:

<img src="data:images/Web-Services.jpg"><br>
<em><strong>${param.subTitle}</strong></em><br>

从一个jsp转发到另一个jsp或者servlet:<jsp:forward>标准动作;
提供条件转发的JSP(Hello.jsp)

<html><body>
Welcome to our page!
<% if (request.getParameter("userName")==null){%><jsp:forward page="HandleIt.jsp"?>
<% } %>
Hello ${param.userName}
</body></html>

请求转发到的目标JSP(HandleIt.jsp)

<html><body>
you need to log in again.
<form action="Hello.jsp" method="get">
Name: <input name="userName" type="text">
<input name="Submit" type="submit">
</form>
</body></html>

发生转发时,请求转发到的目标资源首先会清空响应缓冲区——不要先刷新输出再转发;

第九章 强大的定制标记:使用JSTL

使用JSTL之前,需要将文件(“jstl.jar"和"standard.jar”)放在Web应用的WEB-INF/lib 目录中;
使用<c:out>标记转换HTML特殊字符为实体格式;

<c:out>提供一个default属性

<b> Hello <c:out value='${user}' default='guest' />.</b>

<c:forEach>不用脚本实现循环

var属性存放集合中的各个元素,items对应具体要循环处理的集合(数组、collection、Map);可选属性varStatus得到一个循环计数器;
"var"变量的作用域仅限于标记内部;
使用<c:if>完成条件包含,例如(成员在页面看到更多的东西)

//JSP代码
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html><body>
<strong>Member comments</strong><br>
<hr>${commentList}<hr>//假设有一个servlet会根据用户的登录信息设置useType属性
<c:if test="${userType eq 'member'}">//标记和EL中单引号和双引号都能用<jsp:include page="inputComments.jsp"/>//此处省略input.Comments.jsp的构造
</c:if>

if/else的构造——<c:choose>、<c:when>和<c:otherwise>实现;
<c:set>的两个版本,var版本设置属性变量,target版本设置bean性质或Map值(一些要点和技巧)
使用<c:remove>删除一个属性;
除了include指令、<jsp:include>标准动作,使用<c:import>将资源的内容增加到JSP中;

JSP中URL的重写:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html><body>
This is a hyperlink with URL rewriting enabled.
<a href="<c:url value='/inputComments.jsp' />">Click here</a>
//在"value"相对URL的最后增加jsessionid,如果禁用了cookie.
</body></html>

URL编码把不安全/保留的字符替换为其他字符,然后在服务器端完成解码;<c:url>不会自动地对URL编码;在<c:url>的体中使用<c:param>,完成URL的重写和编码;

设计定制页面处理错误,然后使用page指令配置错误页面;

//指定的错误页面("erroePage.jsp")
<%@page isErrorPage="true" %>
<html><body>
<strong>Bummer.</strong>
You cause a ${pageContext.exception} on the server.<br>//可以得到详细错误信息
//容器为错误页面提供了一个额外的exception对象
<img src="data:images/bummerGuy.jpg">
</body></html>//抛出异常的“坏”页面("badPage.jsp")
<%@ page errorPage="erroePage.jsp" %>
<html><body>
About to be bad...
<% int x=10/0;%>//使页面抛出异常
</body></html>

可以在DD中为整个Web应用声明错误页面,甚至可以为不同的异常类型或HTTP错误码类型(404,500等)配置不同的错误页面;
使用<c:catch>标记完成一种try/catch,把有风险的标记或表达式包起来;
想在<c:catch>标记结束后访问异常,可以使用可选的var属性,把异常对象放在页面作用域,并按照声明的var值来命名;
使用非JSTL的标记库:URI是标记库描述文件(TLD)的唯一标识符,容器需要这个信息将JSP中使用的标记名映射到实际调用的java代码;
当标记的<body-content>元素值不是empty时,这个标记才能有体;
可以把TLD看作定制标记的API;
taglib<uri>只是一个名,而不是一个位置;
容器会自动建立TLD和<uri>名之间的映射;如果JSP使用多个标记库,确保taglib uri名是唯一的,不要使用保留的前缀;

第十章 定制标记开发

利用标记文件,可以使用一个定制标记调用可重用的内容;
在JSP中放一个taglib指令,并调用这个标记:

<%@ taglib prefix="myTags" tagdir="/WEB-INF/tags" %>
<html><body>
<myTags:Header/>
Welcome to our site.
</body></html>

对于标记文件,发送的不是请求参数,而是标记属性;

标记文件使用attribute指令;这个指令只能由标记文件使用;

对于标记属性很长的内容可以放在标记的体中,使用tag指令声明body-content类型;标记文件标记的体重不能使用脚本代码(默认scriptless),除非使用"empty"或"tagdependent",可以声明body-content;
如果标记文件在一个JAR中部署,就必须有一个TLD,如果直接放在Web应用中,就不需要TLD;
建立一个简单的标记处理器:

如果标记需要一个属性,就要在TLD中声明,并在标记处理器中为每个属性提供一个bean式的设置方法;
JspFragment是表示JSP代码的一个对象;getJspContext()实际上是标记体向其他对象提供信息的一个途径;
SkipPageException:停止处理页面,会显示异常出现之前的所有内容;
Tag处理器API有5个接口和3个支持类;
简单标记只有一个doTag(),但是传统标记有一个doStartTag()和一个doEndTag(),有一个doAfterBody()方法,在计算体之后并在doEndTag()运行前调用;
传统标记生命周期取决于返回值;
如果没有覆盖返回一个整数的TagSupport生命周期方法,要当心TagSupport方法实现返回的默认值;
标记处理器类必须为TLD中声明的每个标记属性实现一个设置方法,使用DynamicAttribute接口:

为使用DynamicAttributes,标记处理器类必须实现JSP API的DynamicAttributes接口,碧必须实现setDynamicAttribute()方法,使用hashmap存储属性名/值对;
通过扩展BodyTagSupport,能从Body-Tag接口得到另外两个生命周期方法——setBodyContent()和doInitBody();
标记可以调用其父标记;
标记处理器类不是一个servlet或JSP,但有PageContext的一个引用;
标记文件的查找位置(复习):

Head First Servlets and JSP(二)相关推荐

  1. JSP二手书交易平台设计与实现

    自己已经看过不再需要的二手书,和对需要的二手书进行求购,这是一个很好的处理二手出的方式.让网站用户只要登录进去二手书交易平台就可以查看所有的内容,用户可以查看新闻以及二手书籍的及时更新的信息,能够以最 ...

  2. Java基于JSP二手书交易平台设计与实现

    现代网络技术发展迅速,传统的书店销售模式受到诸如场地.资金.宣传等因素制约,已经不能满足人们的日益增长的图书购买需求,网上书店应运而生,基于web的网络书店给人们带来了很大便利,网络书店不仅是传统售书 ...

  3. 【Head First Servlets and JSP】笔记24:include指令与include动作 param动作 foward动作...

    include指令与include动作 1.样例代码 <%@ page contentType="text/html;charset=UTF-8" language=&quo ...

  4. Why use Servlets JSPs: an introduction(Head First Servlets and JSP)

    ? A GET request appends form data to the end of the URL. ? A POST request includes form data in the ...

  5. JSP与servlets的区别

    从架构上说,JSP可以被看作是从Servlets高级提炼而作为JAVA Servlet2.1 API的扩展而应用.Servlets和JSP最早都是由Sun Microsystems(升阳公司)开发的. ...

  6. [读书笔记]《Head First Servlets JSP》2nd

    书名:Head First Servlets and JSP: Passing the Sun Certified Web Component Developer Exam 出版商:O'Reilly ...

  7. [JSP暑假实训] 二.JSP网站创建及Servlet实现注册表单提交、计算器运算

    本系列文章是作者暑假给学生进行实训分享的笔记,主要介绍MyEclipse环境下JSP网站开发,包括JAVA基础.网页布局.数据库基础.Servlet.前端后台数据库交互.DAO等知识. 本篇文章开始讲 ...

  8. JSP WEB开发入门基础到高手进阶教程002

    JSP WEB开发入门基础到高手进阶教程 -------开发入门 JSP与微软的Active Server Pages 兼容,但它是使用类似HTML的卷标以及Java程序代码段而不是VBScript. ...

  9. 160329(二)、web.xml配置详解

    1.启动一个WEB项目的时候,WEB容器会去读取它的配置文件web.xml,读取<listener>和<context-param>两个结点. 2.紧急着,容创建一个Servl ...

最新文章

  1. 【GDKOI2016Day1T1-魔卡少女】【拆位】线段树维护区间内所有连续子区间的异或和...
  2. 了解下C# 类型转换
  3. Kettle transformation 操作内容快速查询
  4. from __future__ import absolute_import用法心得小结
  5. cannot find -lcudart
  6. 网易云信自研大规模传输网核心系统架构剖析
  7. sqlDataAdapter的FillSchema用法
  8. linux部署jar项目报错_Spring boot项目部署linux系统tomcat报错解决办法
  9. MySQL的前缀索引及Oracle的类似实现
  10. fscanf返回值被忽略怎么解决_pytest的fixture怎么用?
  11. 13. 查看网络端口、配置网络
  12. vlan的基本指令_vlan划分命令
  13. MFC控件学习:图片(bmp/png)
  14. vs2017 开关“/NOENTRY”只与 DLL 兼容;链接时不使用“/NOENTRY”
  15. 网易公司创始人兼CEO丁磊:独家版权偏离了传播的初衷,已陷入资本运作的怪圈...
  16. linux内核编程(hello world示例程序)
  17. PHP+MYSQL 可视化Echarts 完整源码,小白总结
  18. Unity的Animator的动画层(Layer)
  19. python数据分析案例分析题_Python数据分析-案例分析
  20. 关于windows-1252页面乱码问题

热门文章

  1. 我也来分享一个魔兽显血改键工具
  2. xmind 8 pro Mac破解版(思维导图) 附xmind 8 序列号
  3. 电脑Windows使用中遇到的那些问题
  4. 几个在线画图的工具,以备偷懒之需
  5. UnityShader学习笔记 更复杂的光照
  6. 征信大数据的盈利模式,怎么赚钱?
  7. 玲珑骰子安红豆,入骨相思君知否?
  8. Python--提高pip的下载速度
  9. 艾美捷焦磷酸(PPi)分析试剂盒,高通量筛选神器
  10. c语言写学程序,入门:我的第一个程序|学编程写游戏(C语言)