替换之后,myeclipse中新建时特别简洁,不需要每次都删除了。
今天内容都特别重要
一、Servlet概述
1、什么是Servlet
Servlet是一个运行在服务器端的Java小程序,通过HTTP协议用于接收来自客户端请求,并发出响应。
2、Servlet中的方法
public void service(ServletRequest req,ServletResponse res)
throws ServletException,java.io.IOException
ServletRequest req:代表着请求对象,该对象中有HTTP协议的请求部分的所有内容。它的实现类由服务器提供的,封装数据也是服务器来做的。
ServletResponse res:代表着响应对象,该对象中由我们写数据(HTTP协议的响应部分)进去。它的实现类也是由服务器提供的。
service:由服务器调用,每次请求都会调用一次。服务器采用的是多线程机制。
二、Servlet的编码步骤
1、编写一个类实现javax.servlet.Servlet接口,或者继承javax.servlet.GenericServlet。
2、编译Servlet的源码
3、映射Servlet
修改web.xml
4、把应用部署Tomcat中,访问地址:http://localhost:8080/firstServlet/hello
明确:规范 服务器 应用间的关系
三、Servlet的执行过程
1.客户端访问Tomcat访问地址:http://localhost:8080/firstServlet/hello
2.Tomcat解析客户端的访问地址
3.Tomcat找firstServlet应用。
4.找之间先搜索web.xml
5.接着就找到自己的类。
6.执行service
7.给用户看到结果
四、Servlet的编写方式:
1、javax.servlet.GenericServlet:通用的Servlet实现,抽象类
(经常用)2、javax.servlet.http.HttpServlet:与HTTP协议有关的,抽象类
继承HttpServlet,然后覆盖掉doGet或doPost方法即可,
不要覆盖掉service方法。
*Servlet规范中的核心接口类图(建议作为桌面)
Httpservlet(HttpServletRequest、HttpServletResponse)继承GenericServlet(ServletRequest、ServletRespone)、GenericServlet继承Servlet(接口)
五、Servlet的生命周期
1、生命周期(必须清晰):诞生--活着--死亡。人有这个过程,内存中的对象也有。
2、Servlet对象的生命周期
- 诞生:用户第一次访问时,由容器创建他的实例。
- 活着:一旦创建就驻留内存(单例)。每次用户的访问,容器都会调用sevice方法发出响应(多线程)
- 死亡:应用被卸载或者Tomcat关闭了
代码实现:
//用户第一次访问时,只执行一次
public ServletDemo3(){
System.out.println("调用了Servlet的默认构造方法");
}
//用户第一次访问时,执行一次。用于对象的初始化
public void init() throws ServletException {
System.out.println("调用了Servlet的初始化方法");
}
//每次用户访问都执行
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("执行了Service方法");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
//调用一次。用于清理工作
public void destroy() {
System.out.println("调用了Servlet的销毁方法");
}
结果截图:
六、Servlet的线程安全
错误的写法:
七、Servlet的一些细节
1.一个Servlet可以被映射到多个地址上
也可以:
2、可以使用地址的通配符
写法一:*.do结尾。必须以*开头 比如*.do
写法二(比一优先级略高):以/开头,必须*结尾 比如/action/*
映射的先后顺序:(例题)
对于如下的一些映射关系:
lServlet1 映射到 /abc/*
lServlet2 映射到 /*
lServlet3 映射到 /abc
lServlet4 映射到 *.do
问题:
l当请求URL为“/abc/a.html”,“/abc/*”和“/*”都匹配,哪个servlet响应
Servlet引擎将调用Servlet1。
l当请求URL为“/abc”时,“/abc/*”和“/abc”都匹配,哪个servlet响应
Servlet引擎将调用Servlet3。
l当请求URL为“/abc/a.do”时,“/abc/*”和“*.do”都匹配,哪个servlet响应
Servlet引擎将调用Servlet1。
l当请求URL为“/a.do”时,“/*”和“*.do”都匹配,哪个servlet响应
Servlet引擎将调用Servlet2。
l当请求URL为“/xxx/yyy/a.do”时,“/*”和“*.do”都匹配,哪个servlet响应
Servlet引擎将调用Servlet2。
3.默认的Servlet
默认的Servlet的映射路径是<url-pattern>/<url-pattern>。不需要大家配,因为默认的Servlet负责处理用户的请求URL找不到匹配的处理工作。
4.应用在启动时就完成Servlet的实例化和初始化
初始化1被占用了
八、ServletConfig:Servlet的参数配置
1、ServletConfig:代表看针对当前Servlet的参数配置。
在Servlet的配置文件中,可以使用一个或多个<init-param>标签为servlet配置一些初始化参数。
代码实现:
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ServletConfig config = getServletConfig(); //使用config了
// method1(config);
test(config);
}
private void test(ServletConfig config) { //得到当前Servlet所有的配置参数
Enumeration e = config.getInitParameterNames(); //参数的名字
while(e.hasMoreElements()){
String paramName = (String)e.nextElement();
System.out.println(paramName+"="+config.getInitParameter(paramName));
}
}
private void method1(ServletConfig config) { //得到指定名称的参数的值
String str = config.getInitParameter("encoding"); //得到指定名称的参数值
System.out.println(str);
}
2、如何得到ServletConfig对象的应用:在初始化Servlet,由容器产生,并传递给你,
编码和解码:
@Test
public void test1() throws UnsupportedEncodingException{
String s = "陈宇超";
System.out.println(URLEncoder.encode(s,"utf-8"));//编码
}
@Test
public void test2() throws UnsupportedEncodingException{
String s = "%E9%99%88%E5%AE%87%E8%B6%85";
System.out.println(URLDecoder.decode(s,"utf-8"));//解码
}
九、ServletContext
1、ServletContext 代表着当前应用。每个应用只有用一个ServletContext对象实例,有容器提供
2、获得ServletContext的实例:ServletConfig.getServletContext();
3、ServletContext的生命周期
诞生:应用被加载时就有容器创建好
活着:应用不挂就一直活着
死亡:应挂了,就挂了
4、域(存活范围)对象:
ServletContext成为应用范围域对象。
servletContext 是四大域对象中最大的域对象
【应用1】.多个Servlet通过ServletContext对象实现数据共享
注意:运行时,先运行Demo1 在运行Demo2 不然就会出现空指针。
5、配置应用级的参数web.xml
【应用2】、获取WEB应用的初始化参数
这是个全局配置,具有统一性
用ServletContext来取
代码如下:
ServletContext sc = getServletContext();
//获取指定的一个参数
String s = sc.getInitParameter("encoding");
System.out.println(s);
//获取所有的参数
Enumeration<String> e = sc.getInitParameterNames();
while(e.hasMoreElements()){
String contextName = e.nextElement();
System.out.println(contextName+"="+sc.getInitParameter(contextName));
}
【应用3】实现Servlet的转发。
代码实现:
运行Demo4 显示的内容是Demo5
【应用4】利用ServletContext对象读取资源文件。
(1)、下载图片:
(2)读取属性文件
- properties文件(属性文件)
- 得到文件路径(ServletContext.getRealPath(),ServletContext.getReaourceAsStream())
- 思考:如果一个普通类该如何读取配置文件??
- 读取资源文件的三种方式
I、代码如下:
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
test4();
}
//请不要把Tomcat等服务器装在有空格的目录中
//1.1.类加载器读取:只能读取classes或者类路径中的任意资源。但是不适合读取特别大的资源。1 2
private void test4() throws IOException {
//得到类的字节码文件,在得到类得加载器
ClassLoader cl = Demo7.class.getClassLoader();
// URL url = cl.getResource("/resources/1.properties");
URL url = cl.getResource("/2.properties");
InputStream is = new FileInputStream(url.getPath());
Properties prop = new Properties();
prop.load(is);
System.out.println(prop.getProperty("hello"));
}
//1.2.类加载器读取:只能读取classes或者类路径中的任意资源。但是不适合读取特别大的资源。只能读取 1 2
private void test3() throws IOException{
ClassLoader cl = Demo7.class.getClassLoader();
InputStream is = cl.getResourceAsStream("/resources/1.properties");
// InputStream is = cl.getResourceAsStream("2.properties");
Properties prop = new Properties();
prop.load(is);
System.out.println(prop.getProperty("hello"));
}
//2.利用ResourceBundle读取:1 2 (文件在classes类路径内),不能读1,只能读取properties的文件
private void test2(){
// ResourceBundle rb = ResourceBundle.getBundle("2");
ResourceBundle rb = ResourceBundle.getBundle("resource.1");
System.out.println(rb.getString("hello"));
}
//利用ServletContext读取:1 2 3 文件
//3.可以读取应用中任何位置上的资源。使用限制:只能在web应用中用
private void test1() throws IOException{
// String realPath = getServletContext().getRealPath("/WEB-INF/classes/resources/1.properties");
// String realPath = getServletContext().getRealPath("/WEB-INF/classes/2.properties");
String realPath = getServletContext().getRealPath("/3.properties");
InputStream is = new FileInputStream(realPath);
Properties prop = new Properties();
prop.load(is);
System.out.println(prop.getProperty("hello"));
}