一、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. Apache与Tomcat的关系和区别 -个人比较

    我们经常在用apache和tomcat等这些服务器,可是总感觉还是不清楚他们之间有什么关系,在用tomcat的时候总出现apache,总感到迷惑,到底谁是主谁是次,因此特意在网上查询了一些这方面的资料 ...

  2. tp下的memcached运用

    来源:http://blog.csdn.net/fudaoji/article/details/50722839   侵删 一.环境: lnmp开发服务器, memcached2.2.0,thinkp ...

  3. P问题、NP问题、NPC问题

    看师兄们的论文经常说一句这是个NP难问题,所以采用另外一种方法来代替(比如凸松弛,把l0范数的问题松弛为l1范数的问题来求解).然后搜索了相关知识,也还是没看太懂,把一些理论知识先贴上来,希望以后再接 ...

  4. HTML的基本标签

    整理一下这一周学习的一些知识. 首先是一些基本标签. <!DOCTYPE HTML><html> 文档类型声明: 让浏览器,按照html5的标准对代码进行解释与执行.文档类型声 ...

  5. LINUX服务器上新增用户名

    最近所里的机群停了,需要用老板的服务器跑程序,这里首先得在老板的服务器上新增一些用户名.新增用户名方法如下: 1.利用useradd添加用户名,并指定用户名目录.脚本解释器.用户名 sudo user ...

  6. poj 2762 强连通缩点+拓扑排序

    这题搞了好久,先是拓扑排序这里没想到,一开始自己傻乎乎的跑去找每层出度为1的点,然后才想到能用拓扑排序来弄. 拓扑排序的时候也弄了挺久的,拓扑排序用的也不多. 题意:给一个图求是否从对于任意两个点能从 ...

  7. JDBC(一)之细说JDBC

    Properties info = new Properties();//要参考数据库文档 info.setProperty("user", "root"); ...

  8. 转:jquery 父、子页面之间页面元素的获取,方法的调用

    一.jQuery 父.子页面之间页面元素的获取,方法的调用: 1. 父页面获取子页面元素: 格式:$("#iframe的ID").contents().find("#if ...

  9. 201521123083《Java程序设计》第11周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 上周这张图没理解完,继续 2. 书面作业 本次PTA作业题集多线程 1互斥访问与同步访问完成题集4-4(互斥访问) ...

  10. 201521123001《Java程序设计》第7周学习总结

    1. 本周学习总结 以你喜欢的方式(思维导图或其他)归纳总结集合相关内容. 参考资料: XMind 答: 大多数情况下,从性能上来说ArrayList最好,但是当集合内的元素需要频繁插入.删除时Lin ...