1.什么是servlet
servlet是一个Java类,是用来专门处理请求和响应的,是部署在服务器上工作的小程序,之所以叫小程序,是因为它只要部署上去就自动运行工作了可以处理事情了。servlet 通常通过 HTTP(超文本传输协议)接收和响应来自 Web 客户端的请求。
HTTP:
★ HTTP是HyperText Transfer Protocol(超文本传输协议)的简写,传输HTML文件。
★ 用于定义WEB浏览器与WEB服务器之间交换数据的过程及数据本身的格式。
2.操作步骤:
a.创建一个实现servlet接口的Java类(ServletDemo1)。
ServletDemo1爆红是因为实现了Servlet接口就需要重写里面的方法。实现接口所定义的方法。
在service方法里添加输出语句
@Override
public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {
// TODO Auto-generated method stub
System.out.println("执行Servlet里的方法");
}
b.在web.xml中配置servlet的信息。
我们的目的就是让用户通过url来访问我们的刚刚实现了servlet接口的类,然后在这个类里面做一些处理。但是我们的类是写在src中,然后编译成字节码.class文件是存放在WEB-INF中的,我们部署应用的时候就把WEB-INF的东西部署到服务器上,而WEB-INF文件中的东西是不允许外部访问的,所以如果想要访问的这个类(严格意义上说是这个类生成的字节码文件),我们就需要通过一些配置来告诉服务器某个URL地址是用来访问某个类的。这就是我们为什么要配置web.xml的原因。(服务器Tomcat启动后加载项目最先扫描执行web.xml文件)

web.xml主要代码:
<servlet>
<!-- 一般把类名首字母变小写作为servlet-name-->
<servlet-name>ServelDemo1</servlet-name>
<servlet-class>com.szy.web.servlet.ServelDemo1</servlet-class>
</servlet>
这里的访问逻辑是,我们在浏览器输入localhost:8080/应用名/demo1后,它就会找到中相应的url(在中),然后根据这个url找到对应的叫servletDemo1,然后就在这个节点里再找到该对应的。至此,就自动找到这个类,去执行相应的任务了。
<servlet>
<servlet-name>servelDemo1</servlet-name>
<servlet-class>com.cms.Demo1.Service.ServelDemo1</servlet-class>
<!-- 2,填数字越小优先级越高,越先执行,让该servlet在服务器启动时就创建,不建议写零 -->
<load-on-startup>2</load-on-startup>
</servlet>
<!-- 给Servlet映射一个可访问的URI :http://localhost:8080/项目名/demo1即可通过servelDemo1映射到ServelDemo1访问该类-->
<servlet-mapping>
<servlet-name>servelDemo1</servlet-name>
<url-pattern>/demo1</url-pattern>
</servlet-mapping>
com.szy.web.servlet.ServelDemo1路径的获得操作如下图:

执行结果:
浏览器显示空白页面但是控制台输出了ServletDemo1类里的执行结果。

3.Servlet的生命周期
此接口定义了初始化 servlet 的方法 init()、为请求提供服务的方法 service()和从服务器移除 servlet 的方法 destroy()。这些方法称为生命周期方法,它们是按以下顺序调用的:
a .初始化阶段 :
构造 servlet,然后使用 init 方法将其初始化。
b.响应客户请求阶段:
处理来自客户端的对 service 方法的所有调用。
c.终止阶段:
从服务中取出 servlet,然后调用 destroy 方法销毁它,最后进行垃圾回收并终止它。
除了生命周期方法之外,此接口还提供了 getServletConfig 方法和 getServletInfo 方法,servlet 可使用前一种方法获得任何启动信息,而后一种方法允许 servlet 返回有关其自身的基本信息,比如作者、版本和版权。
package com.szy.web.servlet;
import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class ServelDemo1 implements Servlet {
public ServelDemo1() {
// 实例化方法
}
@Override
public void init(ServletConfig arg0) throws ServletException {
// 初始化
}
@Override
public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {
// 服务
System.out.println("执行Servlet里的方法");
}
@Override
public void destroy() {
//销毁
}
@Override
public ServletConfig getServletConfig() {
// TODO Auto-generated method stub
return null;
}
@Override
public String getServletInfo() {
// TODO Auto-generated method stub
return null;
}
}
注意:
Servlet何时被创建:
★ 默认情况下,当WEB客户第一次请求访问某个Servlet的时候,WEB容器将创建这个Servlet的实例。
★ 当web.xml文件中如果<servlet>元素中指定了<load-on-startup>子元素时,Servlet容器在启动web服务器时,将按照顺序创建并初始化Servlet对象。
★ 在web.xml文件中,某些Servlet只有<serlvet>元素,没有<servlet-mapping>元素,这样我们无法通过url的方式访问这些Servlet,这种Servlet通常会在<servlet>元素中配置一个<load-on-startup>子元素,让容器在启动的时候自动加载这些Servlet并调用init()方法,完成一些全局性的初始化工作。
4.servlet的三种创建方式
Servlet --> GenericServlet --> HttpServlet -->我们定义的继承HttpServlet的类
曾祖父 爷爷 爸爸 孙子
方法如下:
a. 实现javax.servlet.Servlet接口(参见:编写一个servlet程序)
要实现此接口,还可以编写一个扩展 javax.servlet.GenericServlet 的一般 servlet,或者编写一个扩展 javax.servlet.http.HttpServlet 的 HTTP servlet。

b. 继承javax.servet.GenericServlet类(适配器模式)

只需重写抽象 service 方法,因为它里面只有一个抽象方法。


c. 继承javax.servlet.http.HttpServlet类(模板方法设计模式)
我们自己写Servlet的时候,处理请求的时候实现Service()就好。不重写Service()方法,而是重写doGet和doPost2个方法,在HttpServlet抽象类中,已经实现了Service方法了,在有请求进来Servlet的时候首先从请求中获取到请求提交的方式,所以我们直接重写doGet和doPost方法就好。通常来说不确定是什么请求的情况下,默认是Get请求,在doGet和doPost中实现一个就够了,如果方法的实现写在
HTTP的请求方式包括DELETE,GET,OPTIONS,POST,PUT和TRACE,在HttpServlet类中分别提供了相应的服务方法,它们是,doDelete(),doGet(),doOptions(),doPost(), doPut()和doTrace().
项目开发一般都用这种方式创建Servlet;
第一步:创建Servlet类文件
Ctrl+N;输入Servlet:

第二步:输入类名

第三步:映射路径的名字,默认为类名,可点击Edit编辑

第三步:勾选需要重写的方法:都默认勾选Doget和Dopost方法,点击Finish:
继承HttpServlet后不要重写service的方法,因为service方法里包含调用doget跟dopost的方法,重写了那两方法不执行就作废了

第五步:检查生成的类和Web.xml的Servlet配置信息
package com.cms.Demo1.Service;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class ServletDemo4
*/
public class ServletDemo4 extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public ServletDemo4() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.getWriter().append("Served at: ").append(request.getContextPath());
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
<servlet>
<display-name>ServletDemo4</display-name>
<servlet-name>ServletDemo4</servlet-name>
<servlet-class>com.cms.Demo1.Service.ServletDemo4</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletDemo4</servlet-name>
<url-pattern>/ServletDemo4</url-pattern>
</servlet-mapping>
注意:查看GenericServlet 的源码包导Tomcat的源码包,apache-tomcat-7.0.81-src.zip。Outline的窗口带三角的说明是继承过来重写的方法,没有的才是自己本身的。

servet映射细节
通配符* 代表任意字符串
url-pattern: *.do 以.字符串的请求都可以访问 注:不要加/
url-pattern: /* 任意字符串都可以访问
url-pattern: /action/ 以/action开头的请求都可以访问
匹配规则:
优先级:从高到低
绝对匹配--> /开头匹配 --> 扩展名方式匹配
如果url-pattern的值是/,表示执行默认映射。所有资源都是servlet
5. Servlet的线程安全
★ 单实例:每次访问多线程
★ 解决线程安全问题的最佳办法,不要写全局变量,而写局部变量。
★ Servlet的线程安全问题只有在大量的并发访问时才会显现出来,并且很难发现,因此在编写Servlet程序时要特别注意。
★ servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,所以你的项目中如果只有一个servlet,那么web容器就只会创建一个实例。所以其默认非线程安全,如果需要线程安全需要指明。
6.ServletConfig
作用:
★ 可以获取servlet配置信息
★ 可以获得ServletContext对象
6.1Servlet配置信息的获取:
当servlet配置了初始化参数后,web容器在创建servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,并在调用servlet的init方法时,将ServletConfig对象传递给servlet。进而,程序员通过ServletConfig对象就可以得到当前servlet的初始化参数信息。
web.xml。只要有ServletConfig对象就能调用getInitParameter方法。
<servlet>
<display-name>servletDemo4</display-name>
<servlet-name>ServletDemo4</servlet-name>
<servlet-class>com.cms.Demo1.Service.ServletDemo4</servlet-class>
<!-- 初始化参数 -->
<init-param>
<param-name>encoding</param-name>
<param-value>GBK</param-value>
</init-param>
</servlet>
获取配置信息:GBK
package com.cms.Demo1.Service;
import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class ServletDemo4
*/
public class ServletDemo4 extends HttpServlet {
private ServletConfig config;//config对象专门操作配置文件信息
@Override
public void init(ServletConfig config) throws ServletException {
// TODO Auto-generated method stub
this.config = config;
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String encoding = config.getInitParameter("encoding");//获得配置文件中的信息
System.out.println(encoding);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
总结:
这样做的好处是:如果将数据库信息、编码方式等配置信息放在web.xml中,如果以后数据库的用户名、密码改变了,则直接很方便地修改web.xml就行了,避免了直接修改源代码的麻烦。
获取Servlet配置信息的方式(关键得到ServletConfig对象):
方式一:

方式二:

方式三:

7. ServletContext
ServletContext: 代表的是整个应用。一个应用只有一个ServletContext对象。单实例。
ServletContext与ServletConfig的区别:

作用:
a. 作为 域对象:在一定范围内(当前应用),使多个Servlet共享数据。
★ 域对象:在一个可以被看见的范围内共享数据用到对象
★ 作用范围:整个web应用范围内共享数据
★ 生命周期:当服务器启动web应用加载后创建出ServletContext对象后,域产生。当web应用被移除出容器或服务器关闭,随着web应用的销毁域销毁。
常用方法:
void setAttribute(String name,object value);//向ServletContext对象的map中添加数据
Object getAttribute(String name);//从ServletContext对象的map中取数据
void rmoveAttribute(String name);//根据name去移除数据
把数据添加到ServletContext的map里:
package com.cms.Demo1.Service;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class ServletDemo5
*/
public class ServletDemo5 extends HttpServlet {
/**
* @see HttpServoGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//通过GenericServlet类 继承的的getServletContext()方法得到ServletContext对象
ServletContext application = this.getServletContext();//输完this.getServletContext() 后Ctrl+回车,对象ServletContext通常用application(应用)表示。
//向ServletContext添加一个键值对
application.setAttribute("name", "value");
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
取出:
package com.cms.Demo1.Service;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class ServletDemo6
*/
public class ServletDemo6 extends HttpServlet {
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = (String) this.getServletContext().getAttribute("name");
System.out.println(name);
if(name==null){
System.out.println("你无权访问");
}
System.out.println();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
b. 获取全局配置信息:
web.xml文件:
String类型--getInitParameter(String name) //根据配置文件中的key得到value

Java文件:

c.获取资源路径:
String getRealPath(String path);//根据资源名称得到资源的绝对路径.
可以得到当前应用任何位置的任何资源。

注意:
getRealPath的路径是参考部署后(publish)的文件路径
'/'代表当前项目部署后的根目录:D:\apache-tomcat-7.0.52\webapps\webService
实现Servlet的转发:

注意:
RequestDispatcher getRequestDispatcher(String path) ;//参数表示要跳转到哪去
网友评论