1 创建Servlet类
创建一个普通类,继承javax.servlet.http.HttpServlet,重写doGet()和doPost()方法;
doGet() 接收一个来自客户端的GET请求
doPost() 接收一个来自客户端的POST请求
1.1 servlet对象是单例的
每一次请求到达服务器时,服务器(tomcat)会检查有没有目标对象(servlet对象),如果没有则创建,如果有,则拿来直接使用。
由于servlet是单例的,所有的用户共享的是一个对象,所以在servlet实现类中不建议定义成员变量,在高并发情况下Servlet是线程不安全的。
1.2 继承关系
父类 | Object | ||
子类 | GenericServlet | init() | 初始化 |
destory() | 销毁servlet对象 | ||
子类 | HttpServlet extends GenericServlet | service() | 接收HTTP请求,并根据请求方式,将请求转发给对应的doGet()和doPost()方法 |
doPost | 处理Get方式的HTTP请求 | ||
doGet() | 处理POST方式的HTTP请求 |
2 Servlet生命周期
2.1 servlet的生命周期
可以被定义为servlet对象从创建到销毁的整个过程:
- 在创建servlet对象时,通过调用init()方法进行初始化
- 通过service()方法来处理客户端的请求,根据请求方式的不同转发给doGet()或doPost()方法
- 停止服务时,通过调用destory()方法销毁servlet对象
- servlet对象被JVM垃圾回收器回收
2.2 示例
public class DefaultServlet extends HttpServlet {
//servlet生命周期
@Override
public void init() throws ServletException {
System.out.println("******servlet init******");
/*
* 初始化方法
* 1 只会调用一次;
* 2 在创建servlet对象时调用,在后续每次用户请求时不再调用。
*/
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//接收一个来自客户端的GET请求
//HttpServletRequest 接收客户端发送的请求报文
//HttpServletResponse 响应客户端的请求(给客户端返回数据)
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
//接收一个来自客户端的POST请求
}
/*
* service()方法,是执行实际业务任务的主要方法,由servlet容器调用service方法
* 作用:处理来自客户端的请求,并把格式化的响应写回给客户端
* 1 service()方法由容器调用;
* 2 service()方法会检查HTTP请求类型(GET/POST/PUT/DELETE等),然后根据请求类型的不同,调用对应的方法,如GET请求调用doGet()方法;
* 3 所以,不需要对service方法做任何修改,只需要根据客户端的请求类型来重写doGet()和doPost()方法;
*/
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("*****service*****");
super.service(req, res);
}
/*
* 销毁
* 1 destroy()方法只调用一次,在servlet对象生命周期结束时(如停止tomcat服务)被调用。
* 2 destroy()方法可以关闭数据库连接、停止后台线程、把cookie或者缓存写入硬盘以及其他清理活动
* 3 在调用destroy()方法后,servlet对象会被GC(垃圾回收)线程标记为被回收的资源。
*/
@Override
public void destroy() {
System.out.println("*****dead*****");
super.destroy();
}
}
3 请求与响应
3.1 HttpServletRequest请求
//设置请求编码
req.setCharacterEncoding("utf-8");
//获取请求参数
String name = req.getParameter("name");
//获取所有请求参数名的结果集
Enumeration<String> params = req.getParameterNames();
//遍历参数名结果集,获取所有参数值
//hasMoreElements判断参数名集合中是否有元素
while (params.hasMoreElements()) {
//nextElement获取下一个元素
String key = (String) params.nextElement();
System.out.print(key+":"+req.getParameter(key));
}
//向请求对象中添加参数
req.setAttribute("user_list", list);
3.2 HttpServletResponse响应
//设置响应数据的编码
resp.setCharacterEncoding("gb2312");
//创建字符输出流,向客户端响应数据
PrintWriter out = null;
out = resp.getWriter();
out.write("success");
out.flush();
if (out == null) {
out.close();
}
4 页面跳转方式:请求转发与重定向
4.1请求转发
req.getRequestDispatcher("/WEB-INF/page/show.jsp").forward(req, res);
4.2 重定向
res.sendRedirect("http://baidu.com");
或
res.sendRedirect("user?method=queryAll");
4.3 请求转发与重定向的区别
- 转发使用的是getRequestDispatcher()方法;重定向使用的是sendRedirect();
- 转发:浏览器URL的地址栏不变;重定向:浏览器URL的地址栏改变;
- 转发是服务器行为,重定向是客户端行为;
- 转发是浏览器只做了一次访问请求。重定向是浏览器做了至少两次的访问请求;
- 转发两次跳转之间传输的信息不会丢失,重定向两次跳转之间传输的信息会丢失(request范围)。
5 Session会话
//创建session会话
HttpSession session = req.getSession();
session.setMaxInactiveInterval(5);//设置session失效时间,单位秒s
//向session中添加信息
session.setAttribute("user_name", "张三");
session.setAttribute("addr", "中国,山东,青岛");
示例:
参考文档《4-2 JSP.docx》-2.3
5.1 session与cookie的区别
1.存储位置不同
通常情况
Cookie的数据信息存放在客户端浏览器上。
Session的数据信息存放在服务器内存中。
2.存储容量不同
通常情况
单个Cookie保存的数据≤4KB,一个站点最多保存20个Cookie。
对于Session并没有上限,但出于对服务器端的性能考虑,session内不要存放过多的东西,并设置session删除机制(有效期)
3.存取方式不同
Cookie中只能保管ASCll字符串,需要通过编码的方式存取Unicode字符或者二进制数据。运用Cookie难以实现存储略微复杂的信息
4.隐私策略不同
Cookie对客服端是可见的,别有用心的人可以分析放在本地的Cookie并伪造cookie信息发送非法请求,所以它是不安全的
5.有效期不同
开发可以通过设置Cookie的属性,达到Cookie长期有效的效果
由于Session依赖于名为JSESSIONID的cookie,而Cookie JSESSIONID的过期时间默认为-1,只需关闭窗口该Session就会失效,因而Session不能达到长期有效的效果,就算不依赖Cookie,运用URL地址重写也不能完成,因为假如设置Session的超过时间过长,服务器累计的Session就会越多,越容易导致内存溢出
6.服务器压力不同
Session是保管在服务端的,每个用户都会产生一个Session,假如并发访问的用户十分多,会产生十分多的Session,耗费大量的内存
Cookie是保管在客户端,不占用服务器资源,对于并发用户十分多的网站,cookie是很好的选择
7.浏览器支持不同
假如客户端浏览器不支持Cookie。
Cookie是需要客户端浏览器支持的。假如客户端禁用了Cookie,或者不支持Cookie,则会话跟踪会失效。关于WAP上的应用,常规的Cookie就派不上用场了。
运用Session需要使用URL地址重写的方式。一切用到Session程序的URL都要进行URL地址重写,否则Session会话跟踪还会失效。关于WAP应用来说,Session+URL地址重写或许是它唯一的选择。
假如客户端支持Cookie。
Cookie 既能够设为本浏览器窗口以及子窗口内有效(把过期时间设为−1),也能够设为一切窗口内有效(把过期时间设为某个大于0的整数)。
Session 只能在本窗口以及其子窗口内有效。假如两个浏览器窗口互不相干,它们将运用两个不同的Session。(IE8下不同窗口Session相干。)
8.跨域支持上的不同
Cookie 支持跨域名访问,例如,将 domain 属性设置为“.biaodianfu.com”,则以“.biaodianfu.com”为后缀的一切域名均能够访问该Cookie。跨域名Cookie如今被普遍用在网络中,例如,Google、Baidu、Sina等。
Session则不会支持跨域名访问。Session仅在它所在的域名内有效。
6 Cookie
7 ServletContext接口
8 Filter过滤器
8.1 定义
过滤器可以动态的拦截请求和响应,以修改或使用包含在请求或响应中的信息。
Filter过滤器可以实现以下目的:
- 在客户端的请求访问servlet之前,拦截这些请求,对用户请求进行预处理;
- 对HttpServletResponse进行后处理;
多个Filter的执行顺序与在web.xml配置文件中的配置顺序一致,一般把filter配置在所有的servlet之前。
8.2 代码示例
import java.io.IOException;
import java.io.PrintWriter;
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 FirstFilter implements Filter{
@Override
public void destroy() {
System.out.println("*****filter destory*****");
Filter.super.destroy();
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//init方法初始化filter对象,在程序启动时调用init()方法
//filterConfig读取配置文件的中的初始化属性
String site = filterConfig.getInitParameter("Site");
System.out.println("*****filter init "+site+"*****");
Filter.super.init(filterConfig);
}
//拦截请求,在servlet的doGet()/doPost()方法前执行
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("*****filter do*****");
String method = request.getParameter("method");
if (method == null || method == "") {
response.setCharacterEncoding("gb2312");
PrintWriter out = response.getWriter();
out.write("未指定method参数");
out.flush();
out.close();
return;
} else {
//放行请求
chain.doFilter(request, response);
}
}
}
8.3 web.xml配置Filter
<!-- 过滤器 -->
<filter>
<!-- 指定filter类的别名-->
<filter-name>first</filter-name>
<!-- 指定filter类的完整包路径 -->
<filter-class>filter.FirstFilter</filter-class>
<!-- 初始化参数,在init方法中用到 -->
<init-param>
<param-name>Site</param-name>
<param-value>hello world!</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>first</filter-name>
<!-- 指定filter的拦截路径 -->
<url-pattern>/comp</url-pattern>
</filter-mapping>
9 Listener监听器
9.1 定义
Javaweb中的监听器是用于监听web常见对象HttpServletRequest/HttpSession/ServletContext
作用:
1 监听web对象的创建与销毁
2 监听web对象属性的变化
3 监听session绑定javabean的操作
9.2 代码示例
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
public class MyListener implements ServletRequestListener{
//ServletRequestListener请求监听器
//监听请求销毁
@Override
public void requestDestroyed(ServletRequestEvent sre) {
// ServletRequestListener.super.requestDestroyed(sre);
System.out.println("***request has destroy***");
}
//监听请求创建
@Override
public void requestInitialized(ServletRequestEvent sre) {
System.out.println("***request has init***");
// ServletRequestListener.super.requestInitialized(sre);
}
}
9.3 web.xml配置listener
<!-- 监听器 -->
<listener>
<listener-class>listener.MyListener</listener-class>
</listener>
10 servlet、filter、listener各方法执行顺序
10.1 Filter过滤器和listener监听器的区别
filter:filter是一个可以复用的代码片段,可以用来转换HTTP请求、响应和头信息。Filter不像Servlet,它不能产生一个请求或者响应,它只是修改对某一资源的请求,或者修改到某一资源的响应。
listener:监听器,从字面上可以看出listener主要用来监听。通过listener可以监听web服务器中某一个执行动作,并根据其要求作出相应的响应。通俗的语言说就是在application,session,request三个对象创建消亡或者往其中添加修改删除属性时自动执行代码的功能组件。
11 WEB-INF目录简介
WEB-INF是Java的WEB应用的安全目录,客户端无法访问,只能通过服务端访问,从而实现了代码的安全。在WEB-INF中主要是系统运行的配置信息和环境。
主要有classes、config、lib文件夹和web.xml