学习Java第三天

学习Java第三天JSP的工作模式是请求/响应模式,客户端首先发出HTTP请求,JSP程序收到请求后进行处理并返回处理结果。

大家好,欢迎来到IT知识分享网。

1 jsp工作原理

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

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

2 JSP脚本元素

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= “属性值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 页面中使用。

学习Java第三天

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隐式对象

学习Java第三天

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数据源

学习Java第三天

当使用 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);

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/54724.html

(0)
上一篇 2024-07-30 15:33
下一篇 2024-07-30 16:45

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信