一、Servlet概述
1、Servlet是SUN公司制定的一套开发动态网页的技术。
2、JavaEE相关的类,包名一般都是以javax开头
3、servlet规范和容器的关系:
4 、参考: ServletAPI
二、编写第一个Servlet案例应用(*****)
1、建立一个标准的JavaWeb应用目录
FirstApp:
WEB-INF:
classes:
lib:
web.xml
2、进入classes目录,建立一个文本文件
注:所有的Servlet类都必须间接或直接实现javax.servlet.Servlet接口
或继承父类GenericServlet(相当于适配器);
package cn.itcast.servlet;
import java.io.*;
import javax.servlet.*;
public class FirstServlet extends GenericServlet{
public void service(ServletRequest req,ServletResponse res)
throws ServletException,java.io.IOException{
OutputStream out = res.getOutputStream();
out.write("Hello Servlet".getBytes());
out.close();
}
}
3、进入classes目录,对FirstServlet进行编译:
前提:把servlet-api.jar加入到你的构建路径中.
set classpath=
%classpath%;C:\apache-tomcat-6.0.35\lib\servlet-api.jar
执行:javac -d . FirsetServlet.java
4、修改web.xml,对FirsetServlet进行url地址映射,配置如下:
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http:
//java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<servlet>
<servlet-name>FirstServlet</servlet-name>
<servlet-class>cn.itcast.servlet.FirstServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FirstServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
5、把你的应用部署到Tomcat中。
6、访问地址:http://localhost:8080/FirstApp/hello
就可以看到写的Servlet类的输出结果了。
7、该程序的执行原理和过程(Servlet的生命周期)
三、Servlet的生命周期(*****)
容器最终要调用service方法为客户进行服务
第一次访问的时候创建Servlet对象,由Tomcat容器创建,
以后每次的请求找Service,在服务器关闭或卸载应用的时候销毁。
Servlet接口中的常用方法:
public void init(ServletConfig config):
初始化。Servlet类被实例化后就执行,
且执行一次。由容器进行调用
public void destroy():销毁Servlet对象。由容器进行调用
public void service(ServletRequest req,ServletResponse res)
在内存中一个Servlet只有一个实例。
针对不同的用户请求,容器采用多线程的机制调用service方法的。
Servlet实例对象和初始化方法,默认情况下,只有第一次访问时才执行,
且只执行一次。
希望在应用被Tomcat加载完毕后(此时还没有任何人访问),
就实例化并完成初始化Servlet的工作的设置方法:
<servlet>
<servlet-name>FirstServlet</servlet-name>
<servlet-class>cn.itcast.servlet.FirstServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
注: 优先级从2开始,0和1(默认的Servlet)已经被默认占用了;
四、Servlet的孩子们(模板方法设计模式)(*****)
如果设计与HTTP协议有关的Servlet,一般选择继承javax.servlet.http.HttpServlet.
不要覆盖其中的service(ServletRequest req,ServletResponse resp)方法,
而应该覆盖掉,doXXX方法。doXXX就是根据你的请求方式来的。
HttpServlet中的service方法是典型的模板方法设计模式的具体应用。
五、Servlet配置(**)
1、一个Servlet可以被映射到多个URL地址上
2、URL地址映射还支持通配符*
方式一:以*开头,以扩展名结尾。比如 <url-pattern>*.do</url-pattern>
方式二:以/前缀开头,以*结尾。 比如<url-pattern>/action/*</url-pattern>
3、多个Servlet使用通配符时,有可能有多个配置的Servlet,到底执行哪一个的原则:
原则:优先级一下三种,递减
绝对匹配
以"/"开头(方式二)要比"*"开头(方式一)优先级高
都以"/"开头,还是有多个匹配,找最匹配的
4、如果一个Servlet的映射为一个"/",就称之为默认的Servlet,它负责处理没有映射路径的URL请求的响应。
六、Servlet中的线程安全问题(*****):
解决并发出现的问题,可以采取以下方式:
使用Java同步机制或锁机制对多线程同步运行: 运行效率极低;
使用SingleThreadModel接口,已过时;
合理决定在Servlet中定义的变量的作用域;
在Servlet中定义变量,除非特殊要求,尽量使用局部变量。
如果有需要实例变量时,应做同步处理,且同步代码块尽量包围少的代码。
七、Servlet的配置对象(***):
ServletConfig:(容器来创建)
作用:代表了Servlet配置中的参数信息。
比如在web.xml中的参数配置如下:
<servlet>
<servlet-name>ServletDemo2</servlet-name>
<servlet-class>cn.itcast.servlet.ServletDemo2</servlet-class>
<init-param><!-- aaa=bbb -->
<param-name>aaa</param-name>
<param-value>bbb</param-value>
</init-param>
<init-param>
<param-name>xxx</param-name>
<param-value>yyy</param-value>
</init-param>
</servlet>
*********************************************************************************
例:
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ServletDemo2 extends HttpServlet {
private ServletConfig config;
@Override
public void init(ServletConfig config) throws ServletException {
this.config = config;
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
test1();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
// 得到指定的参数aaa的值
public void test1() {
String value = config.getInitParameter("aaa");
System.out.println(value);
}
// 得到所有的参数及参数的值
public void test2() {
Enumeration e = config.getInitParameterNames();
while (e.hasMoreElements()) {
String paramName = (String) e.nextElement();
System.out.println(paramName + "="
+ config.getInitParameter(paramName));
}
}
// 得到Servlet的名称
public void test3(){
String name = config.getServletName();
System.out.println(name);
}
}
*********************************************************************************
八、ServletContext详解(*****)
1、在应用被服务器加载时就创建ServletContext对象的实例。
每一个JavaWeb应用都有唯一的一个ServletContext对象,它就代表着当前的应用。
2、得到ServletContext对象方法:
法1:
private ServletConfig config;
public void init(ServletConfig config) throws ServletException {
this.config = config;
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ServletContext sc = config.getServletContext();
}
法2:是对上述法1的封装,直接调用即可
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ServletContext sc = getServletContext();
}
3、作用
3.1 ServletContext对象是一个域对象(域对象就是说其内部维护了一个Map<String,Object>)
Object getAttribute(String name): 根据名称获取绑定的对象
Enumeration getAttributeNames() : 获取ServletContext域中的所有名称
void removeAttribute(String name): 根据名称移除对象
void setAttribute(String name,Object value):添加或修改对象。
3.2 应用共用一个ServletContext对象,所以可以实现多个Servlet之间的数据共享
3.3 获取WEB应用的初始化参数(应用的全局参数)
在web.xml的根元素下配置一下信息:
<context-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</context-param>
这些参数就属于整个应用的全局参数,使用ServletContext来读取。
疑问: 与过滤器有什么区别??? 是配置参数需要读取,而过滤器不需要读取么?
*********************************************************************************
例子: 读取应用的全局参数
public class ServletDemo5 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ServletContext sc = getServletContext();
String value = sc.getInitParameter("encoding");
response.getOutputStream().write(value.getBytes());
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
*********************************************************************************
3.4 实现Servlet的转发
3.4 读取资源文件的三种方式:
利用ServletContext.getRealPath():
特点:读取应用中任何文件。只能在Web环境下用
得到文件的真实路径 注: 路径必须以"/"开头,"/"就代表当前应用
注意不同位置的配置文件的路径写法,具体参考Tomcat中配置文件的路径
ServletContext sc = getServletContext();
String path = sc.getRealPath("/1.jpg");
path为: c:\apache-tomcat-6.0.35\webapps\day06\1.jpg
利用ResourceBundle读取配置文件
特点:可以用在非web环境下。但是只能读取类路径中的properties文件
利用类加载器读取配置文件(专业)
特点:可以用在非web环境下。可以读取类路径下的任何文件。
九、ServletAPI中的主要接口或类的核心类图
十、Tips:更改MyEclipse生成的Servlet的模板(8.5)
1、关闭你的MyEclipse
2、找到MyEclipse的安装目录C:\Program Files\Genuitec
3、搜索*wizard*(com.genuitec.eclipse.wizards_8.5.0.me201003052220.jar)
4、打开,找到templates\Servlet.java,这个文件就是MyEclipse生成Servlet的模板代码
5、弄出来,做好备份,开始修改。
将内容换为如下,再考回去即可
#---------------------------------------------#
# <aw:description>Template for Servlet</aw:description>
# <aw:version>1.1</aw:version>
# <aw:date>04/05/2003</aw:date>
# <aw:author>Ferret Renaud</aw:author>
#---------------------------------------------#
<aw:import>java.io.IOException</aw:import>
<aw:import>java.io.PrintWriter</aw:import>
<aw:import>javax.servlet.ServletException</aw:import>
<aw:import>javax.servlet.http.HttpServlet</aw:import>
<aw:import>javax.servlet.http.HttpServletRequest</aw:import>
<aw:import>javax.servlet.http.HttpServletResponse</aw:import>
<aw:parentClass>javax.servlet.http.HttpServlet</aw:parentClass>
<aw:constructor name="c1">
/**
* Constructor of the object.
*/
public <aw:className/>() {
super();
}
</aw:constructor>
<aw:method name="doGet">
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
</aw:method>
<aw:method name="doPost">
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request,response);
}
</aw:method>