一、什么是JSP?

JSP(Java Server Pages):是以Java语言为基础的动态网页开发技术
Servlet特点:在Java源码中嵌入html源码
JSP特点:在html源码中嵌入java代码
JSP运行过程
1、tomcat获得JSP文件后,先将JSP转成servlet,变成xxx.java(servlet源码),
2、tomcat将java文件编译成class文件
3、tomcat运行class文件,并将结果输出到浏览器,

二、JSP语法

包括JSP中的java部分,包括JSP脚本(JavaScript,或者java代码)以及JSP指令(Directive)与JSP标签(Tag)等

1.JSP脚本:

1、使用<% Java代码 %>,中间java代码必须遵循Java语法
2、使用<%=xxx %>来输出结果,xxx表示某个域中的变量
使用<%=result %>来输出结果,servlet中就会将其转换为out.print(result)进行输出。
可以输出各种类型数据:int、double、boolean、String、Object等
3、JSP注释
<%-- --%>:jsp注释
//:java单行注释,只能在<% %>中使用
/* */:Java多行注释,只能在<% %>中使用
<!-- --> :这个注释,会发送到浏览器端的源码中显示
4、JSP中申明方法与属性(全局变量),使用<%! 方法体或属性名 %>
5、在JSP中使用if语句,或者使用for循环,whilt循环等都可以使用标签实现(下面会讲到)

2、JSP指令

JSP指令格式:<%@ directive {attribute=value}* %>
解释:
directive:指令名称,例如page指令
attribute=value:紧跟指令名称后面的就是各种属性,以键值对的形式书写
* :后面能跟0个或多个属性

1.page指令:用来声明JSP页面的属性等。
例如<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> 
page指令的常用属性

指令属性名称

指令属性值

指令属性功能

language

java

解释该JSP文件时采用的语言,一般为java语言,默认为java

extends

任何类的全名

编译该JSP文件时继承哪个类,JSP为Servlet,因此当指明继承普通类时需要实现Servlet的init、destroy等方法

import

任何包名、类名

引入该JSP中用到的类、包等,import是唯一可以声明多次的page指令属性,中间用英文逗号隔开,

session

true、false

该JSP内是否内置Session对象,如果为true,则内置Session对象,可直接使用,否则反之,默认为true

autoFlush

true,false

是否运行缓存,如果为true,则使用out.println()等方法输出的字符串并不是立刻到达客户端服务器的,而是暂时存到缓存里,缓存满了或者程序执行完毕或者执行out.flush()操作时才到客户端,默认为true。

buffer

none或者数字KB

指定缓存大小,当autoFlush设为true时有效

isThreadSafe

true,false

是否线程安全,如果为true,则运行多个线程同时运行该jsp程序,否则只运行一个线程,默认为false

isErrorPage

true,false

指定该页面是否为错误显示页面,如果为true,则该JSP内置有一个Exception对象exception,可直接使用,否则没有,默认为false

errorPage

某个JSP页面的相对路径

指明一个错误页面,如果该JSP程序抛出一个未捕捉的异常,则转到errorPage指定的页面,errorPage指定的页面通常isErrorPage属性为true,且内置的exception对象为未捕捉的异常

contentType

有效的文档类型

客户端浏览器根据该属性判断文档类型,HTML格式为text/html、纯文本格式为text/plain、JPG图像为image/jpeg、GIF图像为image/gif、WORD文档为application/msword,该属性常跟着charset设置编码一起,作用是通知服务器和浏览器都使用同一个码表

info

任意字符串

指明JSP的信息,该信息可以通过Servlet.getServletInfo()方法获取到

trimDirective Whitespaces

true、false

是否去掉指令前后的空白字符,默认为false

pageEncoding

UTF-8,ISO-8859-1等

指定一张码表来对该JSP页面进行编码,

2.include指令
比较简单,只有一种形式 <%@ include file="relativeURL"%>  
relativeURL:本应用程序内另一个JSP文件或者HTML文件的路径,
例如,网址内所有页面均有一个统一风格的导航栏和页脚版权,那么就可以使用该指令将其包含进来 
特点:include指令会将包含页面的源代码添加到使用include指令的页面中来,然后编译成class文件
<jsp:include page="relativeURL">作用跟include指令一样,但是不同的是,include行为是运行时单独执行包含页面,然后把执行的结果包含到本页面来,属于先运行后包含。
3.taglib指令
作用:用来指明JSP页面内使用的JSP标签库,taglib指令有两个属性,uri为类库的地址,prefix为标签的前缀
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

3、JSP行为

JSP内置的标签就被称为JSP行为(JSP Actions)。
只要书写很少的标记代码就能使用JSP提供的丰富功能,JSP行为其实是对常用的JSP功能的抽象与封装,可以取代JSP脚本,JSP中就少一些嵌入java代码的地方。
格式:<jsp:elements {attribute="value"}* />
jsp:标签的前缀,说明是jsp内置的标签,
elements:行为的名称,
attribute=value:使用键值对来编写属性
*:能指定0个或多个属性对
1.<jsp:include />行为
include行为用于运行时包含某个文件,如果被包含的文件为JSP程序,则先会执行JSP程序,然后在把执行的结果包含进来。 
作用是跟include指令一样的,区别是,include指令是将被包含的文件的源码加入到了本JSP程序中,然后在进行编译,属于静态包含,
而include行为只是将被包含的文件的运行结果包含进自己。属于动态包含。
2.Java bean行为
Java bean行为是一组与Java Bean 相关的行为,包括useBean行为、setProperty行为、getProperty行为等
Java Bean就是普通的Java类,也被称为POJO,只有私有的属性与对应的getter方法和setter方法
注意其中当私有的属性为boolean类型时,习惯上一般把getter方法写成isXxx();而不是getXxx();
(1).useBean行为  
<jsp:useBean id="beanObject" class="className" scope="Value">
在jsp中定义一个java bean对象
如果创建一个新的javabean对象user在page作用域内,会先判断在page作用域内是否有叫user对象的javabean,如果有则取它,如果没有则创建新的javabean对象。
id:指明Java Bean对象的名称,JSP中可以使用该名称引用该Java Bean对象,相当于给new出来的对象取一个变量名,
class:Java Bean类的全名
scope:该java bean对象的作用范围,可以写的就四个,也就是JSP的四大作用域,page、request、session、application

page:只能在当前JSP页面使用,如果不在JSP页面,那么就会失效。
    request:A页面请求转发到B页面,那么使用的是同一个request,那么A,B页面都算是request的作用域,也就是通过请求转发的页面都是其作用域。
    session:该作用域在一个web项目下任何位置应该都访问的到,只要cookie不关闭,并且cookie设置的访问路径为"/"。
    application:其实就是Servlet中的servletContext,服务器下的所有项目都能访问到。

(2).setProperty行为
<jsp:setProperty name="beanName" property="propertyName" value="">
对Java Bean对象进行属性的设置
name:java bean对象的名称,也就是在useBean行为中的id
property:对象中的属性名,
value:要对其属性进行赋值的值
(3).getProperty行为
<jsp:getProperty name="beanName" property="propertyName" />
获取JavaBean对象的某个属性值
name:java bean 对象的名称,也就是在useBean行为中的id
property:对象的属性名
3.<jsp:forward />行为
实现请求转发功能,Servlet中通过
request.getRequestDispatcher("someServlet").forward(request,response);
而在JSP中也能够实现相同的功能,只不过用的是<jsp:forward />行为,实际上forward行为就是对其进行了封装。
格式:

<jsp:forward page="someServlet">
    <jsp:param name="param1" value="value1"/>
    <jsp:param name="param2" value="value2"/>
</jsp:forward>

page:需要跳转到的页面或者servlet、  “`“`参数行为,可以带参数转发,name、value是以键值对的形式带过去的 4.“`“`行为 directive行为,就相当于JSP指令,比如“`

三、JSP隐藏的九大内置对象和四大作用域

1.JSP隐藏的九大内置对象:page、config、application、request、response、session、out、exception、pageContext

对象名称

对象功能

page

page对象代表当前JSP页面,是当前JSP编译后的Servlet类的对象。相当于this。

config

标识Servlet配置,类型:ServletConfig。api跟Servlet中的ServletConfig对象是一样的,能够获取servlet的初始化参数,获取servletContext对象,获取servletName

application

标识web应用上下文,类型:ServletContext。与Servlet中的ServletContext的使用一致

request

请求对象,类型:httpServletRequest

response

响应对象  类型:httpServletResponse

session

表示一次会话,在服务器端记录用户状信息的技术

out

输出响应体,类型:JspWriter。JSP页面转换为Servlet后,使用的out对象是JspWriter类型的,所以会先将要发送的数据存入JSP输出缓存中,然后,等JSP输出缓存满了在自动刷新到servlet输出缓存,等serlvet输出缓存满了,或者程序结束了,就会将其输出到浏览器上。除非手动out.flush()。

exception

表示发生异常对象,类型 Throwable,在上面我们介绍page指令中的一个errorPage属性时就有说到他。使用它,必须结合page指令中的isErrorPage属性和errorPage属性。

pageContext

表示 Jsp页面上下文(Jsp管理者) 类型:PageContext。它是JSP页面的管理者(上下文),所以JSP中的内置对象,它统统能够获得。 还可以简化开发:pageContext.forward(“”);pageContext.include(“”);

2.JSP的四大作用域:page、request、session、application

作用域名称

作用域功能

page

代表变量只能在当前页面上生效

request

代表变量能在一次请求中生效,一次请求可能包含一个页面,也可能包含多个页面,比如页面A请求转发到页面B

session

代表变量能在一次会话中生效,基本上就是能在web项目下都有效,session的使用也跟cookie有很大的关系。一般来说,只要浏览器不关闭,cookie就会一直生效,cookie生效,session的使用就不会受到影响。

application

代表变量能一个应用下(多个会话),在服务器下的多个项目之间都能够使用。

四、EL表达式 ${}

EL表达式:简化JSP中java代码开发,它不是一种开发语言,是JSP中获取数据的一种规范。
JSP中可以使用EL表达式,EL表达式是用”${}”括起来的脚本,用来更方便地读取对象,EL表达式写在JSP的HTML代码中,而不能写在”<%%>”引起的JSP脚本中,现在就来了解一下,EL表达式是如何来替代JSP脚本或者JSP行为的。
EL表达式有11个内置对象:pageScope、requestScope、sessionScope、applicationScope、pageContext、param、paramValues、header、headerValues、cookie、initParam。其中有四个作用域对象:pageScope、requestScope、sessionScope、applicationScope。

对象名称

对象功能

pageContext

表示的是JSP中内置对象pageContext,能获取request等其他JSP八大内置对象

param

表示一个请求参数  ${param.username}  等效  request.getParameter(“username”);

paramValues

表示一组请求参数  ${paramValues.loves}  等效request.getParameterValues(“loves”);

header

表示一个请求头  ${header.referer}  等效request.getHeader(“referer”);

headerValues

表示一组请求头  ${header.cookie}  等效 request.getHeaders(“cookie”);   获取的请求头参数中的内容是一组内容,比如cookie就有可以是多个cookie一起传过来

cookie

获得cookie对象

initPatam

web项目初始化参数,servletContext.getInitParameter(“xxx”);

还有一种特殊的用法,直接获取对象变量:${user.username}
其中user为User的一个实例对象,并且存放在page作用域中,上面这句代码的意思是,依次从page、request、session、application作用域查找user对象,直到找到为止,底层使用的是pageContext.findAttribute(); 是一样的效果。

EL表达式比较简单,使用它的目的是为了减少JSP脚本,尽量不要在HTML中嵌入Java代码,显的很混乱,而在HTML中使用EL表达式,就比较好来获取JSP中各种对象,获取四大作用域中的值。如果要获取四大作用域中的数据,则可以使用${pageScope.xxx} 。如果想要获取请求参数,则使用param或paramValues。如果想要获取请求头中的一些信息,获取想要获取Servlet的一些对象,比如request、session等,可以使用pageContext来获取request对象,然后在获取所需要的信息,或者直接使用header对象来获取头信息。如果想获取web初始化参数,则使用initPatam。最主要的是要记得EL中有哪11个内置对象,知道了他们就知道了EL可以获取哪些信息。

五、JSTL标签库

JSTL(JavaServerPages Standard Tag Library):JSP标准标签库。使用JSTL标签库,需要用taglib指令导入JSTL标签库。
STL标签库中包括很多种类的标签,例如core、fmt、fn、sql 、xml等。

1.core标签库

<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
常用标签
<c:out/>、<c:set/>、<c:remove/>、<c:if/>、<c:choose/>、<c:forTokens />、<c:catch /> 、<c:url />、 <c:redirect />、<c:forEach/>
常用标签使用方法

<c:out/>标签
out :将指定内容输出到浏览器,默认支持el表达式,
<c:out value="" default="" escapeXml />
value:输出的值,可以为EL表达式
default:如果value属性的值不存在,会输出default属性值
excapeXml:如果为true,则会为value中的特殊字符进行转义,默认为true

<c:set/>标签
<c:set value="值" var="id" scope="request" />
其中var不能接受EL表达式,只能是字符
<c:set target="" property="" value="" />
target:跟var类似,但是它只能够接受EL表达式,可以是一个对象。与var互补。
property:对象中的属性名 
value:属性赋值
使用哪种set标签,就看自己的需求了。

<c:remove/>标签
<c:remove var="id" scope="request"/>
其中var不能接受EL表达式,只能是字符

<c:if test=""/>标签
if条件语句

<c:if test="${not empty sessionScope.user}">
欢迎${ sessionScope.user}
</c:if >

            
<c:choose/>标签
choose标签格式
<c:choose>相当于switch
<c:when>相当于case
<c:otherwise>相当于default
            
<c:forTokens > 标签
将自定义字符串,按照指定字符进行分割,并遍历输出
items:自定义字符串
delims:指定字符
var:遍历的变量名

<c:forTokens items="www.baidu.com" delims="." var="a">
${a}
</c:forTokens >
        

<c:catch > 标签
相当于try catch
var:捕捉后的异常对象

<c:catch var="e">
<%--target只接受el表达式,所以此处出现异常--%>
<c:set target="ABC" property="name" value="xiaoming" >
</c:catch >
<c:out value="${e.message}"> </c:out >

<c:forEach/>标签
增强的for循环,
格式:

<c:forEach items="" var="" > 
</c:forEach>

items:需要遍历的对象
var:用于存放遍历的每一项内容,存放在page作用域,只能在循环体中使用
<c:forEach begin="1" end="10" var="num" step="2" > 
${num}
</c:forEach>

begin:从1开始
end:到10结束
step:每次加2
var:循环的变量

<c:url/>标签
如果cookie禁用了,那么只能将url进行重写才能让session继续生效,而使用的api是response.encodeURL();就是将SESSIONID当作参数带过来,而url标签的作用就是实现类似功能
<c:url value="" var="" scope=""/> 
value:要进行重写的url
var:如果写了该变量,那么就会将其重写后的url存入page作用域中,如果scope没有的话,默认就是page,否则以scope属性值为准,在作用域范围内就可以直接拿着这个变量使用了,如下面所展示的。
scope:作用域范围,默认是page,

<c:url value="/index.jsp" var="myurl" > 
<c:param name="username" value="xiaoming"></c:param>
</c:url>
<a href="${myurl}"></a>
        
访问后点击超链接,如果没有关闭cookie,不会将SESSIONID写入url中 。

<c:redirect />标签
重定向到index.jsp
<c:redirect url="/index.jsp"></c:redirect >

<c:import />标签
类似于JSP的include行为和include指令,JSTL也提供了include功能的标签,不过import标签功能更强大,甚至可以把Internet上的网页包含进来。
<c:import url="http://www.baidu.com" charEncoding="utf-8"/>

2.fmt标签库

是一些辅助性功能标签,用的不多
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
 
<fmt:requestEncoding/>设置编码,相当于Java中的request.setCharacterEncoding(“”);
post提交中文参数,使用<fmt:requestEncoding value="utf-8"/>来设置编码,就不会出现中文乱码了。
get提交中文参数,该标签就会失效,除非到TOMCAT的server.xml中,将URLEncoding设置为UTF-8(默认为ISO-8859-1)。

3.fn方法库

提供一些方法,函数,例如字符串查找,截取之类。因为与core,fmt标签格式不一样,并且必须在el表达式中使用,所以不叫fn标签库而叫fn方法库。格式:fn:methodName()。在el表达式中调用方法时,其实就是用到了fn方法库。

contains方法判断是否包含指定的字符串,相当于java里String类的contains方法。
fn:contains(String string1,String string2);
endsWith方法,判断某字符串是否以指定的参数结尾,
fn:endWith(String string1,String string2);
startsWith方法,判断某字符串是否以指定参数开始
fn:startsWith(String string1,String string2);
escapeXml方法,是否转义字符
fn:escapeXml(source);
indexOf方法,查找字符串在另一个字符串中第一次出现的位置
fn:indexOf(String string1,String string2);
split方法,将字符串以指定参数为界分割成多个字符串形成字符串数组
join方法,与split方法相反,将字符串数组以参数为界连接成字符串
length方法,取字符串,数组,集合的长度