Servlet学习应该注意的几点
一、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学习应该注意的几点的更多相关文章
- JSP&Servlet学习手册
JSP&Servlet学习手册 沙琪玛 书 目录 JSP 指令... 3 书写方式... 3 指令列表... 3 JSP 内置对象... 3 内置对象特点... 3 常用内置对象... 3 o ...
- Servlet 学习笔记
Servlet 运行在服务器上的 java 类: Servlet 容器为 javaWeb 应用提供运行时环境,负责管理 servlet 和 jsp 生命周期,以及管理他们的共享数据. 现在我们知道了 ...
- Servlet学习:(三)Servlet3.0 上传文件
转: Servlet学习:(三)Servlet3.0 上传文件 2018年08月03日 11:57:58 iDark_CSDN 阅读数:362 一.注意事项 客户端(浏览器) 表单的提交方法必须是 ...
- Servlet学习(九)——request
request运行流程在Servlet学习(四)——response已介绍,不再赘述 1.通过抓包工具获取Http请求 因为request代表请求,所以我们可以通过该对象分别获得Http请求的请求行, ...
- # jsp及servlet学习笔记
目录 jsp及servlet学习笔记 JSP(Java Server Page Java服务端网页) 指令和动作: servlet(小服务程序) jsp及servlet学习笔记 JSP(Java Se ...
- Servlet学习笔记(四)
目录 Servlet学习笔记(四) 一.会话技术Cookie.session 1. 什么是会话技术? 2. 会话技术有什么用? 3. Cookie 3.1 什么是Cookie? 3.2 使用Cooki ...
- Servlet学习笔记(三)
目录 Servlet学习笔记(三) 一.HTTP协议 1.请求:客户端发送欸服务器端的数据 2.响应:服务器端发送给客户端的数据 3.响应状态码 二.Response对象 1.Response设置响应 ...
- Servlet学习笔记(二)
目录 Servlet学习笔记(二) Request对象 1.request和response对象: 2.request对象继承体系结构: 3.什么是HttpServletRequest ? 4.Htt ...
- servlet 学习(二)
一.ServletConfig讲解 1.1.配置Servlet初始化参数 在Servlet的配置文件web.xml中,可以使用一个或多个<init-param>标签为servlet配置一些 ...
- JavaWeb学习总结-04 Servlet 学习和使用
一 Servlet 1 Servlet概念 Servlet时运行在服务器端的Java程序. Servlet的框架核心是 javax.servlet.Servlet 接口. 所有自定义的Servlet都 ...
随机推荐
- PyQt4简单小demo
#coding=utf-8 import sys from PyQt4.QtCore import * from PyQt4.QtGui import * class FontPropertiesDl ...
- 【javascript】谈谈HTML5 ——HTML兽进化, H5兽!
作为一名Web开发者,可能你并没有对这个“H5”这个字眼投入太多的关注,但实际上它早已不知不觉进入到你的开发中,并且总有一天会让你不得不正视它,了解它并运用它 打个比方:<海贼王>中的 ...
- Tomcat session集群
author:JevonWei 版权声明:原创作品 环境 tomcatA 172.16.253.108 tomcatB 172.16.253.105 代理服务器 172.16.253.191 Tomc ...
- 从送外卖到建站售主机还有共享自行车说起-2017年8月江西IDC排行榜与发展报告
曾几何时,送外卖,这样的"低技术含量"工作,很难被互联网公司看上,直到百度将其当作连接终端用户与大数据的管道. 同样,销售主机域名和建站业务,本也是"微小体量" ...
- Flask04 后台获取请求数据、视图函数返回类型、前台接受响应数据
1 后台获取请求数据 1.1 提出问题 前台发送请求的方式有哪些 后台如何获取这些请求的参数 1.2 前台发送请求的方式 GET.POST.AJAX 点睛:如果不指定请求方式,浏览器默认使用GET请求 ...
- Nand Flash驱动(实现初始化以及读操作)
简单制作一个Nand Flash驱动(只需要初始化Flash以及读Flash) 打开2440芯片手册,K9F2G08U0M芯片手册(因为2440中Nand Flash是用的256MB(2Gb)内存,8 ...
- 为什么可以通过URL来调起APP - URL Scheme和Intent
在手机浏览器中可以通过URL调起APP是不是很神奇?这篇文章就告诉你为什么. URL Scheme 先从前端能接触到的URL Scheme分析一下 丢wiki:https://en.wikipedia ...
- JQuery实用技巧--学会你也是大神(1)——插件的制作技巧
前 言 JRedu 学习之前,首先我们需要知道什么是JQuery? JQuery是一个优秀的javascript框架. JQuery是继Prototype之后又一个优秀的Javascript框架 ...
- 介绍call和apply
function add(a, b) { alert(a + b); } function sub(a, b) { alert(a - b); } add.call(sub, 1,3); //4 传 ...
- 【Alpha】第四次Daily Scrum Meeting
GIT 一.今日站立式会议照片 二.会议内容 1.采取老师提出的建议,考虑对送礼对象进行一个分类,这个在服务功能模块中完善. 2.回顾之前几次会议的内容,做一个小的总结,各抒己见,对每个人哪方面做得比 ...