一、Servlet生命周期(即运行过程)

(1)初始阶段,调用init()方法

(2)响应客户请求阶段,调用service()方法。由service()方法根据提交方式不同执行doGet()或doPost()方法,其中service()方法判断了到底执行doGet()还是doPost()方法。

(3)终止阶段,调用destroy()方法。(服务器关闭)

Servlet生命周期中需要注意一下几点:

1)Servlet是长期贮存内存中的,当Servlet实例加载后,Servlet对象是长期保存在服务器内存中的。

2)Servlet被装载后,Web容器创建一个Servlet实例并且调用Servlet的init()方法进行初始化。在Servlet的整个生命周期内,init()方法只被调用一次。而service()方法在每次客户端请求的时候都会调用。

3)HttpServlet中有两个Service()方法,HttpServlet中两个service()方法的区别:


  public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {
// TODO Auto-generated method stub
super.service(arg0, arg1);
}
  protected void service(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException {
// TODO Auto-generated method stub
super.service(arg0, arg1);
}

A:其中第一种方法是由tomcat自动调用,它将接收的客户端请求转交给HttpServlet中的第二个service()方法,此保护类行的service()方法再把请求分发给doPost()、doGet()方法进行下一步处理。

B:HttpServlet类继承自GenericServlet,HttpServletRequest和HttpServletResponse分别继承自ServletRequest,ServletResponse,简单说,就是第一个方法是HttpServlet的,第二个方法是GenericServlet的,HttpServlet因为继承GenericServlet,所以继承了这个service()方法。

二、Servlet与九大内置对象

Servlet中如何获取JSP的九大内置对象

JSP对象 怎样获得 作用域
out response.getWriter() page
request service方法中的request参数 request
response service方法中的response参数 response
session request.getSession()函数 session
application this.getServletContext()函数 Application
exception new Throwable() page
page this page
pageContext new pageContext() page
config this.getSerletConfig()函数 page

将这九大对象分为

1、out对象和session对象

out对象是通过service()中的response的getWriter()方法获得,而response.getWriter()的返回的是PrintWriter类对象,而out对象是JspWriter类的实例,我们不妨对比一下两个类的方法。不难发现两个类都主要以print()方法为主。

session对象是通过service()中的request的getSession()方法获得,返回的对象就是对应了session实例。

代码示例(以out对象举例):

index.jsp代码

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head> <body>
<a href="Servlets/ServletDemo1"><h1>测试servletDemo1 servlet</h1></a>
</body>
</html>

servletDemo1.java代码

package Servlets;

import java.io.IOException;
import java.io.PrintWriter;import javax.el.ELContext;
import javax.servlet.Servlet;import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import javax.servlet.jsp.JspWriter;public class ServletDemo1 extends HttpServlet { @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//resp.setHeader("Content-type", "text/html;charset=gbk");
//resp.setCharacterEncoding("gbk");
System.out.println("测试ServletDemo1 doGet方法成功!");
PrintWriter out=resp.getWriter();
StringBuffer bf=new StringBuffer("<h1>这里是ServletDemo1 servlet!</h1>");
out.print(bf);
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}

运行结果截图:

分析:绿色背景的代码实现了在servlet中获取out对象,并进行相应操作。但是我们发现通过out对象打印输出的汉字出现了乱码。

关于Servlet中的printWriter中文乱码的问题:

先分析原因:首先我们应该了解servlet中的两个参数request和response分别用来存储客户端发送的请求、储存服务器端返回的数据,而不管是储存还是取出都涉及到重新编码解析的问题,在这个过程如果存储和取出时使用的编码方式不同,势必会导致乱码。printWriter对象是通过response参数调用getWriter()函数获得的,作为响应的信息会在响应存储的时候进行编码的相关操作,而sun公司使用的码表是ISO8859-1之类的码表,而当浏览器显示响应结果时,也会去查码表,而中文的windows下的浏览器使用的一般是gbk或者gb2312,这样两次编码就不同。

解决方法:(两种)

(1)doxxx()方法中添加:response.setCharacterEncoding("gbk");

(2)doxxx()方法中添加:response.setHeader("content-type","text/html;charset=gbk");

上面代码中蓝色部分就是解决方法示例:

运行之后的结果截图:

当然,通过request的getSession()方法获得的session对象对于中文字符也可能出现乱码的问题,我们也可以通过添加:request.setCharaterEncoding("utf-8/gbk");

2、request对象和response对象

request和response对象都是通过service()方法传进的参数获得的,并且这两个参数直接被传入doGet()和doPost()的参数中。

  public void service(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException {
// TODO Auto-generated method stub
super.service(arg0, arg1);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}

3、page对象、config对象和application对象

page对象代表了JSP转译的servlet实例对象,而在继承HttpServlet类的自定义Servlet类中,其当前实例对象在类中的表达,很明显使用this。所以page对象对应this完美。

config对象其实是通过自定义Servlet类的getSerletConfig()方法获取,自定义Servlet类继承自HttpServlet类,而getServletConfig()方法是HttpServlet类继承自其父类GenericServlet类而来,返回类型为ServletConfig对应了config的类。既然是调用其自定义Servlet类本身的getServletConfig()方法,则调用的写法应该是:this.getServletConfig();

application对象其实是通过自定义Servlet类的getSerletcontext()方法获取,自定义Servlet类继承自HttpServlet类,而getServletContext()方法是HttpServlet类继承自其父类GenericServlet类而来,返回类型为ServletContext对应了application的类。既然是调用其自定义Servlet类本身的getSerletcontext()方法,则调用的写法应该是:this.getSerletcontext()。

代码演示:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head> <body>
<%
application.setAttribute("name", "小帅哥");
%>
<a href="Servlets/ServletDemo1"><h1>测试servletDemo1 servlet</h1></a>
</body>
</html>
package Servlets;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;
import java.util.Enumeration; import javax.el.ELContext;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.el.ExpressionEvaluator;
import javax.servlet.jsp.el.VariableResolver; public class ServletDemo1 extends HttpServlet { @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setHeader("content-type", "text/html;charset=gbk");
ServletConfig sc=this.getServletConfig();
Enumeration e=sc.getInitParameterNames();
ServletContext application= this.getServletContext();
String name=(String)application.getAttribute("name");
PrintWriter out=resp.getWriter();
out.print("<h2>name:"+name+"</h2>");
out.print("<h1>初始化的参数名:</h1>");
if(e.hasMoreElements()){
out.print(e.nextElement()+" ");
}else{
out.print("该Servlet没有初始化参数!");
}
//req.getRequestDispatcher("/index1.jsp").forward(req, resp);
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}

运行结果截图:

4、pageContext对象和exception对象

pageContex是通过在Servlet中通过构造起自己构造的,构造的方法是:PageContext pc=new pageContext(),但是pageContext类是抽象类,通过直接new的方式可以获得pageContext对象,但是其中的方法需要覆盖重写才有意义,而重写的,里面的方法的实现大多都需要借助于其他内置对象,pageContext是一个集大成者的内置对象,他的出现就是能实现,一个内置对象能够访问其他内置对象。

PageContext pc=new PageContext() {

        @Override
public void setAttribute(String arg0, Object arg1, int arg2) {
// TODO Auto-generated method stub } @Override
public void setAttribute(String arg0, Object arg1) {
// TODO Auto-generated method stub } @Override
public void removeAttribute(String arg0, int arg1) {
// TODO Auto-generated method stub } @Override
public void removeAttribute(String arg0) {
// TODO Auto-generated method stub } @Override
public VariableResolver getVariableResolver() {
// TODO Auto-generated method stub
return null;
} @Override
public JspWriter getOut() {
// TODO Auto-generated method stub
return null;
} @Override
public ExpressionEvaluator getExpressionEvaluator() {
// TODO Auto-generated method stub
return null;
} @Override
public ELContext getELContext() {
// TODO Auto-generated method stub
return null;
} @Override
public int getAttributesScope(String arg0) {
// TODO Auto-generated method stub
return 0;
} @Override
public Enumeration<String> getAttributeNamesInScope(int arg0) {
// TODO Auto-generated method stub
return null;
} @Override
public Object getAttribute(String arg0, int arg1) {
// TODO Auto-generated method stub
return null;
} @Override
public Object getAttribute(String arg0) {
// TODO Auto-generated method stub
return null;
} @Override
public Object findAttribute(String arg0) {
// TODO Auto-generated method stub
return null;
} @Override
public void release() {
// TODO Auto-generated method stub } @Override
public void initialize(Servlet arg0, ServletRequest arg1, ServletResponse arg2, String arg3, boolean arg4, int arg5,
boolean arg6) throws IOException, IllegalStateException, IllegalArgumentException {
// TODO Auto-generated method stub } @Override
public void include(String arg0, boolean arg1) throws ServletException, IOException {
// TODO Auto-generated method stub } @Override
public void include(String arg0) throws ServletException, IOException {
// TODO Auto-generated method stub } @Override
public void handlePageException(Throwable arg0) throws ServletException, IOException {
// TODO Auto-generated method stub } @Override
public void handlePageException(Exception arg0) throws ServletException, IOException {
// TODO Auto-generated method stub } @Override
public HttpSession getSession() {
// TODO Auto-generated method stub
return null;
} @Override
public ServletContext getServletContext() {
// TODO Auto-generated method stub
return null;
} @Override
public ServletConfig getServletConfig() {
// TODO Auto-generated method stub
return null;
} @Override
public ServletResponse getResponse() {
// TODO Auto-generated method stub
return null;
} @Override
public ServletRequest getRequest() {
// TODO Auto-generated method stub
return null;
} @Override
public Object getPage() {
// TODO Auto-generated method stub
return null;
} @Override
public Exception getException() {
// TODO Auto-generated method stub
return null;
} @Override
public void forward(String arg0) throws ServletException, IOException {
// TODO Auto-generated method stub }
};

exception对象是一个异常对象,当一个JSP页面发生异常时就会产生这个对象,这个对象在Servlet中对应着Throwable类,调用的方法是:Throwable tb=new Throwable();而Throwable类的子类有Exception。几乎不使用这个。

三、Servlet路径跳转(假设在index.jsp页面进行跳转)

Servlet中有两种方式获得转发对象(RequestDispatcher):一种是通过HttpServletRequest的getRwquestDispatcher()方法获得,一种是通过ServletContext的getRequestDispatcher()方法获得。重定向的方法只有一种:HttpServletResponse的sendRedirect()方法。这三种方法的参数都是一个URL形式的字符串,但在使用相对路径或绝对路径上有所区别。

1、HttpServletResponse.sendRedirect(String):

(1)相对路径:

response.sendRedirect("index1.jsp");

(2)绝对路径:

response.sendRedirect("/index1.jsp");  其中"/"表示是项目根目录

response.sendRedirect(request.getContextPath()+"/index.jsp");  request.getContextPath()获得项目的根目录路径

(3)其他Web应用:

response.sendRedirect("http://www.baidu.com");

2、HttpServletRequest.getRequestDispatcher(String)

(1)相对路径:

HttpServletRequest.getRequestDispacher("../index1.jsp").forward(request,response);  其中“../”表明返回上层目录

HttpServletRequest.getRequestDispacher("index1.jsp").forward(request,response);

(2)绝对路径:

HttpServletRequest.getRequestDispacher("/index1.jsp").forward(request,response);  其中“/”表示根目录路径

HttpServletRequest.getRequestDispacher(request.getContextPath()+"/index1.jsp").forward(request,response);      request.getContextPath()获得项目的根目录路径

3、ServletContext.getRequestDispatcher():

(1)绝对路径:

ServletContext.getRequestDispatcher("/index1.jsp").forward(request,response);  其中“/”表示根目录路径

注意:HttpServletRequest.getRequestDispatcher(String)和ServletContext.getRequestDispatcher()的区别,其中ServletContext.getRequestDispatcher():只能使用绝对路径传值URL,且绝对路径必须是以"/"开头,其他都不行。而三种页面跳转只有HttpServletResponse.sendRedirect(String)可以实现非项目目录的跳转。

Servlet学习应该注意的几点的更多相关文章

  1. JSP&Servlet学习手册

    JSP&Servlet学习手册 沙琪玛 书 目录 JSP 指令... 3 书写方式... 3 指令列表... 3 JSP 内置对象... 3 内置对象特点... 3 常用内置对象... 3 o ...

  2. Servlet 学习笔记

    Servlet 运行在服务器上的 java 类: Servlet 容器为 javaWeb 应用提供运行时环境,负责管理 servlet 和 jsp 生命周期,以及管理他们的共享数据. 现在我们知道了 ...

  3. Servlet学习:(三)Servlet3.0 上传文件

    转: Servlet学习:(三)Servlet3.0 上传文件 2018年08月03日 11:57:58 iDark_CSDN 阅读数:362   一.注意事项 客户端(浏览器) 表单的提交方法必须是 ...

  4. Servlet学习(九)——request

    request运行流程在Servlet学习(四)——response已介绍,不再赘述 1.通过抓包工具获取Http请求 因为request代表请求,所以我们可以通过该对象分别获得Http请求的请求行, ...

  5. # jsp及servlet学习笔记

    目录 jsp及servlet学习笔记 JSP(Java Server Page Java服务端网页) 指令和动作: servlet(小服务程序) jsp及servlet学习笔记 JSP(Java Se ...

  6. Servlet学习笔记(四)

    目录 Servlet学习笔记(四) 一.会话技术Cookie.session 1. 什么是会话技术? 2. 会话技术有什么用? 3. Cookie 3.1 什么是Cookie? 3.2 使用Cooki ...

  7. Servlet学习笔记(三)

    目录 Servlet学习笔记(三) 一.HTTP协议 1.请求:客户端发送欸服务器端的数据 2.响应:服务器端发送给客户端的数据 3.响应状态码 二.Response对象 1.Response设置响应 ...

  8. Servlet学习笔记(二)

    目录 Servlet学习笔记(二) Request对象 1.request和response对象: 2.request对象继承体系结构: 3.什么是HttpServletRequest ? 4.Htt ...

  9. servlet 学习(二)

    一.ServletConfig讲解 1.1.配置Servlet初始化参数 在Servlet的配置文件web.xml中,可以使用一个或多个<init-param>标签为servlet配置一些 ...

  10. JavaWeb学习总结-04 Servlet 学习和使用

    一 Servlet 1 Servlet概念 Servlet时运行在服务器端的Java程序. Servlet的框架核心是 javax.servlet.Servlet 接口. 所有自定义的Servlet都 ...

随机推荐

  1. PyQt4简单小demo

    #coding=utf-8 import sys from PyQt4.QtCore import * from PyQt4.QtGui import * class FontPropertiesDl ...

  2. 【javascript】谈谈HTML5 ——HTML兽进化, H5兽!

    作为一名Web开发者,可能你并没有对这个“H5”这个字眼投入太多的关注,但实际上它早已不知不觉进入到你的开发中,并且总有一天会让你不得不正视它,了解它并运用它   打个比方:<海贼王>中的 ...

  3. Tomcat session集群

    author:JevonWei 版权声明:原创作品 环境 tomcatA 172.16.253.108 tomcatB 172.16.253.105 代理服务器 172.16.253.191 Tomc ...

  4. 从送外卖到建站售主机还有共享自行车说起-2017年8月江西IDC排行榜与发展报告

    曾几何时,送外卖,这样的"低技术含量"工作,很难被互联网公司看上,直到百度将其当作连接终端用户与大数据的管道. 同样,销售主机域名和建站业务,本也是"微小体量" ...

  5. Flask04 后台获取请求数据、视图函数返回类型、前台接受响应数据

    1 后台获取请求数据 1.1 提出问题 前台发送请求的方式有哪些 后台如何获取这些请求的参数 1.2 前台发送请求的方式 GET.POST.AJAX 点睛:如果不指定请求方式,浏览器默认使用GET请求 ...

  6. Nand Flash驱动(实现初始化以及读操作)

    简单制作一个Nand Flash驱动(只需要初始化Flash以及读Flash) 打开2440芯片手册,K9F2G08U0M芯片手册(因为2440中Nand Flash是用的256MB(2Gb)内存,8 ...

  7. 为什么可以通过URL来调起APP - URL Scheme和Intent

    在手机浏览器中可以通过URL调起APP是不是很神奇?这篇文章就告诉你为什么. URL Scheme 先从前端能接触到的URL Scheme分析一下 丢wiki:https://en.wikipedia ...

  8. JQuery实用技巧--学会你也是大神(1)——插件的制作技巧

      前  言 JRedu 学习之前,首先我们需要知道什么是JQuery? JQuery是一个优秀的javascript框架. JQuery是继Prototype之后又一个优秀的Javascript框架 ...

  9. 介绍call和apply

    function add(a, b) { alert(a + b); } function sub(a, b) { alert(a - b); } add.call(sub, 1,3); //4  传 ...

  10. 【Alpha】第四次Daily Scrum Meeting

    GIT 一.今日站立式会议照片 二.会议内容 1.采取老师提出的建议,考虑对送礼对象进行一个分类,这个在服务功能模块中完善. 2.回顾之前几次会议的内容,做一个小的总结,各抒己见,对每个人哪方面做得比 ...