一、HTTP协议
1.1 HTTP协议定义
- 超文本传输协议
- 所有的www文件都必须遵守此标准
- 设计http协议的最初目的是提供一种发布和修改html页面的方法
1.2 HTTP组成
1.2.1 请求
1. 请求行
-
定义:请求信息的第一行
-
格式:
请求的方式 + 请求的资源 + 协议/版本
例如:GET /1.html HTTP/1.1 -
请求的方式:
-
get
方式:会将参数追加在地址栏,参数大小有限制http://IP地址 : 端口号 / 项目名 / 资源 ? 参数名=值 & 参数名=值
-
post
方式:不会将参数追加在地址栏,请求的参数在请求体里,参数大小无限制参数名=值 & 参数名=值
-
注意:如果未声明为post,则均为get
-
2. 请求头
key/value形式,value可以为多个值的
3. 请求体
- 位置:和请求头之间有一个空行
- 功能:存post请求参数
1.2.2 响应
1. 响应行
-
定义:响应信息的第一行
-
格式:
版本 / 协议 + 响应的状态码 + OK
例如:HTTP/1.1 200 OK -
状态码:
- 200:响应成功
- 302:重定向
- 304:读缓存
- 404:用户访问的数据不存在
- 500:服务器内部错误
2. 响应头
key / value的格式(value可以是多值的)
3. 响应体
- 位置:和响应头之间有一个空行
- 功能:存浏览器解析的内容
二、Servlet服务器
2.1 什么是servlet
html
网页代码通过servlet
服务器访问dao层的JDBC数据库Servlet = java + html(url)
- 狭义:
javax.servlet.Servlet
接口及其子接口 - 广义:指实现了Servlet接口的普通
java
类,在于交互式地浏览和修改数据,生成动态web
内容
2.2 servlet的作用
- 接收请求
- 处理请求
- 做出响应 【生成动态的web内容】
2.3 使用Servlet接口的步骤
-
编写一个类
A. 实现Servlet接口
B. 重写service()方法
package com.study.servlet;
import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class DemoServlet implements Servlet { //实现servlet接口
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public ServletConfig getServletConfig() {
// TODO Auto-generated method stub
return null;
}
@Override
public String getServletInfo() {
// TODO Auto-generated method stub
return null;
}
@Override
public void init(ServletConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
@Override
// 重新service()方法
public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {
System.out.println("DemoServlet接收到请求!");
}
}
-
编写xml配置文件
C. 注册servlet
D. 绑定路径【路径:目前要求以/开头】
// 注册servlet
<servlet>
<servlet-name> </servlet-name> //给当前的servlet定义名字
<servlet-class> </servlet-class> //需要处理请求的servlet的带包的路径
</servlet>
// 绑定路径
<servlet-mapping>
<servlet-name> </servlet-name> //对应实体类的名称
<url-pattern> </url-pattern> //给当前servlet的路径,以/开始
</servlet-mapping>
- 测试:浏览器输入 协议://主机:端口号/项目名/绑定路径
2.4 Servlet的工作原理(执行流程)
- 页面向服务器发送请求
- 服务器去
web.xml
中找 - 找到对应的
<servlet>
中的<servlet-name>
服务器名 - 根据第三步中的
<servlet-name>
,对应<servlet-mapping>
中的<servlet-name>
,然后找到<servlet-class>
,找到指定Servlet - 默认执行
service()
方法,请求处理,做出响应
2.5 最终创建Servlet方式
继承HttpServlet类,也称Servlet
- 类 : HttpServlet : GenericServlet : Servlet
HttpServlet
--> 实现了service
方法 --> 强转两个参数,调用了重载的service方法;获取请求方式,根据请求方式不同调用不同的doXXX方法GenericServlet
--> 除了service方法没有实现,其他方法都实现了
2.6 Servlet的生命周期
Servlet被创建到消亡的过程:
- 构造器
(1) 执行次数:在整个生命周期中只执行一次
(2) 执行时机:在第一次接受请求时执行 init()
:初始化
(1) 执行次数:在整个生命周期中只执行一次
(2) 执行时机:在第一次接受请求时执行service()
:服务方法
(1) 执行次数:在整个生命周期中执行多次
(2) 执行时机:在每次接受请求时执行destory()
:对Servlet进行销毁
(1) 执行次数:在整个生命周期中只执行一次
(2) 执行时机:服务器正常关闭或项目移除的时候执行
Servlet 的生命周期由一系列事件组成:
- 加载类
- 实例化
- 初始化
- 请求处理
- 销毁
2.7 ServletContext上下文对象
2.7.1 ServletContext的作用
- 获取全局初始化参数
- 资源共享(servlet通信)
- 获取资源文件
- 相当于班主任,什么信息都有;所有的Servlet都可以向班主任要其他servlet的信息
2.7.2 ServletContext的生命周期
- 创建:服务器启动的时候为每一个项目创建一个ServletContext上下文对象,ServletContext是项目的一个引用
- 销毁:服务器关闭或项目移除的时候ServletContext销毁
- 获取方法有二【第二种为重点】
// 方法一:
getServletConfig().getServletContext()
//方法二:获取ServletContext对象【重要】
ServletContext sc = getServletContext();
2.7.3 常用方法
package com.study.a_ServletContextAPI;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ServletContextAPI extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取ServletContext对象
ServletContext sc = getServletContext();
// 1.常用方法一:获取全局初始化参数
String db = sc.getInitParameter("db");
System.out.println(db);
// 2.常用方法二:获取全局初始化参数名称
Enumeration<String> initParameterNames = sc.getInitParameterNames();
while(initParameterNames.hasMoreElements()) {
String string = (String) initParameterNames.nextElement();
System.out.println(string+":"+sc.getInitParameter(string));
}
// 3. 常用方法三:获取一个资源在服务器上的真实路径
String realPath = sc.getRealPath("/1.html");
System.out.println(realPath);
//4. 常用方法四:以流的形式返回一个文件
InputStream is = sc.getResourceAsStream("/1.html");
System.out.println(is);
//5. 常用方法五:获取一个文件的mime类型(大类型/小类型 例如:img/gif)
String mimeType = sc.getMimeType("/1.html");
System.out.println(mimeType);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
2.7.4 资源共享
setAttribute(String name,Object value)
—— 设置
getAttribute(String name)
—— 获取指定的属性值
removeAttribute(String name)
—— 移除指定的属性
//获取上下文对象
ServletContext sc = this.getServletContext();
//往上下文对象中放数据
sc.setAttribute("aa", "AA");
//获取上下文对象
ServletContext sc = this.getServletContext();
//从上下文对象中获取数据
Object attribute = sc.getAttribute("aa");
System.out.println(attribute);
//获取上下文对象
ServletContext sc= getServletContext();
//删除上下文对象中的aa
sc.removeAttribute("aa");
2.8 ServletConfig
-
定义:代表了Servlet的配置对象
-
作用:
- 获取Servlet初始化参数
- 获取ServletContext对象
- 获取Servlet的名字
2.9 servlet中的三大域对象
2.9.1 servletContext
-
生命周期
- 创建:服务器启动的时候为每一个项目创建一个ServletContext上下文对象,ServletContext是项目的一个引用
- 销毁:服务器关闭或项目移除的时候ServletContext销毁
-
作用范围:整个应用
-
作用:存放整个项目共享的数据
2.9.2 session
- 生命周期
- 创建:java代码中暂时认为第一次调用
request.getSession()
- 销毁:三种方式销毁(之后会统一讲解)
- 创建:java代码中暂时认为第一次调用
- 作用范围:一次会话
- 作用:存放私有数据
2.9.3 request
- 生命周期
- 创建:请求来的时候
- 销毁:响应生成的时候
- 作用范围:一次请求
- 作用:存放一次请求中的资源
三、 Response响应(服务器到客户端)
3.1 response响应的定义
代表客户端向服务器发送请求报文,该对象由服务器(web容器或Servlet容器)创建,同时发送给Service(),Service()再发送给doGet()或doPost()
3.2 response响应的类型
HttpservletResponse response
3.3 response的作用
- 服务器向客户端做出响应(文本 | html)
- 重定向(路径跳转)【两次请求】
3.4 响应行
-
格式
协议/版本 + 状态码 + 状态码说明
-
状态码分类
- 1xx:已发送请求
- 2xx:响应完成 200:响应正常完成
- 3xx:还需浏览器进一步操作 302:重定向 ;304:读缓存
- 4xx:用户操作错误 400:用户访问资源不存在
- 5xx:服务器错误 500:程序异常
-
常用方法
setStatus(int code)
—— 针对1 2 3sendError(int code)
—— 针对 4 5
3.5 响应头(重定向)
-
格式
key / value形式(value可多值)
-
常用方法
setHeader(String name,String value)
——设置一个字符串形式的响应头 -
常见的三个响应头
location
:重定向
重定向的概念理解:
A向我借钱【第一次请求】,我说我没有钱,我知道B有钱,让他去问B借钱,A现在知道了B有钱,A再去向B借钱【第二次请求】,B借给他了钱。
- 第一种写法
- 设置重定向的状态码302 ——
response.setStatus(302);
- 设置重定向的头 location ——
response.setHeader("location", "/response/demo");
- 设置重定向的状态码302 ——
//1.设置重定向的状态码302
response.setStatus(302);
//2.设置重定向的头 location
response.setHeader("location", "/response/demo");
- 第二种写法【重要】
response.sendRedirect("/response/demo");
重定向到demo
//从根目录开始找,与请求转发不同,请求转发是内部路径
response.sendRedirect("/response/demo");
refresh
:定时刷新
//Java中使用
response.setHeader("refresh","秒数;url=跳转的路径")
//html中使用
<mate http-equiv="refresh" content="秒数 ; url=跳转的路径">
content-type
:
- 设置文件的mime类型
- 设置响应流的编码,通知浏览器用什么编码打开
3.6 响应体
- 常用方法:
PrintWriter getWriter()
—— 字符流ServletOutputStream getOutputStream()
—— 字节流- 自己编写的使用字符流,其他的使用字节流,两个流互斥
- 解决响应乱码:
// 方法一:
response.serHeader("content-type","text/html;charset=utf-8");
// 方法二:
response.setContentType("text/html;charset=utf-8");
四、Requset请求(客户端到服务器)
4.1 request请求的定义
代表客户端向服务器发送请求报文,该对象由服务器(web容器或Servlet容器)创建,同时发送给Service(),Service()再发送给doGet()或doPost()
4.2 request请求的类型
HttpServletRequest request
4.3 请求行
-
格式:
请求方式 + 请求的资源 + 协议/版本
-
重要的方法
String getMethod()
—— 获取请求的方式(get还是post方式请求)String getContextPath()
—— 获取项目动态路径String getRemoteAddr()
—— 获取请求者的IP
-
了解的方法
- String getRequestURI() —— 获取的是请求的资源(不带get请求的参数?前边的内容)
- String getQueryString() —— 获取的get请求参数(get请求行?后边的内容)
- String getProtocol() —— 获取协议和版本
4.4 请求头
-
格式:
key / value (value可多值)
-
重要的方法
String getHeader(String name)
—— 获取的一个请求头(返回值String) -
了解的方法
- int getIntHeader(String name)
- long getDateHeader(String name)
- Enumeration getHeaders(String name)
4.5 请求体【存post请求参数】
-
格式:
username=tom & hobby=play
-
常用的方法【三个方法同时适用于get、post的请求】
String getParameter(String name)
—— 获取单值的请求参数String getParameterValues(String name)
—— 获取的指定的多值的请求参数Map<String,String[]> getParameterMap()
—— 获取的所有的参数名称和值
4.6 请求转发
-
请求转发的概念理解:
A向我借钱,我说我没钱,我知道B有钱,我去找B,给B说A要借钱,B借给我了钱,我再把钱给B。
-
格式:
request.getRequestDispatcher(“/内部路径”).forward(request, response);
-
作用:
两个资源可以在同一次请求之间进行资源共享
【资源共享仅限于当前页面和请求的页面】
4.7 请求转发和重定向的区别
- 重定向发送两次请求,请求转发发送一次
- 重定向地址栏变化,请求转发地址栏不变
- 重定向是响应发起的,请求转发是请求发起的
- 重定向路径不带协议和主机的绝对路径,请求转发是内部路径
- 重定向不能使用request的属性操作,请求转发可以
4.8 request域对象
-
创建:请求来的时候
-
销毁:生成响应的时候
-
方法:
- request.setAttribute(name,value)
- request.getAttribute(String name)
- request.removeAttribute(name)
-
【域对象都有范围,域对象都有xxxAttribute方法】
五、JSP
5.1 JSP的定义
- JSP 总称 Java Server Pages(Java服务器页面)
servlet = Java + html
JSP = html +Java
- JSP只能运行在服务器(web容器)中
5.2 JSP的本质
JSP本质是Servlet
5.3 JSP的运行原理
- 浏览器向JSP服务器发送请求
- 如果是第一次访问
.jsp
页面时,会经过以下步骤:- 服务器将
.jsp
文件翻译为.java
文件 - 将
.java
文件编译为.class
文件
- 服务器将
- 如果不是第一次访问
.jsp
文件,就看文件没有更新修改,未修改则以后再访问,就不会翻译和编译 - 将产生结果返回到客户端
5.4 JSP的基本语法(6个)
- 指令
语法:<%@ %>
- 脚本片段 —— 生成在
service
方法中
语法:<% %>
作用:html中书写java代码 - 表达式 —— 生成在service方法中,相当于调用了
out.print()
语法:<%= %>
作用:输出数据到页面 - 模板元素(html)
- 声明成员 —— 不会出现在service方法中,出现在类中(类中可以写方法,所以声明可以定义方法)
语法:<%! %>
作用:书写java代码 - 注释
html —— <!-- --> 在客户端浏览器中是看不见的,源代码中能看见
java —— // /**/
jsp —— ctrl+shift+c <%-- --%> 在客户端源代码中是看不见的
5.5 JSP中的指令
5.5.1 语法
<%@ 指令名 属性=属性值 属性2=属性值 %>
- 注意:指令可出现多次
5.5.2 page指令
- 语法:
<@page 属性=属性值 %>
- 作用:定义整个JSP页面的全局属性
-
language ——支持语言只有 java
contentType —— response.setContentType()作用一致
pageEncoding —— JSP页面的编码
import —— 导包
errorPage —— 当前页面报错了显示的页面
isErrorPage —— 设置当前页面是否为错误页面
5.5.3 include指令
- 语法::
<@include file="相对路径" %>
- 作用:将目标页面包含到当前页面
- 特点:静态包含,被包含的文件不会被翻译和编译
5.5.4 taglib指令
- 语法:
<@taglib prefix="前缀标签" uri="标签库uri" %>
- 作用:导入标签库
5.6 JSP的动作标签
5.6.1 语法
<jsp:标签名 属性=属性值> </jsp:>
5.6.2 请求转发(页面跳转)【地址栏不变】
-
带参数
<jsp:forward page="被包含文件的路径"> <jsp:param ><jsp:param> </jsp:forward>
-
不带参数
注意开始标签结束标签之间不能用任何内容
5.6.3 动态包含
-
语法:包含一个静态或者动态的文件
<jsp:include page="被包含文件的相对路径" flush="true"> <jsp:param name="paramName" value="paramValue" /> <!-- 亦可以没有参数 --> <jsp:include>
-
特点:被包含文件先被翻译和编译
-
include指令和include动作的不同点:
- include指令:<%@ include file=“文件的相对路径”%>
- include动作:<jsp:include page=“文件的相对路径” />
- include指令中直接包含源代码,include动作中包含请求的HTML代码,并且支持JSP表达式和Struts应用中的请求模式
- inlcude指令中不能带参数,而include动作中可以带参数
- include指令的file属性不能是表达式,而动作中的path属性可以使用表达式
- 指令比动作请求速度快,因为指令处理一个请求,动作处理两个请求
5.6.4 useBean标准动作
- 语法
<jsp:useBean id="实例的变量名" class="JavaBean的类名" scope="JavaBean的作用范围">
- 作用范围
<jsp:useBean>
声明对象的默认有效范围为page范围
5.7 九大隐含对象
-
定义:可以在JSP中直接使用的对象,不需要我们new的对象,服务器实例化的九大隐含对象,并存放在_jspService方法中
-
对象详情:
1. application【域范围最大 —— 当前项目】
- 类型:ServletContext
- 作用:JSP域对象
- Servlet中获取方式:this.getServletContext()
2. session【域范围第三小 —— 一次会话(可包含多次请求)】
- 类型:HttpSession
- 作用:JSP域对象
- Servlet中的获取方式:request.getSession()
3. request【域范围第二小 —— 一次请求】
- 类型:HttpServletRequest
- 作用:JSP域对象
- Servlet中的获取方式:直接使用
<% String name = request.getParameter("username"); //请求转发 %>
4. pageContext【域范围最小 —— 当前页面】
- 类型:pageContext
- 作用:
- JSP域对象----xxxAttribute()
- 操作其他三个域对象----xxxAttribute(…,int scope)
- PAGE_SCOPE
- REQUEST_SCOPE
- SESSION_SCOPE
- APPLICATION_SCOPE
- 直接获取其他八个隐含对象getXxx()
- 便捷查找 —— findAttribute(String name)
【依次从pageContext、request、session、application中查找指定的属性,若找到则返回,若找不到返回null】
- Servlet中的获取方式:无
5.response
- 类型:HttpServletResponse
- 作用:与Servlet中的response对象一致
- Servlet中的获取方式:直接使用
<% response.sendRedirect("welcome.jsp"); //重定向 %>
6.page
- 类型:Object
- 作用:page = this,为当前类的对象
7.out
- 类型:JspWriter
- 作用:与Servlet中的PrintWriter作用类似(都继承了java.io.Writer)
<% // 这两种写法都不能实现换行 // 第一种执行完不结束当行,第二种结束当行 out.print("第一个jsp页面"); out.println("第一个jsp页面"); %>
8.config
- 类型:ServletConfig
- 作用:与Servlet中的ServletConfig作用一致
- Servlet中的获取方式:this.getServletConfig()
9.exeption
- 类型:Throwable
- 作用:接受处理异常信息
六、乱码的总结
6.1 乱码产生的原因
服务器和浏览器编码 / 解码不一致
6.2 响应的乱码
- 产生的原因
- 服务器使用 iso-8859-1 方式编码
- 浏览器使用 utf-8 方式解码
- 解决的方法
// 方法一:
response.setHeader("content-Type","text/html;charset=utf-8");
// 方法二:(重点)
response.setContentType("text/html;charset=utf-8");
6.3 请求的乱码
- 产生的原因
- 浏览器使用utf-8编码
- 服务器使用iso-8859-1解码
- 解决的方法
- 一、反向解码
- 二、通用方式【get post都能用】
new String(乱码.getBytes("iso8859-1","utf-8")) ;
- 三、post方式【只针对post】
request.setCharacterEncoding("utf-8");
package com.study.luanmaServlet;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.Charset;
public class LmDemo {
public static void main(String[] args) throws UnsupportedEncodingException {
String s="汤姆";
System.out.println(s);
//模拟浏览器
String s1 = URLEncoder.encode(s,"utf-8");
System.out.println(s1);
//模拟服务器
String s2 = URLDecoder.decode(s1,"iso-8859-1");
System.out.println(s2);
//解决的方式一【反向解码】
//1. 使用ISO-8859-1编码
String s3 = URLEncoder.encode(s2,"iso-8859-1");
System.out.println(s3);
//2. 使用utf-8解码
String s4 = URLDecoder.decode(s3,"utf-8");
System.out.println(s4);
//解决的方式二【通用方式】
//1. 把乱码的数据打成iso-8859-1的字节数组
byte[] bytes = s2.getBytes("iso-8859-1");
//2. 再把字节数组使用utf-8的编码方式重新组成字符串
String s5 = new String(bytes,"utf-8");
System.out.println(s5);
//简写方式
String s6 = new String(s2.getBytes("iso-8859-1"),"utf-8");
System.out.println(s6);
}
}
6.4 文件的乱码
针对于下载功能,文件名也会产生乱码
-
产生的原因
- 不同浏览器对下载文件的中文名的编码格式不一样
- IE和谷歌是UTF-8
- 火狐是base64
-
解决的方法
- IE和谷歌 UTF-8 :URLEncoder.encode(“中文名”,“编码方式”)
- 火狐 : 直接使用base64位即可
-
注意:根据浏览器的不同,我们使用工具类来帮助我们解决文件名为中文的乱码问题
七、Cookie和Session会话技术
7.1 什么是会话
用户开一个浏览器访问一个网站,只要不关闭浏览器,不管该用户点击多少个超链接,访问多少资源,直到用户关闭浏览器,或者服务器关闭,整个过程叫一次会话
7.2 会话过程中要解决的问题
用来保存用户在访问过程中产生的数据
7.3 cookie:浏览器端的会话
7.3.1 cookie工作流程
- 浏览器访问服务器,服务器产生键值对形式的cookie
- 通过响应头(Set-Cookie)返回给浏览器
- cookie保存在浏览器上,下次访问的服务器的时候,根据一定的规则携带不同的cookie,通过请求头(Cookie)携带,服务器就可以拿到这些cookie
- cookie是web服务器保存在客户端的一系列文本信息
7.3.2 cookie的API
-
创建cookie ——
new Cookie(String name,String value)
-
返回给浏览器 ——
response.addCookie(Cookie c)
-
获取cookie ——
Cookie[] request.getCookies()
-
获取cookie的名称 ——
getName()
-
获取cookie的value ——
getValue()
-
设置cookie在浏览器端的存活时间 ——
setMaxAge(int 秒数)
【若秒数=0,则删除该cookie(前提,必须路径相同)】
-
-
cookie的路径
- 设置cookie的路径 ——
setPath(String cookie的path)
- 当访问的url包含此cookie的路径,就会携带这个cookie,反之不会
- 同一路径下不能用同名的cookie,有的话会覆盖,不同路径下可以有同名的cookie】
- 设置cookie的路径 ——
-
注意
-
一个路径不存在重名的cookie
-
不同路径可以有重名的cookie
-
默认路径:从项目路径开始,到最后一个"/"结束
例如:http://localhost/day12/aa/bb/cc 的默认路径是 day12/aa/bb
-
7.3.3 cookie的注意事项
- cookie不能跨浏览器
- cookie不支持中文
7.4 session:服务器端的会话
7.4.1 session工作流程
- 浏览器向服务器发送请求
- 服务器判断浏览器是否携带了唯一标识
- 若有唯一标识,服务器拿着唯一标识去session池里查询是否有对应的标识
- 若有,直接操作session对象,并把它们存放到浏览器端
- 若没有,服务器会为其创建一个私有的内存空间,可以操作session,把它存放在浏览器端
- 若无唯一标识,服务器会为其创建一个私有的内存空间,可以操作session,把它存放在浏览器端
7.4.2 session的API
- session的获取 ——
HttpSession session = request.getSession();
- session属性操作 ——
xxxAttribute()
- session创建和销毁的时间 ——
long starttime = session.getCreationTime();
long endtime = session.getLastAccessedTime();
7.4.3 session的生命周期
- 创建:java代码中暂时认为第一次调用request.getSession()
- 销毁:
- 服务器非正常关闭 【正常关闭不会销毁】
- 超时
- 默认tomcat是30分钟
- 手动设置:
setMaxInactiveInterval(int interval)
【一般不用这种方法】
- 手动销毁:
invalidate()
八、EL表达式和JSTL标签
8.1 EL表达式
8.1.1 el表达式的概念
提供了在JSP中简化表达式的方法,让jsp代码更加简单
8.1.2 el表达式作用
将html中的Java标签<% =… %>替换掉,使html中不再出现Java代码
8.1.3 el表达式语法
${ 表达式 }
8.1.4 el表达式功能
1. 获取域中的数据
- 获取简单的数据:
${ pageScope | requestScope | sessionScope | applicationScope . 属性名 }
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>获取简单的数据</title>
</head>
<body>
<%
session.setAttribute("skey", "svalue");
application.setAttribute("akey", "avalue");
session.setAttribute("eee", "svalue");
application.setAttribute("eee", "avalue");
%>
${sessionScope.skey} //获取session中的skey
<hr>
${applicationScope.akey} //获取application中的akey
<hr>
${skey}<br>
${akey}
<hr>
${eee} <!-- 从最小域查找,在这里找到的是“svalue” -->
</body>
</html>
2. 获取复杂的数据
- 获取域中的数组中的值
${ 数组属性名[index] }
- 获取域中list的值
${ list属性名[index] }
- 获取域中map的值
${ map对象 . 键 }
- 获取域中JavaBean的数据
${ JavaBean对象 . bean属性 }
3. 注意
- 如果找不到属性怎么办?
- 能获取则获取,不能则返回 " "
${ 域中属性名 }
: 依次从pageScope
,requestScope
,sessionScope
,applicationScope
中查找对应的属性- 若找到,立即返回
- 若找不到,返回" "
-
若出现了+ - . 等特殊符号怎么办?
$(xxxScope["属性名"])
<%@page import="com.study.bean.User"%> <%@page import="java.util.HashMap"%> <%@page import="java.util.Map"%> <%@page import="java.util.List"%> <%@page import="java.util.ArrayList"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>获取复杂数据</title> </head> <body> <% //定义一个数组 String[] strs = new String[]{"aa","bb","cc"}; request.setAttribute("strs", strs); //定义一个list List list = new ArrayList(); list.add("AA"); list.add("BB"); list.add("CC"); request.setAttribute("list", list); //定义一个map集合 Map<String,String> map = new HashMap<String,String>(); map.put("xx", "xx"); map.put("yy", "yy"); map.put("zz", "zz"); request.setAttribute("map", map); //定义一个bean User user = new User("zhangsan","123"); request.setAttribute("user", user); //定义一个带特殊符号的字符串 request.setAttribute("hello.world", "hw"); %> 获取数组中的数据 老方式:<%= ((String[])request.getAttribute("strs"))[1] %><br> el方式:${ strs[0] } <hr> 获取list中的数据 老方式:<%=((List)request.getAttribute("list")).get(2) %><br> el方式:${ list[2] } <hr> 获取map中的数据 老方式:<%=((Map)request.getAttribute("map")).get("zz") %><br> el方式:${ map.zz } <hr> 获取bean中的数据 老方式:<%=((User)request.getAttribute("user")).getUsername() %><br> el方式:${ user.username } <hr> 找不到属性怎么办?返回" " ${ ffff } <hr> 若属性中有特殊符号则加上中括号<br> ${ requestScope["hello.world"] } </body> </html>
4. 执行运算
-
算术运算:只能计算数字或者是字符串形式数字
-
关系运算
-
逻辑运算
-
特殊运算
-
empty:是否为null或者空字符串
-
三元运算
<%@page import="java.util.List"%> <%@page import="java.util.ArrayList"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <% request.setAttribute("i", 3); request.setAttribute("j", 7); request.setAttribute("q", "9"); request.setAttribute("k", "k"); //创建一个空list List list = new ArrayList(); request.setAttribute("", list); //创建一个数组 String[] strs = null; request.setAttribute("strs", strs); %> ${ i+j } <hr> ${ i+q } <hr> 不能算<%-- ${ i+k } --%> <hr> ${ empty list } <hr> ${ empty strs } <hr> EL中的三元运算 ${ 1==1?"asd":"dsa" }; </body> </html>
8.1.5 el表达式中的内置对象
- pageScope
- requestScope
- sessionScope
- applicationScope
- param:表示保存了所有请求参数的Map对象【对于多值属性,只能返回第一个值】
- paramValues:表示一个保存了所有请求参数的Map对象,它对于某个请求参数,返回的是一个String[]
- header:表示一个保存了所有http请求头字段的Map对象
- headerValues:表示保存了所有http请求头字段的Map对象,他对于某个请求参数,返回的是一个string[]
- initParam:表示一个保存了所有web应用初始化参数的map对象
- cookie:表示一个保存了所有cookie的Map对象
- pageContext:对应于JSP页面中的pageContext对象
${ pageContext.request.contextPath }
:在jsp页面中动态获取项目动态路径的方法
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
${ param.username }
<hr>
${ paramValues }<br>
${ paramValues.username[0] }<br>
${ paramValues.hobby[1] }
<hr>
${ header }
<br><br>
${ header["user-agent"] }
<hr>
${ headerValues }<br><br>
${ headerValues["user-agent"][0] }
<hr>
${ cookie.JSESSION.value }
<hr>
获取当前项目的动态路径---
${ pageContext.request.contextPath }
<!-- 通过EL的对象pageContext,来获取其他三个域对象,
这里获取request对象,request有getContextPath方法 -->
</body>
</html>
8.2 JSTL标签
8.2.1 JSTL的概念
JSTL是一个不断完善的开放源代码的JSP标签库,是由apache维护
8.2.2 JSTL的作用
减少页面的java代码量
8.2.3 JSTL的使用步骤
-
导入jar包
-
在页面上导入标签库:
<%@taglib prefix="" uri=""%>
prefix:前缀
uri:需要的库
8.2.4 JSTL分类
1. core:核心
- c:out
- 相当于out.print
- <c:out value=“tom”/>
- c:set
- 下面式子将uname和tom以键值对的形式存储在session中
- <c:set var=“uname” value=“tom” scope=“session”/>
- c:remove
- 下面式子把session范围中的uname去除掉
- <c:remove var=“uname” scope=“session”/>
- c:if
<c:if test=“条件(EL表达式)” [var=“给之前的表达式的结果起名字”][scope=“将结果保存到一个域中,默认page”]>具体的实现</c:if>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
int i=0;
request.setAttribute("i", i);
pageContext.setAttribute("flag", "111");
%>
<c:if test="${ i>4 }">
i是大于四的
</c:if>
<c:if test="${ i<4 }" var="flag" scope="request">
i是小于四的
${ flag }
</c:if>
</body>
</html>
- c:forEach
-
基础用法
<c:forEach begin=“开始的值” end=“结束的值” step=“步长” var=“给当前的这个值起名字”> ${变量名称} </c:forEach>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib prefix="x" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <x:forEach begin="1" end="10" step="1" var="i"> ${ i } </x:forEach> <hr> <x:forEach begin="1" end="20" step="2" var="j"> ${ j } </x:forEach> </body> </html>
-
高级用法
- 遍历list
<c:forEach items=“${ list }” var=“str” varStatus=“vs” >
第 ${ vs.count } 个元素为 ${ str } ,索引为 ${ vs.index }
</c:forEach> - 遍历map
<c:forEach items=“${map}” var=“en”>
${ en.key }–${ en.value }
</c:forEach>
- 遍历list
-
- fmt:国际化(格式化)【基本不用了】
- sql:和sql相关【基本不用了】
- xml:和xml相关【基本不用了】
- function:函数【基本不用了】
九、Filter过滤器
9.1 filter的概念
servlet2.3之后增加的新功能,运行在服务器端的程序,先于之相关的servlet或者jsp页面之前运行
9.2 filter作用
过滤请求与响应
9.3 应用场景
自动登录、统一编码、过滤一些特殊符号或者敏感词
9.4 入门程序
- 编写一个类,实现filter接口,重写所有方法
- 编写web.xml配置文件 —— 注册filter,绑定路径
package com.study.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class Demo1Filter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
}
@Override
public void destroy() {
}
}
<filter>
<display-name>Demo1Filter</display-name>
<filter-name>Demo1Filter</filter-name>
<filter-class>com.study.filter.Demo1Filter</filter-class>
</filter>
<filter-mapping>
<filter-name>Demo1Filter</filter-name>
<url-pattern>/demo1</url-pattern>
</filter-mapping>
9.5 filter方法
init(FilterConfig)
初始化doFilter(ServletRequest req,ServeltResponse resp,FilterChain chain)
执行过滤的方法
必须执行chain.dofilter(request,response)
,才能放行请求,然后产生响应destory()
销毁
package com.study.filterLifeTime;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class Demo3Filter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("init");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("doFilter");
//放行
chain.doFilter(request, response);
}
@Override
public void destroy() {
System.out.println("destory");
}
}
9.6 filter生命周期
- filter也是单实例多线程的
- 在项目启动的时候,服务器创建filter对象,调用init方法实现初始化操作
- 每当请求来的时候,服务器获取一个线程,执行doFilter方法,实现过滤的逻辑
- 当服务器移除filter的时候,或者服务器正常关闭的时候,服务器调用destory方法,实现销毁操作
9.7 filter的url-pattern配置
- 完全匹配【精确路径匹配】:以"/"开始 —— 例如/demo1 /demo2 /aa/bb/demo3
- 目录匹配【最长路径匹配】:以"/“开始,以” * "结束 —— 例如/aa/* /*
- 后缀名匹配:以"“开始 —— 例如”.jsp" “*.html”
9.8 filterChain:过滤链
- 多个filter组合在一起
- 执行顺序:多个filter的执行顺序是由web.xml中filter-mapping的位置决定的,当一个filter收到请求的时候,调用
chain.doFilter
才可以访问下一个匹配的filter,若当前的filter是最后一个filter,调用chain.doFilter
才能访问目标资源
9.9 filter-mapping中的子标签
- servlet-name:指定具体过滤哪个servlet
- dispatch:指定过滤哪种方式过来的请求
- 参数有:
- REQUEST:默认值,只过滤从浏览器发送过来的请求
- FORWARD:只过滤请求转发过来的请求
- INCLUDE:只过滤包含过来的请求
- ERROR:只过滤错误过来的请求
- 参数有:
9.10 全局统一错误页面
<error-page>
<error-code>404</error-code>
<location>/404.jsp</location>
</error-page>
9.11 filterConfig
- 获取filter名称
- 获取filter的初始化参数
- 获取filter所有初始化名称
- 获取上下文
package com.study.filterConfig;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class Demo8Filter implements Filter {
FilterConfig fc=null;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
fc=filterConfig;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("Demo8Filter过滤到请求");
//获取filter的名称
String filterName = fc.getFilterName();
System.out.println(filterName);
//获取filter的初始化参数
String initParameter = fc.getInitParameter("db");
System.out.println(initParameter);
//获取filter所有的初始化名称
Enumeration<String> initParameterNames = fc.getInitParameterNames();
while(initParameterNames.hasMoreElements()) {
String string = (String)initParameterNames.nextElement();
System.out.println(string+":"+fc.getInitParameter(string));
}
//获取filter上下文对象
ServletContext servletContext = fc.getServletContext();
System.out.println(servletContext);
//放行
chain.doFilter(request, response);
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}
十、Listener监听器
10.1 listener监听器的概念
监听器其实就是一个实现特定接口的普通java类程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法立即被执行
10.2 listener监听器的作用
监听JavaWeb:ServletContext,request,HttpSession
10.3 listener监听器的编写步骤
- 编写一个类—实现监听器接口,重写方法
- 编写配置文件(大部分需要)—— 注册listener
10.4 listener监听器的分类
10.4.1 监听三个对象的创建和销毁
- ServletContextListener
- 创建:服务器启动时候,为每一个项目创建一个
- 销毁:项目移除的时候,或者服务器关闭的时候
- ServletRequestListener
- 创建:请求来的时候
- 销毁:生成响应的时候
- HttpSessionListener
- 创建:java中第一次调用request.getSession()
Jsp中认为第一次访问jsp页面的时候 - 销毁:
1.服务器非正常关闭
2.超时
3.手动销毁
- 创建:java中第一次调用request.getSession()
10.4.2 监听三个对象的属性变化【添加、替换、删除】
- ServletContextAttributeListener
- ServletRequestAttributeListener
- HttpSessionAttributeLListener
- 注意:
- public Object getValue():
- 如果添加了属性,则这是属性的值
- 如果移除了属性,则这是被移除的属性的值
- 如果替换了属性,则这是原来的值
10.4.3 监听JavaBean在session中的状态变化【不需要配置配置文件】
- HttpSessionBindingListener(解绑和绑定)
- 绑定:JavaBean放入到session
- 解绑:JavaBean从session中移除
- HttpSessionActivationListener(钝化和活化)
- 钝化:把session中的JavaBean序列化到磁盘中
- 活化:JavaBean从磁盘中把数据读取回session
- 注意:只需要JavaBean实现接口即可,不需要配置文件【需要实现序列化接口】
十一、Ajax异步请求
11.1Ajax的概念
异步JavaScript和XML,即使用JS语言域服务器进行异步交互,传输的数据为XML
11.2 Ajax的应用场景
- 检测用户名是否可用
- 搜索下拉展示
- 动态加载项目
11.3 Ajax的优缺点
- 优点
AJAX无需刷新整个页面,因为服务器响应内容不再是整个页面,而是页面中的局部,所以ajax性能高 - 缺点
- AJAX虽然提高了用户体验,但无形中向服务器发送的请求增多了,导致服务器压力增大
- 因为AJAX是在浏览器中使用JS技术完成的,所以还需要处理刘浏览器兼容性问题
11.4 js中ajax的使用
11.4.1 开发步骤
- 获取核心对象(XMLHttpRequest)
- 确定请求方式和请求路径
- 发送请求
- 编写回调函数
11.4.2 Ajax中的API
- 获取xmlHttpRequest对象
var xmlhttp;
if(window.XMLHttpRequest){
xmlhttp=new XMLHttpRequest(); //IE7+,Firefox,Chrome,Opera,Safari
}else{
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); //IE5,IE6
}
- 常用方法
open(请求的方式,请求的路径,[是否异步]) ------确定请求的方式和路径
send([post请求的参数]) ------发送请求 - 常用属性
- onreadystatechange ------监测XMLHttpRequest对象状态的变化
- readyState ------XMLttpRequest对象状态
- 0:对象已创建
- 1:对象调用了open
- 2:对象调用了send
- 3:部分已完成
- 4:响应已完成
- status ------响应状态码
- 200:“OK”
- 404:未找到页面
- responseText ------响应回来的内容
- 注意:若post请求参数,必须设置请求参数的mime类型
xmlhttp.setRequestHeader("content-type","application/x-www-form-urlencoded");
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<button id="btn1" onclick="getAjax()">js-ajax-get</button>
<button id="btn2" onclick="postAjax()">js-ajax-post</button>
</body>
<script>
function getAjax(){
//向服务器发送get请求
//获取xmlHttprequest对象
var xmlhttp;
if(window.XMLHttpRequest){
//code for IE7+,Firefox,Chrome,Opera,Safari
xmlhttp=new XMLHttpRequest();
}else{
//code for IE5,IE6
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
//确定请求方式和请求路径
xmlhttp.open("get","${pageContext.request.contextPath}/demo1?username=zs");
//发送请求
xmlhttp.send();
//接受结果(回调函数)
xmlhttp.onreadystatechange = function(){
if(xmlhttp.readyState==4&&xmlhttp.status==200){
alert(xmlhttp.responseText);
}
}
}
function postAjax(){
//向服务器发送post请求
//获取xmlHttprequest对象
var xmlhttp;
if(window.XMLHttpRequest){
//code for IE7+,Firefox,Chrome,Opera,Safari
xmlhttp=new XMLHttpRequest();
}else{
//code for IE5,IE6
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
//确定请求方式和请求路径
xmlhttp.open("post","${pageContext.request.contextPath}/demo1");
//发送请求
xmlhttp.setRequestHeader("content-type","application/x-www-form-urlencoded");
xmlhttp.send("username=张三");
//接受结果(回调函数)
xmlhttp.onreadystatechange = function(){
if(xmlhttp.readyState==4&&xmlhttp.status==200){
alert(xmlhttp.responseText);
}
}
}
</script>
</html>
11.5 jQuery中的Ajax使用
$.get(url,params,function(obj){},type);
—— 发送get请求$.post(url,params,function(obj){},type);
——发送post请求- url:请求的路径
- params:请求参数
- 格式一:key=value
- 格式二:json格式
- fn:成功之后的回调函数,obj就是服务器返回给浏览器的内容
- type:返回数据的格式
$.ajax(选项)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<button id="btn1">jquery-ajax-get</button><br>
<button id="btn2">jquery-ajax-post</button>
</body>
<script src="${pageContext.request.contextPath}/js/jquery-1.12.4.js"></script>
<script>
//jquery的ajax-get
$("#btn1").click(function(){
$.get("${pageContext.request.contextPath}/demo1","username=zhangsan",function(obj){
alert(obj);
});
});
//jquery的ajax-post
$("#btn2").click(function(){
$.post("${pageContext.request.contextPath}/demo1","username=zhangsan",function(obj){
alert(obj);
});
});
</script>
</html>
十二、三层架构
12.1 三层架构
- 表示层(视图层):主要作用为数据显示或者后台进行交互,里面是HTML代码或JSP页面
- 业务逻辑层(业务层):主要用于处理业务逻辑
- 数据层(持久层):主要是对非原始数据的操作,与数据库交互
12.2 两层架构
三层架构理念相对复杂,而两层架构更加简练。
- 表示层:同三层架构的表示层
- 业务和数据层:将业务层和数据层合成一层
12.3 MVC模式+三层架构
十三、DAO模式
13.1 什么是DAO模式
- DAO模式的全称为Data Access Object(数据访问对象),这是一种夹在业务逻辑与数据库资源中间的一种数据库技术
- 把数据库层对数据库进行操作的代码全部封装到DAO类中,这个类就是专门用来访问数据库进行数据操作的
13.2 DAO模式的组成
-
数据库工具类 —— DataBase.java
这个类主要功能是连接数据库并获得连接对象,抽象出增删改函数,以及关闭数据库等。
package com.study.utils; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class DataBase { public static String driver="com.mysql.jdbc.Driver"; public static String url="jdbc:mysql://localhost:3306/librarymanage?characterEncoding=utf-8"; public static String username="root"; public static String password="123"; static Connection conn=null; PreparedStatement ps=null; static Statement sm=null; protected ResultSet rs=null; public DataBase() { //1.加载驱动 try { Class.forName(driver); //2.建立连接 if(conn==null || conn.isClosed()) conn=DriverManager.getConnection(url, username, password); //3.执行sql sm=conn.createStatement(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } /* * 查询函数 */ public ResultSet getResultSet(String sql,Object[] param) { try { ps=conn.prepareStatement(sql); if(param!=null) { for(int i=0;i<param.length;i++) { ps.setObject(i+1, param[i]); } } rs = ps.executeQuery(); } catch (SQLException e) { e.printStackTrace(); } return rs; } /* * 增删改函数 */ public void executeDML(String sql,Object[] param) { try { ps=conn.prepareStatement(sql); if(param!=null) { for(int i=0;i<param.length;i++) ps.setObject(i+1, param[i]); } ps.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } } //关闭资源函数 public void close() { try { if(rs!=null) rs.close(); if(sm!=null) sm.close(); if(conn!=null) conn.close(); } catch (SQLException e) { e.printStackTrace(); } } }
-
实体类 —— Entity.java
这个类是一个包含属性和表中字段完全对应的类,类中有setter和getter方法用来设置和获取该类中的属性。
public class Entity { private int BOOKID; private String LENDDATE; private String RETURNDATE; private String READER; public int getBOOKID() { return BOOKID; } public void setBOOKID(int bOOKID) { BOOKID = bOOKID; } public String getLENDDATE() { return LENDDATE; } public void setLENDDATE(String lENDDATE) { LENDDATE = lENDDATE; } public String getRETURNDATE() { return RETURNDATE; } public void setRETURNDATE(String rETURNDATE) { RETURNDATE = rETURNDATE; } public String getREADER() { return READER; } public void setREADER(String rEADER) { READER = rEADER; } @Override public String toString() { return "Entity [BOOKID=" + BOOKID + ", LENDDATE=" + LENDDATE + ", RETURNDATE=" + RETURNDATE + ", READER=" + READER + "]"; } }
-
DAO接口 —— xxxDao.java
DAO接口中封装了对该表进行的数据库操作,例如增删改查。
package com.hkd.exam1; import java.sql.ResultSet; public interface ReadinfoDao { //显示所有信息的方法 public ResultSet ShowAllInfo(); //根据图书编号显示所有信息的方法 public ResultSet ShowAllInfoById(int id); }
-
DAO接口实现类 —— xxxDaoImpl.java
该类需继承数据库工具类DataBase,并实现DAO接口,实现接口中的各个函数。
package com.hkd.exam1; import java.sql.ResultSet; public class ReaderindoDaoImpl extends DataBase implements ReadinfoDao{ @Override public ResultSet ShowAllInfo() { String sql = "select * from readerinfo"; ResultSet res = this.getResultSet(sql,null); return res; } @Override public ResultSet ShowAllInfoById(int id) { String sql = "select * from readerinfo where BOOKID=?"; Object[] param = {id}; ResultSet resulet = this.getResultSet(sql, param); return resulet; } }