JSP的事情模式是要求/相应模式,客户端首先发出HTTP要求,JSP程序收到要求后进行处理并返回处理结果。
在一个JSP文件第1次被要求时,JSP引擎(容器)把该JSP文件转换成为一个Servlet,而这个引擎本身也是一个Servlet。

理解了JSP的运行事理后,完备可以利用个中的一些步骤来做一些事情,如:可以在jspInit()中进行一些初始化事情(建立数据库的连接、建立网络连接、从配置文件中获取一些参数等),可以在jspDestroy()中开释相应的资源等

2 JSP脚本元素

jsp打印局部进修Java第三天 React

JSP脚本元素是指嵌套在<%和%>之中的一条或多条Java程序代码
通过JSP脚本元素可以将Java代码嵌入HTML页面中,所有可实行的Java代码,都可以通过JSP脚本来实行

1.JSP ScriptletsJSP Scriptlets 是一段代码段。
当须要利用Java实现一些繁芜操作或掌握时,可以利用它。
JSP Scriptlets的语法格式如下所示。

<% java 代码(变量、方法、表达式等)%>

在JSP Scriptlets中声明的变量是JSP页面的局部变量,调用JSP Scriptlets时,会为局部变量分配内存空间,调用结束后,开释局部变量霸占的内存空间。

2.JSP声明语句

JSP 的声明语句用于声明变量和方法,它以“<%!”开始,以“%>”结束,其语法格式如下所示。

<%!定义的变量或方法等%>

须要把稳的是,<%!
和%>里面定义的属性是成员属性,相称于类的属性,方法相称于全局的方法,也相称于类里面的方法,但是它是不可以进行输出的,由于它只是进行方法的定义和属性的定义。
<%和%>可以进行属性的定义,也可以输出内容,但是它不可以进行方法的定义。
由于这对标签里面的内容是在此JSP被编译为Servlet的时候,放在_jspService()方法里面的,这个方法便是做事器向客户端输出内容的地方,它本身便是一个方法。
以是,如果在它里面定义方法的话,那么就相称于是在类的方法里面嵌套定义了方法,这在Java里面是不许可的。
但是,可以在里面定义自己的私有变量,由于方法里面也可以定义变量,也可以调用方法,唯独不可以再定义方法了。

总之,<%!
和%>是用来定义成员变量属性和方法的,<%和%>紧张是用来输出内容的,因此,如果涉及到了成员变量的操作,那么就该当利用<%!
和%>,而如果涉及到了输出内容,就利用<%和%>。

3 .JSP表达式

JSP表达式(expression)用于将程序数据输出到客户端,它将要输出的变量或者表达式直接封装在以“<%=”开头和以“%>”结尾的标记中,其基本的语法格式如下所示。
<%= expression %>在上述语法格式中,JSP表达式中的变量或表达式的打算结果将被转换成一个字符串,然后插入到JSP页面输出结果的相应位置处。
例如,对example01.jsp文件进行修正,将<body>内的脚本元素修正为表达式,详细如下。

<%=a+b %><br />

<%=print() %>

4 JSP注释

同其他各种编程措辞一样,JSP也有自己的注释办法,其基本语法格式如下。

<%-- 注释信息 --%>

5 page指令

在 JSP 页面中,常常须要对页面的某些特性进行描述,例如,页面的编码办法、JSP 页面采取的措辞等,这时,可以通过page指令来实现。
page指令的详细语法格式如下所示。
<%@ page 属性名1= &#34;属性值1" 属性名2= "属性值2" ...%>

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>

<%@ page import="java.awt." %>

<%@ page import="java.util.","java.awt." %>

除了import属性外,其他的属性都只能涌现一次,否则会编译失落败。
须要把稳的是,page指令的属性名称都是区分大小写的。

6 include指令

在实际开拓时,有时须要在JSP页面静态包含一个文件,例如HTML文件、文本文件等,这时,可以通过include指令来实现。
include指令的详细语法格式如下所示。

<%@ include file="被包含的文件地址"%>

include指令只有一个file属性,该属性用来指定插入到JSP页面孔标位置的文件资源。
须要把稳的是,插入文件的路径一样平常不以“/”开头,而是利用相对路径。

关于include指令的详细运用,有很多问题须要把稳,接下来,将这些问题进行列举,详细如下。

(1)被引入的文件必须遵照 JSP 语法,个中的内容可以包含静态 HTML、JSP 脚本元素和JSP指令等普通JSP页面所具有的统统内容。

(2)除了指令元素之外,被引入的文件中的其他元素都被转换成相应的Java源代码,然后插入当前JSP页面所翻译成的Servlet源文件中,插入位置与include指令在当前JSP页面中的位置保持同等。

(3)file属性的设置值必须利用相对路径,如果以“/”开头,表示相对付当前Web运用程序的根目录(把稳不是站点根目录),否则,表示相对付当前文件。
须要把稳的是,这里的 file属性指定的相对路径是相对付文件(file),而不是相对付页面(page)

7 JSP隐式工具

在JSP页面中,有一些工具须要频繁利用,如果每次都重新创建这些工具则会非常麻烦。
为了简化Web运用程序的开拓,JSP2.0规范中供应了9个隐式(内置)工具,它们是JSP默认创建的,可以直接在 JSP 页面中利用。

out工具

在JSP页面中,常常须要向客户端发送文本内容,这时,可以利用out工具来实现。
out工具是javax.servlet.jsp.JspWriter类的实例工具,它的浸染与ServletResponse.getWriter()方法返回的PrintWriter工具非常相似,都是用来向客户端发送文本形式的实体内容。
不同的是,out工具的类型为JspWriter,它相称于一种带缓存功能的PrintWriter。

<%out.println("first line<br />");

response.getWriter().println("second line<br />"); %>

只管out.println();语句位于response.getWriter().println();语句之前,但它的输出内容却在后面。
由此可以解释,out 工具通过 print 语句写入数据后,直到全体JSP页面结束,out工具中输入缓冲区的数据(即first line)才真正写入到Serlvet引擎供应的缓冲区中。
而response.getWriter().println();语句则是直接把内容(即second line)写入Servlet引擎供应的缓冲区中,Servlet引擎按照缓冲区中的数据存放顺序输出内容。

有时候,开拓职员会希望out工具可以直接将数据写入Servlet引擎供应的缓冲区中,这时,可以通过page指令中操作缓冲区的buffer属性来实现。

<%@ page language="java" contentType="text/html; charset=UTF-8"                         buffer="0kb"%>

8 pageContext工具

在JSP页面中,利用pageContext工具可以获取JSP的其他8个隐式工具。
pageContext工具是javax.servlet.jsp.PageContext类的实例工具,它代表当前JSP页面的运行环境,并供应了一系列用于获取其他隐式工具的方法。

JspWriter getOut() 用于获取out隐式工具

Object getPage() 用于获取page隐式工具

ServletRequest getRequest() 用于获取request隐式工具

ServletResponse getResponse() 用于获取response隐式工具

HttpSession getSession() 用于获取session隐式工具

Exception getException() 用于获取exception隐式工具

ServletConfig getServletConfig() 用于获取config隐式工具

ServletContext getServletContext() 用于获取application隐式工具

9 pageContext工具

不仅供应了获取隐式工具的方法,还供应了存储数据的功能。

pageContext工具存储数据是通过操作属性来实现的,

表6-4列举了pageContext操作属性的一系列方法,

详细如下。
表6-4

pageContext操作属性的干系方法

void setAttribute(String name,Object value,int scope)

Object getAttribute(String name,int scope)

void removeAttribute(String name,int scope)

void removeAttribute(String name)

Object findAttribute(String name)用于设置pageContext工具的属性用于获取pageContext工具的属性删除指定例模内名称为name的属性删除所有范围内名称为name的属性

个中,参数name指定的是属性名称,参数scope指定的是属性的浸染范围。
pageContext工具的浸染范围有4个值,

详细如下。

• pageContext.PAGE_SCOPE:表示页面范围

• pageContext.REQUEST_SCOPE:表示要求范围

• pageContext.SESSION_SCOPE:表示会话范围

• pageContext.APPLICATION_SCOPE:表示Web运用程序范围

须要把稳的是,当利用 findAttribute()方法查找名称为 name 的属性时,会按照page、request、session和application的顺序依次进行查找,如果找到,则返回属性的名称,否则返回null。
接下来,通过一个案例来演示pageContext工具的利用。

<%

//pageContext.setAttribute("str", "Java",PageContext.PAGE_SCOPE);

//pageContext.setAttribute("str", "Java Web",PageContext.REQUEST_SCOPE);

HttpServletRequest req = (HttpServletRequest) pageContext.getRequest();

req.setAttribute("str", "Java Web");

pageContext.setAttribute("str", "Java",pageContext.PAGE_SCOPE);

String str2 = (String)pageContext.getAttribute("str",pageContext.PAGE_SCOPE);

String str1 = (String)pageContext.getAttribute("str",pageContext.REQUEST_SCOPE);

%>

<%= "request范围:" + str1 %><br />

<%= "page范围:" + str2 %><br />

10 exception工具

在 JSP 页面中,常常须要处理一些非常信息,这时,可以通过 exception 工具来实现。
exception工具是java.lang.Exception类的实例工具,它用于封装JSP中抛出的非常信息。
须要把稳的是,exception 工具只有在缺点处理页面才可以利用,即 page 指令中指定了属性<%@page isErrorPage="true"%>的页面。

<%@ page language="java" contentType="text/html; charset=utf-8"

pageEncoding="utf-8" errorPage = "error.jsp" %>

--error.jsp

<%@ page contentType = "text/html; charset = utf-8"

language = "java" isErrorPage = "true" pageEncoding="utf-8"%>

11 jsp处理非常

<%

try{

int a = 6;

int c = a/0 ;

}

catch(Exception exception)

{

out.println(exception.getClass());

out.println(exception.getMessage());

}

%>

12<jsp:include>标签

<jsp:include page="included.jsp" flush="true" />

• <jsp:include>标签中要引入的资源和当前JSP页面是两个彼此独立的实行实体,即被动态引入的资源必须能够被Web容器独立实行。
而include指令只能引入遵照JSP格式的文件,被引入文件与当前JSP文件须要共同合并才能翻译成一个Servlet源文件。

• <jsp:include>标签中引入的资源是在运行时才包含的,而且只包含运行结果。
而include指令引入的资源是在编译期间包含的,包含的是源代码。

• <jsp:include>标签运行事理与RequestDispatcher.include()方法类似,即被包含的页面不能改变相应状态码或者设置相应头,而include指令没有这方面的限定。

13 <jsp:forward>动作元素

<jsp:forward>动作元素将当前要求转发到其他Web资源(HTML页面、JSP页面和Servlet等),在实行要求转发之后确当前页面将不再实行,而是实行该元素指定的目标页面。
其详细语法格式如下所示。

<jsp:forward page="relativeURL" />

${pageContext.request.contextPath}会获取项目的名称chapter06并以“/”开头

13 什么是JavaBean

JavaBean是Java开拓措辞中一个可以重复利用的软件组件,它实质上便是一个Java类。
为了规范JavaBean的开拓,Sun公司发布了JavaBean的规范,它哀求一个标准的JavaBean组件须要遵照一定的编码规范,详细如下。

(1)它必须具有一个公共的、无参的布局方法,这个方法可以是编译器自动产生的默认布局方法。

(2)它供应公共的setter方法和getter方法,让外部程序设置和获取JavaBean的属性。

如果一个属性只有getter方法,则该属性为只读属性。
如果一个属性只有setter方法,则该属性为只写属性。
如果一个属性既有getter方法,又有setter方法,则该属性为读写属性。
常日来说,在开拓JavaBean时,其属性都定义为读写属性。
须要把稳的是,对付 JavaBean 属性的命名办法有一个例外情形。
如果属性的类型为boolean,它的命名办法该当利用 is/set,而不是 get/set。
例如,有一个boolean 类型的属性married,该属性所对应的方法声明如下所示。

14 EL表达式

由于EL可以简化JSP页面的书写,因此,在JSP的学习中,节制EL是相称主要的。
要利用EL表达式,首先要学习它的语法。
EL表达式的语法非常大略,都因此“${”符号开始,以“}”符号结束的,详细魄式如下。

用户名:<%=request.getAttribute("username")%><br />   

密 码:<%=request.getAttribute("password")%><br />   <hr />   

利用EL表达式:<br />  

用户名:${username}<br />  

密 码:${password}<br />

15 EL隐式工具

pageContext工具:

要求URI为:${pageContext.request.requestURI}

<br />Content-Type相应头:${pageContext.response.contentType}

<br />做事器信息为:${pageContext.servletContext.serverInfo}

<br />Servlet注册名为:${pageContext.servletConfig.servletName}

16 Web域干系工具

利用pageScope、requestScope、sessionScope和applicationScope这4个隐式工具成功地获取到了相应JSP域工具中的属性值。
须要把稳的是,利用EL表达式获取某个域工具中的属性时,也可以不该用这些隐式工具来指定查找域,而是直接引用域中的属性名称即可,例如表达式${userName}便是在page、request、session、application这4个浸染域内按顺序依次查找userName属性的。

<%

pageContext.setAttribute("userName", "itcast");

%>

<%

request.setAttribute("bookName", "Java Web");

%>

<%

session.setAttribute("userName", "itheima");

%>

<%

application.setAttribute("bookName", "Java 根本");

%>

表达式\${pageScope.userName}的值为:${pageScope.userName}

<br /> 表达式\${requestScope.bookName}的值为:${requestScope.bookName}

<br /> 表达式\${sessionScope.userName}的值为:${sessionScope.userName}

<br />

表达式\${applicationScope.bookName}的值为:${applicationScope.bookName}

<br /> 表达式\${userName}的值为:${userName}

17 param和paramValues工具

param 工具用于获取要求参数的某个值,它是 Map 类型,与request.getParameter()方法相同,在利用EL获取参数时,如果参数不存在,返回的是空字符串,而不是null。
param工具的语法格式比较大略,详细示例如下。

${param.num}

如果一个要求参数有多个值,可以利用paramValues工具来获取要求参数的所有值,该工具用于返回要求参数所有值组成的数组。
如果要获取某个要求参数的第1个值,可以利用如下代码。

${paramValues.nums[0]}

举例:

<form action="${pageContext.request.contextPath}/param.jsp">

num1:<input type="text" name="num1"><br />

num2:<input

type="text" name="num"><br />

num3:<input type="text"

name="num"><br /> <br />

<input type="submit" value="提交" />

<input type="submit" value="重置" />

<hr />

num1:${param.num1}<br />

num2:${paramValues.num[0]}<br />

num3:${paramValues.num[1]}<br />

</form>

18 .Cookie工具

在JSP开拓中,常常须要获取客户真个Cookie信息,为此,在EL表达式中,供应了Cookie隐式工具,该工具是一个代表所有Cookie信息的Map凑集,Map凑集中元素的键为各个Cookie的名称,值则为对应的Cookie工具,详细示例如下。

获取cookie工具的信息:${cookie.userName}

获取cookie工具的名称:${cookie.userName.name}

获取cookie工具的值:${cookie.userName.value}

举例:

Cookie工具的信息:

<br />${cookie.userName }

<br />Cookie工具的名称和值:

<br />${cookie.userName.name }=${cookie.userName.value }

<%

response.addCookie(new Cookie("userName", "itcast"));

%>

19 什么是JSTL

从JSP 1.1规范开始,JSP就支持利用自定义标签,利用自定义标签大大降落了JSP页面的繁芜度,同时增强了代码的重用性。
为此,许多Web运用厂商都定制了自身运用的标签库,然而同一功能的标签由不同的Web运用厂商制订可能是不同的,这就导致市情上涌现了很多功能相同的标签,令网页制作者无从选择。
为理解决这个问题,Sun 公司制订了一套标准标签库(JavaServer Pages Standard Tag Library),简称JSTL。

利用JSTL标签库报错,可将 jstl.jar 和 standard.jar 这两个文件复制到 chapter07项目的 lib 目录下,复制到tomcat的lib目录下即可。

<%@ page language="java" contentType="text/html; charset=utf-8"

pageEncoding="utf-8"%>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<html>

<head></head>

<body>

<c:out value="Hello World!"></c:out>

<c:out value="${param.username}" default="unknown"/>

</body>

</html>

在<c:out>标签中将escapeXml的属性值设置为false,因此,<c:out>标签不会对分外字符进行HTML转换,<meta>标签便可以发挥浸染,在访问c_out2.jsp页面时就会跳转到www.itcast.cn网站。
如下,escapeXml设置为了false,在没有HTML转换的情形下meta发挥了浸染。

<c:out value="${param.username }" escapeXml="false">     

<meta http-equiv="refresh" content="0;url=http://www.itcast.cn" />  

</c:out>

20 <c:if>标签

<c:if test="testCondition" var="result"[scope="{page|request|session|application}"]>body content</c:if>

• test属性用于设置逻辑表达式。

• var属性用于指定逻辑表达式中变量的名字。

• scope属性用于指定var变量的浸染范围,默认值为page。
如果属性test的打算结果为true,那么标签体将被实行,否则标签体不会被实行。

举例:

<c:set value="1" var="visitCount" property="visitCount" />

<c:if test="${visitCount==1 }">    

This is you first visit. Welcome to the site!

</c:if>

由于利用了<c:set>标签将visitCount的值设置为1,因此,表达式${visitCount==1}的结果为true,便会输出<c:if>标签体中的内容。

21 <c:choose>标签

在程序开拓中不仅须要利用if条件语句,还常常会利用if-else语句。
为了在JSP页面中也可以完成同样的功能,Core标签库供应了<c:choose>标签,该标签用于指定多个条件选择的组合边界,它必须与<c:when>、<c:otherwise>标签一起利用。
<c:choose>标签没有属性,在它的标签体中只能嵌套一个或多个<c:when>标签和零个或一个<c:otherwise>标签,并且同一个<c:choose>标签中所有的<c:when>子标签必须涌如今<c:otherwise>子标签之前,其语法格式如下。

<c:choose>

<c:when test="${empty param.username}">      unKnown user.   

</c:when>

<c:when test="${param.username=='itcast' }">      ${ param.username} is manager.    </c:when>

<c:otherwise>     

${ param.username} is employee.   

</c:otherwise>

</c:choose>

22 <c:forEach>标签

在 JSP 页面中,常常须要对凑集工具进行循环迭代操作,为此,Core 标签库供应了一个<c:forEach>标签,该标签专门用于迭代凑集工具中的元素,如Set、List、Map、数组等

<% String[] fruits = { "apple", "orange", "grape", "banana" };%>

String数组中的元素:

<br />

<c:forEach var="name" items="<%=fruits%>">     ${name}<br />   </c:forEach>

<% Map userMap = new HashMap();

userMap.put("Tom", "123"); userMap.put("Make", "123"); userMap.put("Lina", "123");%>

<hr />

HashMap凑集中的元素:

<br />

<c:forEach var="entry" items="<%=userMap%>">

       ${entry.key} ${entry.value}<br />

   </c:forEach>

<c:forEach>标签的varStatus属性用于设置一个javax.servlet.jsp.jstl.core.LoopTagStatus类型的变量,这个变量包含了从凑集中取出元素的状态信息。
利用<c:forEach>标签的varStatus属性可以获取以下信息。

• count:表示元素在凑集中的序号,从1开始计数。

• index:表示当前元素在凑集中的索引,从0开始计数。

• first:表示当前是否为凑集中的第1个元素。

• last:表示当前是否为凑集中的末了一个元素。

<c:forEach var="name" items="<%=userList%> "varStatus="status">

<tr><td>${status.count}</td><td>${status.index}</td><td>${status.first}</td>        <td>${status.last}</td><td>${name}</td> </tr>    

</c:forEach>

23 <c:param>标签用于在URL地址中附加参数,它常日嵌套在<c:url>标签内利用。
<c:param>标签有两种语法格式,详细如下。

语法1:利用value属性指定参数的值<c:param name="name" value="value">

语法2:在标签体中指定参数的值<c:param name="name">parameter value</c:param>

24 布局URL

利用绝对路径布局URL:

<br /><c:url var="myURL" value="http://localhost:8080/chapter07/register.jsp"><c:param name="username" value="张三" /><c:param name="country" value="中国" /></c:url>   <a href="${myURL}">register.jsp</a><br />  

利用相对路径布局URL:<br />  <c:url var="myURL" value="register.jsp?username=Tom&country=France" />   <a href="${ myURL}">register.jsp</a>

25 什么是FilterFilter

被称作过滤器,其基本功能便是对Servlet容器调用Servlet的过程进行拦截,从而在Servlet 进行相应处理前后实现一些分外功能。

实现如下:

1定义拦截类,实现Filter接口

public class MyFilter implements Filter

//在doFilter中进行拦截

public void doFilter(ServletRequest request,ServletResponse response,       FilterChain chain) throws IOException, ServletException {    

// 用于拦截用户的要求,如果和当前过滤器的拦截路径匹配,该方法会被调用     PrintWriter out=response.getWriter();

out.write("Hello MyFilter");

}

2 在web.xml中进行配置拦截类

<filter>

<filter-name>MyFilter</filter-name>

<filter-class>cn.itcast.chapter08.filter.MyFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>MyFilter</filter-name>

<url-pattern>/MyServlet</url-pattern>

</filter-mapping>

在上述代码中,设置了过滤器对“/MyServlet”要求资源进行拦截,将在要求到达MyServlet程序前实行MyFilter程序。

26 利用通配符“”拦截用户的所有要求

27 拦截不同办法的访问要求

在 web.xml 文件中,一个<filter-mapping>元素用于配置一个 Filter 所卖力拦截的资源。
<filter-mapping>元素中有一个分外的子元素<dispatcher>,该元素用于指定过滤器所拦截的资源被Servlet容器调用的办法,<dispatcher>元素的值共有4个,详细如下。

1)REQUEST当用户直接访问页面时,Web 容器将会调用过滤器。
如果目标资源是通过Request Dispatcher的include()或forward()方法访问的,那么该过滤器将不会被调用。

2)INCLUDE如果目标资源是通过RequestDispatcher的include()方法访问的,那么该过滤器将被调用。
除此之外,该过滤器不会被调用。

3)FORWARD如果目标资源是通过RequestDispatcher的forward()方法访问的,那么该过滤器将被调用。
除此之外,该过滤器不会被调用。

4)ERROR如果目标资源是通过声明式非常处理机制调用的,那么该过滤器将被调用。
除此之外,过滤器不会被调用。

举例:

<filter>

<filter-name>ForwardFilter</filter-name><filter-class>cn.itcast.chapter08.filter.ForwardFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>ForwardFilter</filter-name>

<url-pattern>/first.jsp</url-pattern>

<dispatcher>FORWARD</dispatcher>

</filter-mapping>

28 Filter链

在一个Web运用程序中可以注册多个Filter程序,每个Filter程序都可以针对某一个URL进行拦截。
如果多个Filter程序都对同一个URL进行拦截,那么这些Filter就会组成一个Filter链(也叫过滤器链)。
Filter链用FilterChain工具来表示,FilterChain工具中有一个doFilter()方法,该方法的浸染便是让Filter链上确当前过滤器放行,使要求进入下一个Filter。

<filter-name>MyFilter01</filter-name><filter-class>cn.itcast.chapter08.filter.MyFilter01</filter-class></filter><filter-mapping><filter-name>MyFilter01</filter-name><url-pattern>/MyServlet</url-pattern></filter-mapping><filter><filter-name>MyFilter02</filter-name><filter-class>cn.itcast.chapter08.filter.MyFilter02</filter-class></filter><filter-mapping><filter-name>MyFilter02</filter-name>

<url-pattern>/MyServlet</url-pattern></filter-mapping><servlet><servlet-name>MyServlet</servlet-name><servlet-class>cn.itcast.chapter08.filter.MyServlet</servlet-class></servlet><servlet-mapping><servlet-name>MyServlet</servlet-name><url-pattern>/MyServlet</url-pattern></servlet-mapping>

MyServlet首先被MyFilter01拦截了,打印出MyFilter01中的内容,然后被MyFilter02拦截,直到MyServlet被MyFilter02放行后,浏览器才显示出MyServlet中的输出内容。

29 java解码

剖析:当调用request.getParameter()函数时,会自动进行一次URI的解码过程,调用时内置的解码过程会导致乱码涌现。
而URI 编码两次后,request.getParameter()函数得到的是原信息URI编码一次的内容。
再用可控的解码函数 java.net.URLDecoder.decode()就可解出原始的精确的信息。

30 java编码

java.net.URLEncoder.encode(strBuf,"UTF-8"); .

31 Listener监听器

上述监听器根据监听事宜的不同可以将其分为3类,详细如下。

(1)用于监听域工具创建和销毁的事宜监听器(ServletContextListener接口、HttpSession Listener接口、ServletRequestListener接口)。

(2)用于监听域工具属性增加和删除的事宜监听器(ServletContextAttributeListener接口、HttpSessionAttributeListener接口、ServletRequestAttributeListener接口)。

(3)用于监听绑定到 HttpSession 域中某个工具状态的事宜监听器(HttpSessionBinding Listener接口、HttpSessionActivationListener接口)。

在Servlet规范中,这3类事宜监听器都定义了相应的接口,在编写事宜监听器程序时只需实现对应的接口就可以。
Web 做事器会根据监听器所实现的接口,把它注册到被监听的工具上,当触发了某个工具的监听事宜时,Web容器将会调用Servlet监听器与之干系的方法对事宜进行处理。

设置监听超时信息为了尽快地查看到HttpSession工具销毁的过程,可以在chapter08运用的web.xml文件中设置session的超时时间为2min,详细代码如下。

<session-config><session-timeout>2</session-timeout></session-config>

监听域工具的属性变更

1)jsp中设置属性

<%getServletContext().setAttribute("username", "itcast");

getServletContext().setAttribute("username", "itheima");

getServletContext().removeAttribute("username");

session.setAttribute("username", "itcast");

session.setAttribute("username", "itheima");

session.removeAttribute("username");

request.setAttribute("username", "itcast");

request.setAttribute("username", "itheima");

request.removeAttribute("username");%>

2)编写一个名称为MyAttributeListener的监听器类,该类实现了ServletContextAttributeListener、HttpSessionAttributeListener 和ServletRequestAttributeListener接口,并实现这些接口中的所有方法

3)web.xml中添加

<listener><listener-class>listener.MyAttributeListener</listener-class></listener>

32 数据库连接池

为了避免频繁地创建数据库连接,数据库连接池技能应运而生。
数据库连接池卖力分配、管理和开释数据库连接,它许可运用程序重复利用现有的数据库连接,而不是重新建立。

数据源中包含数据库连接池。
如果数据是水,数据库便是水库,数据源便是连接到水库的管道,终端用户看到的数据集是管道里流出来的水。
一些开源组织供应了数据源的独立实现,常用的有DBCP数据源和C3P0数据源。

DBCP数据源

DBCP是数据库连接池(DataBase Connection Pool)的简称,是Apache组织下的开源连接池实现,也是Tomcat做事器利用的连接池组件。
单独利用DBCP数据源时,须要在运用程序中导入两个JAR包,详细如下。
1.commons-dbcp.jar包commons-dbcp.jar 包是 DBCP 数据源的实现包,包含所有操作数据库连接信息和数据库连接池初始化信息的方法,并实现了DataSource接口的getConnection()方法。
2.commons-pool.jar包commons-pool.jar包是DBCP数据库连接池实现包的依赖包,为commons-dbcp.jar包中的方法供应了支持。
可以这么说,没有该依赖包,commons-dbcp.jar包中的很多方法就没有办法实现。

C3P0数据源

当利用 C3P0数据源时,首先须要创建数据源工具,创建数据源工具可以利用ComboPooledDataSource 类,该类有两个布局方法,分别是ComboPooledDataSource()和 ComboPooledDataSource(String configName)。

1.通过ComboPooledDataSource()布局方法创建数据源工具

导入JAR包c3p0-0.9.1.2.jar

public class Example03 {

public static DataSource ds = null;

//初始化C3P0数据源

static {

ComboPooledDataSource cpds = new ComboPooledDataSource();

// 设置连接数据库须要的配置信息

try {

cpds.setDriverClass("com.mysql.jdbc.Driver");

cpds.setJdbcUrl("jdbc:mysql://localhost:3306/world");

cpds.setUser("root2");

cpds.setPassword("caicai123");

// 设置连接池的参数

cpds.setInitialPoolSize(5);

cpds.setMaxPoolSize(15);

ds = cpds;

}

catch (Exception e) {

throw new ExceptionInInitializerError(e);

}

}

public static void main(String[] args) throws SQLException {

// 获取数据库连接工具

System.out.println(ds.getConnection());

}

}

2 通过读取配置文件创建数据源工具

利用ComboPooledDataSource(String configName)布局方法读取c3p0-config.xml 配置文件,从而创建数据源工具,然后获取数据库连接工具。

(1)在src根目录下创建一个c3p0-config.xml文件,用于设置数据库的连接信息和数据源的初始化信息

<?xml version="1.0" encoding="UTF-8"?>

<c3p0-config> 

<default-config>    

<property name="driverClass">com.mysql.jdbc.Driver</property>

<property name="jdbcUrl">jdbc:mysql://localhost:3306/world</property>    

<property name="user">root</property>  

<property name="password">caicai123</property>  

<property name="checkoutTimeout">30000</property>

<property name="initialPoolSize">10</property>   

<property name="maxIdleTime">30</property> 

<property name="maxPoolSize">100</property>  

<property name="minPoolSize">10</property>   

<property name="maxStatements">200</property>

</default-config>

<named-config name="itcast">

<property name="driverClass">com.mysql.jdbc.Driver</property> 

<property name="jdbcUrl">jdbc:mysql://localhost:3306/world</property> 

<property name="user">root</property>

<property name="password">caicai123</property>  

<property name="initialPoolSize">5</property>   

<property name="maxPoolSize">15</property> 

</named-config>

</c3p0-config>

(2)在利用ComboPooledDataSource(String configName)方法创建工具时必须遵照以下两点。
1)配置文件名称必须为c3p0-config.xml或者c3p0.properties,并且位于该项目的src根目录下。
2)当传入的configName值为空或者不存在时,则利用默认的配置办法创建数据源。

public class Example04 {

public static DataSource ds = null;

// 初始化C3P0数据源8

static {

// 利用c3p0-config.xml配置文件中的named-config节点中name属性的值

ComboPooledDataSource cpds = new ComboPooledDataSource("itcast");

ds = cpds;

}

public static void main(String[] args) throws SQLException {

System.out.println(ds.getConnection());

}

}

33 DBUtils工具先容

为了更加大略地利用JDBC,Apache组织供应了一个DBUtils工具,它是操作数据库的一个组件,实现了对JDBC的大略封装,可以在不影响性能的情形下极大地简化JDBC的编码事情量.

DBUtils工具的核心是org.apache.commons.dbutils.QueryRunner类和org.apache.commons. dbutils.ResultSetHandler接口.

QueryRunner类QueryRunner类简化了实行SQL语句的代码,它与ResultSetHandler组合在一起就能完成大部分的数据库操作,大大地减少了编码量。
QueryRunner类供应了带有一个参数的布局方法,该方法以javax.sql.DataSource作为参数通报到 QueryRunner 的布局方法中来获取 Connection 工具。
针对不同的数据库操作, QueryRunner类供应了几种常见的方法,详细如下。

• query(String sql, ResultSetHandler rsh, Object… params)方法该方法用于实行查询操作,它可以从供应给布局方法的数据源 DataSource 或利用的setDataSource()方法中得到连接。

• update(String sql, Object… params)方法该方法用于实行插入、更新或者删除操作,个中,参数params表示SQL语句中的置换参数。

• update(String sql)方法该方法用来实行插入、更新或者删除操作,它不须要置换参数。

ResultSetHandler接口ResultSetHandler接口用于处理ResultSet结果集,它可以将结果集中的数据转为不同的形式。
根据结果集中数据类型的不同,ResultSetHandler供应了几种常见的实现类,详细如下。

• BeanHandler:将结果集中的第1行数据封装到一个对应的JavaBean实例中。

• BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,并存放到List里。

• ScalarHandler:将结果集中某一条记录的个中某一列的数据存储成Object工具。
其余,在ResultSetHandler接口中,供应了一个单独的方法handle (java.sql.ResultSet rs),如果上述实现类没有供应想要的功能,可以通过自定义一个实现 ResultSetHandler 接口的类,然后通过重写handle()方法,实现结果集的处理。

34 mysql Jar 包下载

https://dev.mysql.com/downloads/connector/j/

35 DBUtils Cannot create chapter10.User: class org.apache.commons.dbutils.BeanProcessor (in module commons.dbutils)

发生这种情形是由于Apache Commons DBUtils的不决名模块无法访问您的类。

发生这种情形是由于您正在利用 Java平台模块系统
要办理此问题,您须要导出软件包,以便Apache模块可以看到它们。

module chapter10 {

requires java.sql;

requires c3p0;

requires java.desktop;

requires commons.dbutils;

exports chapter10;

}

36 DBUtils举例如下,定义两个类去访问beanhandler,beanlisthandler

1.定义BaseDao类查询数据库

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

import org.apache.commons.dbutils.ResultSetHandler;

public class BaseDao {

//优化查询

public static Object query(String sql,ResultSetHandler<?> rsh,Object... params) throws SQLException

{

Connection conn = null;

PreparedStatement pstmt = null;

ResultSet rs = null;

try {

//得到链接

conn = JDBCUtils.getConnection();

//预编译sql

pstmt = conn.prepareStatement(sql);

//将参数设置进去

for(int i=0;params != null && i < params.length;i++)

{

pstmt.setObject(i+1, params[i]);

}

//发送sql

rs = pstmt.executeQuery();

//让调用者实现对结果集的处理

Object obj = rsh.handle(rs);

return obj;

}

catch(Exception e)

{

e.printStackTrace();

}

finally

{

//开释资源

JDBCUtils.release(pstmt, conn);

}

return rs;

}

}

2.封装User类

package chapter10;

public class User {

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getPassword() {

return password;

}

public void setPassword(String password) {

this.password = password;

}

private int id;

private String name;

private String password;

}

3. Bean Handler类对结果集的处理

BaseDao basedao = new BaseDao();

String sql = "select from user where id=?";

User user = (User)basedao.query(sql, new BeanHandler(User.class), 1);

BeanListHandler类对结果集的处理

BaseDao basedao = new BaseDao();

String sql = "select from user";

ArrayList<User> list = (ArrayList<User>)basedao.query(sql, new BeanListHandler(User.class));

在利用DBUtils工具操作数据库时,如果须要输出结果集中一行数据的指定字段值,可以利用ScalarHandler类

BaseDao basedao = new BaseDao();

String sql = "select from user where id=?";

Object arr = (Object) basedao.query(sql, new ScalarHandler("name"), 1);

37 利用DBUtils实现增编削查

//查询所有

创建QueryRunner工具    

QueryRunner runner = new QueryRunner(C3p0Utils.getDataSource());    

// 写SQL语句    

String sql = "select from user";    

// 调用方法    

List list = (List) runner.query(sql,new BeanListHandler(User.class));

//查询单个工具

// 写SQL语句    

String sql = "select from user where id=?";    

// 调用方法    

User user = (User) runner.query(sql,new BeanHandler(User.class), new Object[] { id });

添加用户的操作

// 写SQL语句37    

String sql = "insert into user (name,password) values (?,?)";    

// 调用方法    

int num = runner.update(sql,new Object[] { user.getName(), user.getPassword() });

//变动用户

// 写SQL语句    

String sql = "update user set name=?,password=? where id=?";    

// 调用方法    

int num = runner.update(sql, new Object[] { user.getName(),user.getPassword(),user.getId() });

// 删除用户    

String sql = "delete from user where id=?";    

// 调用方法65    

int num = runner.update(sql, id);