JspServlet

JSP简介
JSP页面的构成元素
JSP的生命周期
JSP的内置对象
JSP表达式语言(EL)
JSP标准标签库(JSTL)html


JSP简介
1.使用Servlet产生动态页面,须要在代码中打印出不少HTML的标签,在Servlet将静态显示的内容和动态内容代码混合在一块儿。
2.使用Servlet开发动态网页,程序员与美工人员没法一块儿工做,由于美工不了解Java语言,没法修改Servlet代码。
为了解决这些问题,SUN公司推出了JSP技术。java

JSP的基本原理:
JSP的本质依然是Servlet(一个特殊的Java类),当用户向Servlet发送请求时,Servlet利用输出流动态生成HTML页面,包括每个静态的HTML标签和全部在HTML页面中出现的内容。也就是说,JSP实际上是Servlet的一种简化,使用JSP时,其实仍是使用Servlet,由于在Web应用中,每一个JSP页面都会由Servlet容器生成对应的Servlet。JSP必须在Web应用中才有效。git

JSP仅做为表现层技术,其做用有2点:
1.收集用户的请求参数。
2.将应用程序的处理结果呈现给用户。程序员

JSP是一种创建在Servlet规范提供的功能之上的动态网页技术,在网页文件中经过JSP页面元素嵌入Java代码。web


JSP页面的构成元素
1.静态内容:HTML静态文本。sql

2.指令:
指令主要用于转换阶段提供整个JSP页面的相关信息,指令不会产生任何的输出到当前的输出流中。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
page指令用于设置JSP页面的属性。
<%@ include file="/WEB-INF/jsp/res.jsp"%>
include指令用于在JSP页面中静态包含一个文件,该文件能够是JSP页面,HTML页面,文本文件。使用了include指令的JSP页面在转换时,JSP容器会在其中插入所包含文件的文本或代码。
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
taglib指令可让JSP页面使用标签。数据库

3.声明:<%!%> 类、方法和全局变量。
4.脚本段:<% int a = 30; out.println(a);%> Java代码。
4.表达式:<%=Math.PI%> 表达式用于求值,而后其值转化为字符串,插入到当前流中。express

6.动做:嵌入到JSP页面中的一个标签。在页面被转换为Servlet期间,当JSP容器遇到这个标签,就用预先定义的对应该标签的Java代码来替代它。
<jsp:useBean>寻找或者实例化一个JavaBean。
<jsp:setProperty>设置JavaBean的属性。
<jsp:getProperty>输出某个JavaBean的属性。
<jsp:useBean id="BeanId" class="example5.simpleBean" scope="application"/>
<jsp:setProperty name="BeanId" property="name" value="Andrew"/>
<jsp:setProperty name="BeanId" property="age" value="25"/>
<jsp:getProperty name="BeanId" property="name"/>
<jsp:getProperty name="BeanId" property="age"/>
<jsp:include> <jsp:include page="sample.jsp" flush="true"><jsp:param name="name" value="csp"/></jsp:include>
用于在当前页面中包含静态和动态的资源,能够传递参数。
<jsp:forward> <jsp:forward page="requestedpage.jsp"/>
和RequestDispatcher接口的forward()方法的做用同样。容许在运行时将当前的请求转发给一个静态的资源,JSP页面或者Servlet,请求被转向到的资源必须位于同JSP发送请求相同的上下文环境中。
<jsp:plugin>根据浏览器类型为Java插件生成OBJECT或EMBED标记。apache

7.注释:<!-- --> <%-- --%>小程序

include指令与include动做
include指令能够在JSP页面转换成Servlet以前,将JSP代码插入其中。它的主要优势是功能强大,所包含的代码能够含有整体上影响主页面的JSP构造,好比属性、方法的定义和文档类型的设定。它的缺点是难于维护只要被包含的页面发生更改,就得更改主页面,这是由于主页面不会自动地查看被包含的页面是否发生更改。
include动做是引入执行页面或Servlet所生成的应答文本。在主页面被请求时,将次级页面的输出包含进来。被包含的页面发生改变时,无须对主页面作出修改。
ps:仅当include动做不能知足要求时,咱们才应该使用include指令。

forward和redirect的区别
forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,而后把这些内容再发给浏览器,浏览器根本不知道服务器发送的内容是从哪儿来的,因此它的地址栏中仍是原来的地址。
redirect就是服务端根据逻辑,发送一个状态码,告诉浏览器从新去请求那个地址,通常来讲浏览器会用刚才请求的全部参数从新请求,因此session,request参数均可以获取。

scope做用域
1.page
表示页面做用域,即所建立的对象在当前页面有效,请求转交给其余页面处理时,对象失效。
默认值。在处理当前请求的过程当中,bean对象都应该存放在PageContext对象中。让同一Servlet中的其余方法能够访问该bean。
2.request
表示请求做用域,即在当前页面建立的对象,在该请求后续访问的页面均可以访问。
处理当前请求的过程当中,bean对象应存储在ServletRequest对象中,能够经过getAttribute访问到它。
3.session
表示会话做用域,即在某个客户的会话期间,建立的对象,在其会话存续期间均可以访问。
bean会被存储在与当前请求关联的HttpSession中,和普通的会话对象同样,在常规Servlet中可使用getAttribute和setAttribute访问到它们。
4.application
表示应用程序做用域,即建立的对象在web服务器没有被关闭以前,该对象均可以访问。
bean将存储在ServletContext中(经过application变量或调用getServletContext()来访问)。ServletContext由同一Web应用中的全部Servlet共享(或服务器上的全部Servlet——在没有另外定义Web应用的状况下)。


JSP的生命周期
1.翻译和编译(转换阶段)
jspinit - JSP容器建立一个对象的时候,执行jspinit方法,该方法在JSP的生命周期中只执行一次。
2.执行阶段
jspService - JSP容器处理用户请求的时候,调用这个方法。一个请求,一个线程。
3.销毁阶段
jspDestory - 因为Servlet常驻内存,因此JSP响应速度快。当系统资源不足的时候,须要将Servlet移出内存,此时执行jspDestory方法。

JSP执行流程:
第一个用户请求JSP文件的时候,把JSP文件转换成Java文件(Servlet类文件),而后再编译成class文件,常驻内存。而后再有用户请求的时候,直接再开一个线程,而不是一个进程,无须从新编译,直接执行第一次已经编译好的class文件,速度快。若是JSP文件发生变化,那么就须要从新编译一次。


JSP的内置对象
1.JSP内置对象是Web容器加载的一组类。
2.它不像通常的Java对象那样用"new"去获取实例,而是能够直接在JSP页面使用的对象。
3.内置对象的名称是JSP的保留字。
4.JSP使用Java定义的内置对象来访问网页的动态内容。

编写test.jsp,编译以后查看test_jsp.java源代码:
public void _jspService(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
JspFactory _jspxFactory = null;
javax.servlet.jsp.PageContext pageContext = null;
HttpSession session = null;
ServletContext application = null;
ServletConfig config = null;
JspWriter out = null;
Object page = this;
...
}
这些内置对象都在_jspService中定义,因此只能在脚本或表达式中使用内置对象。

1.输入/输出对象
request、response、out
2.做用域通讯对象
pageContext、request、session、application
3.Servlet对象
page、config
4.异常对象
exception

request
表示客户端对网页的请求,实现javax.servlet.http.HttpServletRequest接口。使用HTTP协议处理客户端的请求。
经常使用方法
String getParameter(String name)
String[] getParameterValues(String name)

response
处理JSP生成的响应,将响应发送给客户端,实现javax.servlet.http.HttpServletResponse接口。
经常使用方法
void setContentType(String name)设置响应内容的类型和字符编码。
void sendRedirect(String name)重定向。

out
表示输出流,javax.servlet.jsp.JspWriter类的实例,以字符流的形式输出数据,经过page指令的buffer属性来制定缓冲区的大小,默认是8kb。
经常使用方法
write()、print()、println()

session
用户会话对象,Web服务器为单个用户发送的多个请求建立会话,实现javax.servlet.http.HttpSession接口。
经常使用方法
void setAttribute(String name,Object value)
void getAttribute(String name)

application
JSP页面所属的应用程序,实现javax.servlet.ServletContext接口。
经常使用方法
void setAttribute(String name,Object value)
void getAttribute(String name)

pageContext
页面上下文对象,继承javax.servlet.jsp.PageContext类。它的做用范围是在同一页面。
经常使用方法
void setAttribute(String name,Object value)
void getAttribute(String name)

page
页面对象,继承java.lang.Object类。JSP中不多使用该对象。

config
配置信息对象,实现javax.servlet.ServletConfig接口。在Servlet初始化时向其传递配置信息。

exception
异常对象,用于处理JSP页面中的异常。


JSP表达式语言
EL(Expression Language),能够简化对变量的访问。由两个组开发(JSP标准标签库专家组、JSP2.0专家组)。

语法
${EL Expression}

EL表达式的操做内容能够是常量、变量、JSP内置对像。还提供了对操做内容的运算(算述运算、关系运算、逻辑运算)。EL表达式的操做结果会自动输出到输出流对象中。

EL支持的文字常量
字符串 - 由0个或多个字符组成。
整形 - 十进制、十六进制和八进制类型的值。
浮点型 - 由两部分组成,如用'E'、'e'和f后缀类型表示的指数。
布尔型 - 指定或检查运算结果,返回结果为true或false。
Null - 表示无值,Null值可用于代码中检查方法是否返回值。

使用情形
1.静态文本。
2.标准标签和自定义标签。
3.EL不能在脚本元素中使用。

10/5=${10/5} -- 10/5=2.0
10%5=${10%5} -- 10%5=0
${true && false} -- false
${true || false} -- true
5>6=${5>6} -- 5>6=false
5==6=${5==6} -- 5==6=false

EL使用"[]"和"."操做符来访问对象属性。
${user.name}同${user["name"]}

禁用EL
<%@ page isELIgnored ="true"%>

EL表达式搜索范围
EL在对变量进行操做的时候,它默认经过pageContext.findAttribute("")的方式来查找变量,查找的范围从page、request、session到application。假如途中找到变量,就直接回传,再也不继续找下去。若是这几个范围都没有找到则返回null。也能够经过如下的内容来指定范围pageScope、requestScope、sessionScope和applicationScope。${pageScope.user.name}。

EL变量类型自动转换
${param.count + 20}当param.count为10时,则结果为30。

运算符
1.算术运算符
(+、-、*、/或div、%或mod)
${param.count + param.count}

2.关系运算符
(==或eq、!=或ne、<或lt、>或gt、<=或le、>=或ge)
${param.count eq param.count}

3.逻辑运算符
(&&或and、||或or、!或not)
${param.count == 1 || param.count == 2}

4.其它运算符
empty运算符主要用来判断值是否为null或空的。
${empty param.count}
条件运算符。当A为true时,执行B,A为false时,则执行C。
${A ? B : C}

EL中的隐含对像共有11个,能够分红三类
1.与范围有关的隐含对象(pageScope、requestScope、sessionScope、applicationScope)。
它们基本上就和JSP的pageContext、request、session和application同样,不过必须注意的是,这四个隐含对象只能用来取得范围属性值,即JSP中的getAttribute(String name),却不能取得其余相关信息,没有其它相关的方法。
2.与输入有关的隐含对象(param、paramValues)。
用来取得用户请求的参数,如:
${param.name}
${paramValues.name}
以上的做用为:
request.getParameter(String name)
request.getParameterValues(String name)

3.其余隐含对象。
cookie是一个小小的文本文件,它是以key、value的方式将session tracking的内容记录在这个文本文件内。EL没有实现cookie地动做,只是能够简单的把cookie中保存的值取出,其它的工做交由后台的程序员来完成。
${cookie.userCountry}
取出cookie中保存的userCountry的信息。

header和headerValues
取出请求的关信息。用户浏览器的版本、用户计算机所设定的区域等其余相关数据。在鲜少机会下,有可能同一标头名称拥有不一样的值,此时必须改成使用headerValues来取得这些值。
${header["User-Agent"]}
取得浏览器的版本信息。

initParam
取得web.xml中的配置参数,如在web.xml中有以下配置
<context-param>
<param-name>userid</param-name>
<param-value>mike</param-value>
</context-param>
${initParam.userid}同String userid = (String)application.getInitParameter("userid");

pageContext
提供对页面属性的访问
${pageContext.request.queryString}取得请求的参数字符串
${pageContext.request.requestURL}取得请求的URL,但不包括请求参数字符串。
${pageContext.request.contextPath}服务的web application的名称。
${pageContext.request.method}取得HTTP的方法(get、post)。
${pageContext.request.protocol}取得使用的协议(HTTP/1.一、HTTP/1.0)。
${pageContext.request.remoteUser}取得用户名称。
${pageContext.request.remoteAddr}取得用户IP。
${pageContext.session.new}判断session是否为新的。所谓新的session,表示刚由server产生而client还没有使用。
${pageContext.session.id}取得session的ID。
${pageContext.servletContext.serverInfo}取得主机端的服务信息。


JSP标准标签库
JSTL(JSP Standard Tag Library),由标签库和EL表达式两部分组成。功能包括迭代和条件判断、数据管理格式化、XML操做以及数据库访问。由apache的jakarta小组维护。JSTL1.0发布于2002年6月,目前最新版本为1.2。

JSTL包含5大标签库
1.核心标签库:包含Web应用的常见工做,好比:循环、表达式赋值、基本输入输出等。
2.国际化标签库:用来格式化显示数据,好比:日期、数字格式化。
3.数据库标签库:访问数据库。
4.XML标签库:访问XML。
5.函数标签库:读取已定义的函数。

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/xml" prefix="x" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>

1.核心标签库
对JSP页面通常处理的封装,包含14标签,分为4类
a.多用途核心标签
<c:out>、<c:set>、<c:remove>、<c:catch>

用于显示的<c:out>标签
<c:out>标签是一个最经常使用的标签,用于在JSP中显示数据。若是vlaue为null时,会显示default的值。
<c:out value="${param.count}" [escapeXml="{true|false}"] [default="0"] />

用于赋值的<c:set>标签
<c:set>标签主要用来将变量存储到JSP范围中或JavaBean中的属性中。
<c:set var="number" scope="request" value="csp" />
<c:set target="user" property="name" value="csp" />

用于删除的<c:remove>标签
<c:remove>标签用于删除存在于scope中的变量。
<c:remove var="varName" [scope="{page|request|session|application}]" />

用于异常捕获的<c:catch>标签
<c:catch var="err">
${param.car[2] == 1}
</c:catch>
${err}

b.条件控制标签
<c:if>、<c:choose>、<c:when>、<c:otherwise>
用于判断的<c:if>标签
<c:if test="${param.count==1}" [var="varName"] [scope="{page|request|session|application}"]>
...
</c:if>

用于复杂判断的<c:choose>、<c:when>、<c:otherwise>标签
<c:choose>标签没有属性,能够被认为是父标签,<c:when>、<c:otherwise>将做为其子标签来使用。<c:when>标签等价于if语句,它包含一个test属性,该属性表示须要判断的条件。<c:otherwise>标签没有属性,它等价于else语句。
<c:choose>
<c:when test="${param.count == 0}">
...
</c:when>
<c:when test="${param.count == 1}">
...
</c:when>
<c:otherwise>
...
</c:otherwise>
</c:choose>

c.循环控制标签
<c:forEach>、<c:forTokens>
用于循环的<c:forEach>标签
<c:forEach [var="v"] [items="collection"] [varStatus="i"] [begin="begin"] [end="end"] [step="step"]>
...
</c:forEach>

用于分隔字符的<c:forTokens>标签
<c:forTokens items="stringOfTokens" delims="delimiters" [var="v"] [varStatus="i"] [begin="begin"] [end="end"] [step="step"]>
</c:forTokens>
<c:forTokens items="aa,bb,cc,dd" delims="," var="v">
${v}
</c:forTokens>

d.URL相关标签
<c:import>、<c:url>、<c:redirect>、<c:param>
用于包含页面的<c:import>
<c:import>标签能够把其余静态或动态文件包含到本页面来。和<jsp:include>最大的区别是<jsp:include>只能包含和本身同一个应用下的文件,<c:import>便可包含和本身同一个应用下的文件,也能够包含和本身不一样的应用下的文件。
<c:import url="url" [context="context"] [var="v"] [scope=""] [charEncoding="charEncoding"]>
...
</c:import>

用于获得URL地址的<c:url>标签
<c:url value="url" [context="context"] [var="varName"] [scope=""] >
  <c:param name="param" value="value"/>
</c:url>

用于页面重定向的<c:redirect>标签
<c:redirect url="url" [context="context"]>
<c:param>
</c:redirect>

用于包含传递参数的<c:param>标签
<c:param name="param" [value="value"]/>

2.国际化标签库
fmt库中的定制标记主要分红四组。第一组容许设置本地化上下文,其它标记将在其中进行操做。换句话说,这组标记容许页面做者显式地设置其它fmt标记在格式化数据时将要使用的语言环境和时区。第二组和第三组标记分别支持对日期和数字进行格式化和解析。最后一组标记侧重于对文本消息进行本地化。
用户语言环境
<fmt:setLocale value="en_US" [scope="session"] [variant="Microsoft Windows"]/>
JSP容器处理完该JSP代码段以后,将忽略用户浏览器设置中所指定的语言首选项。

用于时区
<fmt:setTimeZone value="Australia/Brisbane" [var="name"] [scope="scope"]/>

用于日期标记
<fmt:formatDate>用来格式化和显示日期和时间(数据输出)。
<fmt:parseDate>用来解析日期和时间值(数据输入)。
<fmt:formatDate value="expression" [timeZone="expression"] [type="field]" [dateStyle="style"] [timeStyle="style]" [var="name"] [pattern="expression"] [scope="scope"]/>
<fmt:formatDate value="${createTime}" pattern="yyyy/MM/dd HH:mm:ss"/>

用于数字标记
<fmt:formatNumber>标记用来以特定于语言环境的方式显示数字数据,包括货币和百分数。
<fmt:parseNumber>操做解析了一个数值,该数值是经过value属性或该操做的标记体内容以特定于语言环境的方式提供的,将结果做为java.lang.Number类的实例返回。
<fmt:formatNumber value="expression" [type="type"] [pattern="expression"] [currencyCode="expression"] [currencySymbol="expression"] [maxIntegerDigits="expression"] [minIntegerDigits="expression"] [maxFractionDigits="expression"] [minFractionDigits="expression"] [groupingUsed="expression"] [var="name"] [scope="scope"]/>
<fmt:formatNumber value="0.02" type="currency"/>

用于消息标记
<fmt:message key="expression" [bundle="expression"] [var="name"] [scope="scope"]>
  <fmt:param value="expression"/>
</fmt:message>

3.函数标签
functions标签被用于EL表达式语句中。为两大类,共16个函数。长度函数:fn:length。字符串处理函数:fn:contains、fn:containsIgnoreCase、fn:endsWith、fn:escapeXml、fn:indexOf、fn:join、fn:replace、fn:split、fn:startsWith、fn:substring、fn:substringAfter、fn:substringBefore、fn:toLowerCase、fn:toUpperCase、fn:trim。

长度函数
${fn:length(arrayList)}

判断函数 fn:contains,判断源字符串是否包含子字符串。 ${fn:contains("ABC","A")}
判断函数 fn:containsIgnoreCase,忽略大小写判断源字符串是否包含子字符串。
词头判断函数 fn:startsWith。
词尾判断函数 fn:endsWith。
字符实体转换函数 fn:escapeXml,将全部特殊字符转化为字符实体码。只包含一个string参数,返回一个string类型的值。
字符匹配函数 fn:indexOf,取得子字符串与源字符串匹配的开始位置。
分隔符函数,返回string类型的值。 ${fn:join({"a","b","c"},",")}
替换函数 ${fn:replace("ABC","A","B")}
分隔符转换数组函数,返回string[]类型的值。 ${fn:split("A,B,C",",")}
字符串截取函数 ${fn:substring("ABC","1","2")} B
起始到定位截取字符串函数 ${fn:substringBefore("ABCD","BC")} A
小写转换函数 fn:toLowerCase
大写转换函数 fn:toUpperCase
空格删除函数 fn:trim

 

Servlet

前面已经介绍JSP本质就是Servlet,直接使用Servlet的坏处是:
1.开发效率低,全部的HTML标签都须要使用页面输出流完成。
2.不利于团队开发,美工人员没法参与Servlet开发。
3.可维护性差,修改时须要编辑Java代码并从新编译。

自MVC规范出来后,Servlet的责任开始明确下来,仅仅做为控制器使用,相似于调度员,全部用户的请求都发送到Servlet。再也不须要生成页面标签,也再也不做为视图层角色使用。

Servlet被称为服务器端小程序,运行在服务器端,用于处理及响应客户端的请求。

Servlet是个特殊的Java类,这个Java类必须继承HttpServlet。Servlet提供不一样的方法来响应客户端请求。
doGet:用于响应客户端的GET请求。
doPost:用于响应客户端的POST请求。
大部分时候,Servlet对于全部请求的响应都是彻底同样的。所以能够采用重写service方法来代替上面的全部方法。

init(ServletConfig config):建立Servlet实例时,初始化Servlet资源。
destory():销毁Servlet。

JSP与Servlet的区别:
1.Servlet中没有内置对象,须要由程序显示建立。
2.对于静态HTML标签,Servlet都必须使用页面输出流逐行输出。

从Servlet3.0开始,配置Servlet有两种方式:
1.在web.xml文件中配置。
<servlet>
  <servlet-name>login</servlet-name>
  <servlet-class>com.csp.LoginAction</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>login</servlet-name>
  <url-pattern>/login</url-pattern>
</servlet-mapping>

2.在Servlet类中使用注解配置。
@WebServlet(name="login",urlPatterns={"/login"})

Servlet生命周期:
1.建立Servlet实例。
2.init方法初始化Servlet对象。
3.service方法处理客户的请求。
4.destroy方法销毁Servlet。

当Servlet在容器中运行时,其实例的建立及销毁都不是由程序员决定的,而是由Web容器进行控制。
建立Servlet实例有两个时机:
1.客户端第一次请求某个Servlet时,系统建立该Servlet实例,大部分Servlet都是这种Servlet。
2.Web应用启动时当即建立Servlet实例,即load-on-startup,这种Servlet没有service方法,不能处理用户请求。
<servlet>
  <servlet-name>myThread</servlet-name>
  <servlet-class>com.csp.MyThread</servlet-class>
  <load-on-startup>1</load-on-startup>
</servlet>

Filter介绍:
Filter能够认为是Servlet的增强版,它主要用于对用户请求进行预处理,也能够对HttpServletResponse进行后处理。建立Filter须要两个步骤:
1.建立Filter处理类,实现Javax.servlet.Filter接口。
2.web.xml文件中配置Filter。

<filter>  <filter-name>login</filter-name>  <filter-class>com.csp.LoginFilter</filter-class></filter><filter-mapping>  <filter-name>login</filter-name>  <url-pattern>/*</url-pattern></filter-mapping>