初步了解JSP
JSP(Java Server Pages)的产生主要是为了解决浏览器页面生成的问题。由于Servlet的应用逻辑是在Java文件中,并且完全从表示层中的HTNL分离开来,所以Servlet输出HTML非常困难。而JSP就是将Java代码和HTML组合的一种Servlet的简易形式,其作用就是代替Servlet输出HTML。
JSP工作原理
JSP会在客户端第一次请求JSP文件时被翻译为HttpJspPage类(该类为接口Servlet的一个子类)的一个.java
文件,翻译后的文件放在服务器工作目录下。java文件会被编译为.class
文件,客户端访问的就是class文件。只有Tomcat检测到Jsp程序改动才会重新编译jsp,不然则会保存class文件便于下次访问。
JSP语法
- 模板数据:模板数据就是JSP中的HTML代码,模板数据的内容会作为
out.write()
的参数,直接输出到页面中。 - 元素:JSP页面中的Java代码、JSP指令、JSP标签
JSP脚本
JSP脚本就是JSP页面中的java代码,也叫scriplet。脚本片段写在<% %>中,它会复制到java文件的service方法中的对应位置。JSP脚本有三种方式:
- <% %>:定义局部变量,编写语句
- <%! %>:定义类或方法,声明的变量会翻译成java文件的全局变量
- <%= %>:表达式输出,作为
out.print()
方法的参数,可以编写任意的对象
除此之外,JSP的注释写在<%-- --%>
中,也可以用HTML注释<!-- -->
或java代码注释`//``。
标签式写法: Jsp提供一种scriptlet标签来编写java代码
<jsp:scriptlet>
String s = "Hello World";
out.print(s);
</jsp:scriplet>
JSP三大指令
JSP指令用来声明JSP页面的相关属性,例如编码方式、文档类型等。
<%@ 指令名 属性名="值" %>
page指令
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
page指令常见属性:
- import = “{package.class | package.*},…” //导包
- sesssion = “true | false” //是否自动创建session
- extends = “package.class” //当前jsp对应java类需要继承的父类
- errorPage = “relative_url” //当页面出现错误以后,要转发到的错误页面
- isErrorPage = “true | false” //当前页面是否为一个错误页面
- isELIgnored = “true | false” //是否忽略EL表达式
- contentType=“text/html;charset=UTF-8” //当前jsp内容的类型
- pageEncoding = “characterSet | ISO-8859-1” //当前页面使用的编码
include指令
include指令为静态包含,将一个页面包含进另一个页面。它只会将被包含文件的代码内容复制并包含进来,再将包含后的文件进行编译。
<%@ include file = "test.jsp" %>
taglib指令
JSP支持标签技术,要使用标签技术就先得声明标签库和标签前缀,taglib指令就是用来指明JSP页面内使用标签库技术。
<jsp:标签名 属性名= "属性值"></jsp:标签名>
JSP七大行为
JSP行为是一组JSP内置的标签,是对常用的JSP功能的抽象和封装。
include行为
include行为与include指令不同的是,include行为为动态包含。其原理就是封装了request.getRequestDispatcher(String url).include(request, response)
<jsp:include page=""/>
动态包含就是先编译被包含的页面,再将页面的结果写入被包含的页面中。动态包含可以向被包含的页面传递参数,并且分别处理包含页面(如果有相同名称的参数,使用静态包含就会报错)。
forward行为
forward行为封装了request.getRequestDispatcher(String url).forward(request, response)
,用来进行页面的跳转。
<jsp:forward page=""/>
param行为
当使用include和forward行为引入或请求转发给其他资源时,可以使用param行为向资源传递参数。
<jsp:forward page = "test.jsp">
<jsp:param name = "abc" value="123"/>
</jsp:forward>
directive行为
该行为用来代替指令<%@ %>
的语法:
<jsp:directive.include file= " "/>
<jsp:directive.page/>
<jsp:directive.taglib/>
和使用
<jsp:scriptlet>
替代<% %>
一样,使用该行为可以让JSP页面更加美观。
javaBean行为
javaBean:javaBean指的是满足三种条件,分别为有无参构造、成员属性私有化以及对外界访问提供get和set方法的java类。
JSP提供了三个操作javaBean对象的行为:
- < jsp:useBean />:在jsp页面中查找javaBean对象
在指定的域范围内存在返回javaBean对象引用,不存在则实例化一个新的。
<jsp:useBean id="实例化对象的名称" class="类的全名" scope="保存范围" />
- < jsp:setProperty />:设置javaBean的属性
setProperty通过反射的原理,将属性名和客户端传递过来的数据对象名称保持一致,从而封装到javaBean对象上。
<jsp:setProperty name="对象名称" property="属性名" param="参数名" value="值" >
- < jsp:getProperty />:获取javaBean的属性
<jsp:getProperty name="对象名" property="属性名"/>
JSP九大内置对象
JSP引擎在调用JSP对应的JSPServlet时,会传递或创建9个与web开发相关的对象,开发人员可以通过定义的9个相应的变量获得这9大对象的引用。
out对象
out对象用于向浏览器输出数据,与之对应的是Servlet的PrintWriter对象。out对象返回类型是JspWriter,可以理解为带缓存的PrintWriter。
int getBufferSize() //得到缓存大小
int getRemaining() //得到未使用缓存的大小
boolean isAutoFlush()
void println()
void flush()
void close()
void clearBuffer()
void clear()
request对象(其实就是HttpServletRequest)
response对象(其实就是HttpServletResponse)
config对象(其实就是ServletConfig)
session对象(HttpSession)
application对象(ServletContext)
page对象
代表当前jsp页面,是当前jsp编译后的Servlet类的对象,相当于java类的this。
exception对象
exception封装了jsp页面抛出的异常信息,用来处理错误页面。
pageContext对象
pageContext对象代表着jsp页面编译后的页面,它封装了对其他8大内置对象的引用,通过pageContext可以获取到其他的8个内置对象(通过调用get方法)。
作为域对象pageContext也有以下三个方法:
- setAttribute(String name, Onject obj)
- getAttribute(String name)
- removeAttribute(String name)
pageContext域对象只在当前page范围内有效,request在一次请求中有效,session在一次会话中有效,ServletContext/application在整个web应用都有效。
pageContext重载了三个attribute方法来让pageContext除了page还能获取到其他域对象的属性:
getAttribute(String name, int scope)
setAttribute(String name,Object obj, int scope)
removeAttribute(String name, int scope)
page参数可以为以下:
- PageContext.APPLICATION_SCOPE
- PageContext.SESSION_SCOPE
- PageContext.REQUEST_SCOPE
- PageContext.PAGE_SCOPE
pageContext其他方法:
findAttribute(String name) //按从小到大顺序在各个域对象查找属性
forward(String url) //简化了RequestDispatcher.forward方法
include(String url) //简化了RequestDispatcher.include方法
EL表达式
EL(Expression Language)表达式是在${ }
里面的脚本,用来更方便的读取对象、读取数据。使用EL表达式可以方便地读取对象中的属性、提交的参数、javaBean甚至集合。
获取数据
域对象
在域对象中调用setAttribute(String name, Object obj)
设置完属性后可以通过EL表达式${name}
获取到域对象的数据。原理:EL表达式调用findAttribute(String name)
分别从page、request、session、application四个域对象中查找相应的对象。
JavaBean属性
在一个JavaBean中设置属性值后,EL内部会通过反射机制调用对象的get
方法获取属性。
集合数据
EL表达式还可以从Collection集合和Map集合读取内容
Collection集合:
List<Person> list = new ArrayList();
Person person1 = new Person("111");
Person person2 = new Person("222");
list.add(person1);
list.add(person2);
session.setAttribute("list", list);
${list[0].username}
${list[1].username}
Map集合:
Map<String, Person> map = new HashMap<>();
Person person1 = new Person("111");
Person person2 = new Person("222");
map.put("aaa",person1);
map.put("111",person2);
session.setAttribute("map", map);
${map.aaa.username}
${map["222"].username}
回显数据
EL表达式最大的特点为:如果获取到的数据为null,则输出空白字符串。利用这个特点可以让数据回显:
User user = new User();
user.setGender("male");
request.setAttribute("user", user);
<input type="radio" name="gender" value="male"
${user.gender=='male'?'checked':''}>男
<input type="radio" name="gender" value="female"
${user.gender=='female'?'checked':''}>女
EL运算符
EL内置对象
- pageContext:对应jsp中的pageContext对象
pageContext.setAttribute("abc", "123");
${pageContext.getAttribute("abc")}
- pageScope:代表page域中保存属性的Map对象
pageContext.setAttribute("abc", "123");
${pageScope.abc}
- requestScope:代表request域中保存属性的Map对象
request.setAttribute("abc", "123");
${requestScope.abc}
- sessionScope:代表session域中保存属性的Map对象
session.setAttribute("abc", "123" );
${sessionScope.abc}
- applicationScope:代表application域中保存属性的Map对象
application.setAttribute("abc", "123");
${applicationScope.abc}
- param:表示一个保存了所有请求参数的Map对象(一般处理别的页面数据如表单、地址栏)
<input type="text" name="username">用户名<br>
<input type="password" name="password">年龄<br>
${param.username}
${param.password}
- paramValues:表示一个保存了所有请求参数的Map对象,对于某个请求参数返回的是一个String[]
<input type="checkbox" name="hobbies" value="football">⾜球
<input type="checkbox" name="hobbies" value="basketball">篮球
<input type="checkbox" name="hobbies" value="table tennis">兵乓球<br>
${paramValues.hobbies[0]}
${paramValues.hobbies[1]}
${paramValues.hobbies[2]}
- header:保存了所有http请求头字段的Map对象
${header.Host}
- headerValues:返回保存所有请求头字段的string[]数组
${headerValues.Cookie[0]}
- cookie:表示一个保存了所有cookie的Map对象
Cookie cookie = new Cookie("abc", "123"};
${cookie.JSESSIONID.value}
${cookie.key}
访问cookie对象,${cookie.key.name}
访问cookie的名称,${cookie.key.value}
访问cookie的值。
- initParam:表示一个保存了所有web应用初始化参数的map对象
${initParam.name}
EL函数库
EL函数库就是fn方法库,是JSTL标签库中的一个库,其全部方法都是跟字符串有关的。使用JSTL标签库需要导入jstl.jar
和standard.jar
包并用taglib指令声明使用该标签库:
<%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
- fn:toLowerCase
- fn:toUpperCase
- fn:trim
- fn:length
- fn:split
- fn:join
- fn:indexOf
- fn:contains
- fn:startsWith
- fn:replace
- fn:substring
- fn:substringAfter
- fn:endsWith
- fn:escapeXml
- fn:substringBefore
JSTL
JSTL(Jsp Standard Tag Library)即JSP标准标签库,提供了一系列的JSP标签,实现了基本的功能:集合的遍历、数据的输出、字符串的处理、数据的格式化等。
core标签库
core标签库是JSTL的核心标签库,实现了最基本的功能:流程控制、迭代输出等操作。
c:out
属性名 | 是否支持EL | 属性类型 | 属性描述 |
---|---|---|---|
Value | true | Object | 指定要输出的内容 |
escapeXml | true | Boolean | 指定是否将(>、<、&、’、")等特殊字符进行HTML编码转换后再进行输出 |
default | true | Object | 指定如果value属性的值为null时所输出的默认值 |
c:set
属性名 | 是否支持EL | 属性类型 | 属性描述 |
---|---|---|---|
value | true | Object | 指定属性值 |
var | false | String | 指定要设置的Web域属性的名称 |
scope | false | String | 指定属性所在的Web域 |
target | true | Object | 指定要设置属性的对象,这个对象必须是javaBean对象或java.util.Map对象 |
preperty | true | String | 指定当前要为对象设置的属性名称 |
c:remove
属性名 | 是否支持EL | 属性类型 | 属性描述 |
---|---|---|---|
var | false | String | 指定要设置的Web域属性的名称 |
scope | false | String | 指定属性所在的Web域 |
c:catch
该标签用来处理程序中产生的异常,只有一个var属性,var属性封装了异常的信息。
<c:catch var="example">
<c:set target="person" property="age" value="32"/>
</c:catch>
${example}
c:if
属性 | 是否支持EL | 属性类型 | 属性描述 |
---|---|---|---|
test | true | Boolean | 决定是否处理标签体中的内容的条件表达式 |
var | false | String | 指定将test属性的执行结果保存到某个web域中的某个属性 |
scope | false | String | 指定将test属性的执行结果保存到哪个web域中 |
c:choose
choose标签类似于java中if-else
条件语句,需要联合when和otherwise标签一起使用
<c:choose>
<c:when test="${param.name='abc'}">
1111
</c:when>
<c:otherwise>
222
</c:otherwise>
</c:choose>
c:forEach
属性名 | 是否支持EL | 属性类型 | 属性描述 |
---|---|---|---|
var | false | String | 指定将当前迭代到的元素保存到page域中的属性名 |
items | true | 任何支持的类型 | 将要迭代的集合对象 |
begin | true | int | 若指定items属性,从集合的第begin个元素开始进行迭代;没有指定items属性就从begin指定值开始迭代直到end值结束 |
end | true | int | 迭代结束标志 |
step | true | int | 指定迭代步长 |
varStatus | false | LoopTagStatus | 将当前被遍历对象的信息记录在varStatus |
varStatus代表着当前被迭代对象的信息,有以下属性:
- index:返回当前是第几个对象
- count:已遍历对象数
- first:是否是第一个
- last:是否是最后一个
- current:当前被迭代对象
- begin:开始位置
- end:最后位置
- step:步长
c:forTokens
该标签类似于String类的split()和for循环的一种结合,与forEach标签不同的是forTokens标签的items属性里面是字符串,这个字符串会被delims属性的内容分割成多个字符串。
c:import
import标签类似于JSP行为<jsp:include/>
和JSP指令<%include>
。import标签的属性:
- url:指定要包含的路径
- context:访问同一个web容器的其他资源,以"/"开头
- var:保存导入的文件的内容,以String类型存储
- scope:保存的范围,默认是page
- charEncoding:字符编码
- varReader:保存导入文件的内容,以Reader类型存储
c:param
在进行URL相关操作时,<c:param>
标签可以嵌套在<c:import>
、<c:url>
或c:redirect>
标签内,为这些标签所使用的URL地址附加参数。
c:url
属性名 | 是否支持EL | 属性类型 | 属性描述 |
---|---|---|---|
value | true | String | 指定要构造的URL |
var | false | String | 指定将构造出的URL结果保存到web域中的属性名 |
scope | false | String | 指定将构造出的URL保存到哪个web域中 |
c:redirect
属性名 | 是否支持EL | 属性类型 | 属性描述 |
---|---|---|---|
url | true | String | 指定要转发或重定向到的目标资源的URL地址 |
context | true | String | 当要使用相对路径重定向到同一个服务器下的其他web应用程序中的资源时,context属性指定其他web应用程序的名称 |