1、Servlet简介
Servlet全称Java Servlet。servlet 是运行在 Web 服务器中的小型 Java 程序。servlet 通常通过 HTTP(超文本传输协议)接收和响应来自 Web 客户端的请求。
功能:用于交互式地浏览和修改数据,生成动态Web内容。
2、Servlet的使用
1、编写java类实现servlet接口(可以编写一个继承 javax.servlet.GenericServlet 或者 javax.servlet.http.HttpServlet 的servlet)
2、部署到web服务器中
3、在MyEclipse中创建servet
1、创建web project
2、继承servlet
public class MyServlet implements Servlet {
//只创建一次
public void init(ServletConfig arg0) throws ServletException {
// TODO Auto-generated method stub
System.out.println("Servlet------init()");
}
public void service(ServletRequest arg0, ServletResponse arg1)
throws ServletException, IOException {
// TODO Auto-generated method stub
System.out.println("Servlet------service()");
}
public ServletConfig getServletConfig() {
// TODO Auto-generated method stub
return null;
}
public String getServletInfo() {
// TODO Auto-generated method stub
return null;
}
public void destroy() {
// TODO Auto-generated method stub
System.out.println("Servlet------destory()");
}
}
3、在web.xml中配置
web.xml其实就是servlet的一个配置文件,通过这个配置文件来寻找对应的servlet处理业务。
sun公司就是这样设计,容器通过配置文件web.xml找相应的servlet这样有助于灵活和可维护性
4、Servlet生命周期
1、init()方法:服务器调用该方法初始化Servlet
2、service()方法:初始化完毕,服务器调用该方法响应客户的请求
3、destroy()方法:服务器调用该方法消灭servlet对象
其中,init()方法只在Servlet第一次被请求加载的时候被调用一次,当有客户再请求Servlet服务时,Web服务器将启动一个新的线程,在该线程中,调用service方法响应客户的请求
Servlet是一个供其他Java程序(Servlet引擎)调用的Java类,它不能独立运行,它的运行完全由Servlet引擎来控制和调度。
针对客户端的多次Servlet请求,通常情况下,服务器只会创建一个Servlet实例对象,也就是说Servlet实例对象一旦创建,它就会驻留在内存中,为后续的其它请求服务,直至web容器退出,servlet实例对象才会销毁。
在Servlet的整个生命周期内,Servlet的init方法只被调用一次。而对一个Servlet的每次访问请求都导致Servlet引擎调用一次servlet的service方法。对于每次访问请求,Servlet引擎都会创建一个新的HttpServletRequest请求对象和一个新的HttpServletResponse响应对象,然后将这两个对象作为参数传递给它调用的Servlet的service()方法,service方法再根据请求方式分别调用doXXX方法。
5、GenericServlet
GenericServlet 是对servlet的封装,它实现 了Servlet 和 ServletConfig 接口。如果我们实现原有的Servlet,要写每一个servlet都要写init(),等生命周期的方法。如果再加上一些都是相同的代码,会有很多不必要的工作。因此GenericServlet 是在Servlet的基础上实现servlet接口,对它进行封装,主要做以下工作:
- init()方法,并保存了config对象
- 空参init()方法,防止调用原生init()方法
- service(),声明抽象(具体业务而定)
- 实现getServletInfo,getServletConfig
- 实现了servletConfig接口. 接口中的方法直接调用config实现类实现
- destory()方法空实现
6、HttpServlet
HttpServlet是在GenericServlet 基础上进行的再一次封装,它是GenericServlet 的子类
在这里它比GenericServlet 又做了一些全局的通用的处理
1、把ServletRequest,ServletResponse强转成HttpServletRequest,HttpServletResponse以为在具体的开发中用到的是ServletRequest封装的HTTP请求
@Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
HttpServletRequest request;
HttpServletResponse response;
try {
request = (HttpServletRequest) req;
response = (HttpServletResponse) res;
} catch (ClassCastException e) {
throw new ServletException("non-HTTP request or response");
}
service(request, response);
}
2、处理用户的不同请求
1、METHOD_GET
2、METHOD_HEAD
3、METHOD_POST
4、METHOD_DELETE
5、METHOD_OPTIONS
6、METHOD_TRACE
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String method = req.getMethod();
if (method.equals(METHOD_GET)) {
long lastModified = getLastModified(req);
if (lastModified == -1) {
// servlet doesn't support if-modified-since, no reason
// to go through further expensive logic
doGet(req, resp);
} else {
long ifModifiedSince;
try {
ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
} catch (IllegalArgumentException iae) {
// Invalid date header - proceed as if none was set
ifModifiedSince = -1;
}
if (ifModifiedSince < (lastModified / 1000 * 1000)) {
// If the servlet mod time is later, call doGet()
// Round down to the nearest second for a proper compare
// A ifModifiedSince of -1 will always be less
maybeSetLastModified(resp, lastModified);
doGet(req, resp);
} else {
resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
}
}
} else if (method.equals(METHOD_HEAD)) {
long lastModified = getLastModified(req);
maybeSetLastModified(resp, lastModified);
doHead(req, resp);
} else if(){
......
}......
}
7、Servlet线程安全问题
从Servlet的生命周期中可以看出,我们调用init()方法只执行一次,当我们再次运行的时候已经不调用init方法
因此,共享引起线程安全。如果使用成员变量来接受线程中的参数,那么就就会出现线程安全问题。
解决办法:把成员变量放到局部变量中
8、Servlet路径配置问题
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>com.example.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/MyServlet</url-pattern>
</servlet-mapping>
在的url-pattern中配置servlet的路径,在这是一个相对路径/表示在我们当前的目录下,在这里相当于http:localhost:8080/ServletDemo
8、ServletConfig
在Servlet的配置文件中,可以使用一个或多个标签为servlet配置一些初始化参数。(配置在某个servlet标签或者整个web-app下)
当servlet配置了初始化参数后,web容器在创建servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,并在调用servlet的init方法时,将ServletConfig对象传递给servlet。进而,程序员通过ServletConfig对象就可以得到当前servlet的初始化参数信息。
9、ServletContext
ServletContext,是一个全局的储存信息的空间。
ServletContext定义一组方法,servlet 使用这些方法与其 servlet 容器进行通信,例如,获取文件的 MIME 类型、分发请求或写入日志文件。
比如 Servlet之间传递数据;
通过获取ServletContext对象设置
public void setAttribute(String name, Object object);
通过getAttribute获取
public Object getAttribute(String name);
本文详细介绍了Servlet的概念、使用方法及生命周期,包括如何编写、部署Servlet,以及ServletConfig和ServletContext的作用。
1347

被折叠的 条评论
为什么被折叠?



