你的位置:首页 > Java教程

[Java教程]Java Web之Servlet技术


 1、Servlet基础

  针对Servlet技术开发,Sun公司提供了一些列接口和类,其中最重要的是javax.servlet.Servlet接口,两个重要的包是javax.servlet和javax.servlet.http,Servlet就是一种实现了Servlet接口的类,它由Web容器(Tomcat/Jetty等)负责调用并创建,用于接收和响应用户请求。Servlet接口中定义了5个抽象方法:

方法功能
void init(ServletConfig config)

负责Servlet初始化工作,容器在创建好Servlet对象后就调用此方法。该方法接受一个

ServletConfig 类参数,Servlet容器通过这个参数向Servlet传递配置信息

ServletConfig getServletConfig()返回容器调用init(ServletConfig config)时传递的ServletConfig 对象
void service(ServletRequest req, ServletResponse res)

负责响应用户的请求,当接收到客户端访问Servlet对象的请求时就会调用此方法。

容器会构造一个ServletRequest和ServletResponse对象作为参数传递到该方法中,

在该方法中通过ServletRequest对象获取请求信息,对请求处理完成后,通过

ServletResponse对象设置响应消息

String getServletInfo()

返回一个字符串,包含Servlet信息。注意,该方法自己需要重定义,在GenericServlet

类中该方法返回空字符串

void destroy()负责释放Servlet对象占用的资源,当Servlet对象被销毁时,容器会调用该函数

Servlet顶层类结构如下所示:

2、第一个Servlet程序

  新建一个Java Web工程,然后新建Hello类,Hello.java源码如下:

package zzz;import java.io.IOException;import java.io.PrintWriter;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class Hello extends HttpServlet {  @Override  public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {    // 设置响应消息编码    response.setContentType("text/html;charset=utf-8");    PrintWriter out = response.getWriter();    out.println("Hello World");  }    @Override  public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {    this.doGet(request, response);  }}

  配置文件web.

<??><web-app ="http://www.w3.org/2001/   ="http://   xsi:schemaLocation="http:// id="WebApp_ID" version="3.1">  <display-name>zzz</display-name> <servlet> <!-- 注册Servlet -->   <servlet-name>Hello</servlet-name> <!-- 指定Servlet名称 -->   <servlet-class>zzz.Hello</servlet-class> <!-- 指定Servlet完整类名 --> </servlet> <servlet-mapping> <!-- 映射Servlet对外访问路径 -->   <servlet-name>Hello</servlet-name> <!-- 指定Servlet名称 -->   <url-pattern>/hello</url-pattern> <!-- 指定访问Servlet的虚拟路径 --> </servlet-mapping></web-app>

  启动运行浏览器显示如下:

3、Servlet生命周期

   Servlet生命周期大致分为3个阶段,初始化阶段、运行阶段和销毁阶段。以下是各个阶段详细说明:

  • 初始化阶段:客户端向Servlet容器发出请求访问Servlet时,容器首先解析请求,查看内存中是否有该Servlet对象,如果有直接使用;否则创建该Servlet对象,然后调用init()方法,注意,Servlet整个声明周期中,init()只会调用一次
  • 运行阶段:这个是Servlet最重要的阶段,此阶段容器会构造一个ServletRequest和ServletResponse对象作为参数传递到Servlet的service()方法中。对于Servlet的每一次访问,Servlet容器都会调用一次service()方法,service()方法在Servlet整个生命周期中会被调用多次
  • 销毁阶段:当服务器关闭或者Web应用被移除出容器时,会进入到此阶段,此时会调用destroy()方法,整个生命周期中destroy()方法只会被调用一次

  在客户端首次访问Servlet时,容器会创建该Servlet对象,但是有时希望Servlet对象在Tomcat启动时跟随启动,这怎么处理呢?此时,只需要在web.

<servlet>   <servlet-name>Hello</servlet-name>   <servlet-class>zzz.Hello</servlet-class>  <!-- 自动加载servlet程序 -->  <load-on-startup>1</load-on-startup>  </servlet> <servlet-mapping>   <servlet-name>Hello</servlet-name>   <url-pattern>/hello</url-pattern> </servlet-mapping>

 4、ServletConfig和ServletContext

ServletConfig接口

  Servlet运行期间,如果需要一些辅助信息,例如文件编码、使用Servlet的公司等,这些信息可以在web.

方法功能
String getServletName()返回Servlet名字,即web.
ServletContext getServletContext()返回代表当前Web应用的ServletContext对象
String getInitParameter(String name)根据参数名返回对应的参数值,如果未找到返回null
Enumeration<String> getInitParameterNames()返回一个Enumeration对象,其中包含所有的初始化参数

  接下来以getInitParameter()为例,讲解该方法使用示例:

web.

<??><web-app ="http://www.w3.org/2001/   ="http://   xsi:schemaLocation="http:// id="WebApp_ID" version="3.1">  <display-name>zzz</display-name> <servlet>   <servlet-name>Hello</servlet-name>   <servlet-class>zzz.Hello</servlet-class>   <init-param>     <param-name>company</param-name>     <param-value>dahua</param-value>   </init-param> </servlet> <servlet-mapping>   <servlet-name>Hello</servlet-name>   <url-pattern>/hello</url-pattern> </servlet-mapping></web-app>

Hello.java文件如下:

package zzz;import java.io.IOException;import java.io.PrintWriter;import javax.servlet.ServletConfig;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class Hello extends HttpServlet {  @Override  public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {    // 设置响应消息编码    response.setContentType("text/html;charset=utf-8");    PrintWriter out = response.getWriter();        ServletConfig config = this.getServletConfig();    String param = config.getInitParameter("company");    out.println("company: " + param);  }    @Override  public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {    this.doGet(request, response);  }}

 ServletContext接口

  当Servlet容器启动时,会为每一个Web应用创建一个唯一的ServletContext对象代表当前Web应用,该对象不仅封装了该Web应用的所有信息,而且实现了多个Servlet对象间的数据共享。在web.

<context-param>  <param-name>name</param-name>  <param-value>luoxn28</param-value></context-param><context-param>  <param-name>company</param-name>  <param-value>dahua</param-value></context-param>

  注意:一个<context-param>元素里只能有一个<param-name>和<param-value>,上面的配置在web.

package zzz;import java.io.IOException;import java.io.PrintWriter;import java.util.Enumeration;import javax.servlet.ServletContext;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class Hello extends HttpServlet {  @Override  public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {    // 设置响应消息编码    response.setContentType("text/html;charset=utf-8");    PrintWriter out = response.getWriter();        ServletContext context = this.getServletContext();    Enumeration<String> paramNames = context.getInitParameterNames();    while (paramNames.hasMoreElements()) {      String name = paramNames.nextElement();      String value = context.getInitParameter(name);      out.println(name + ": " + value + "<br/>");    }  }    @Override  public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {    this.doGet(request, response);  }}

 

  由于一个Web应用中所有Servlet共享一个ServletContext对象,所以ServletContext对象的域属性可以被Web应用中所有的Servlet访问。在ServletContext接口中定义了分别增加、删除、设置ServletContext域属性的4个方法:

方法功能
Object getAttribute(String name)根据指定参数获取一个匹配的域属性值
Enumeration<String> getAttributeNames()返回一个Enumeration对象,包含所有存放在ServletContext中所有域属性名
void setAttribute(String name, Object object)设置ServletContext域属性值,name-域属性名,object-域属性值
void removeAttribute(String name)根据指定的域属性名从ServletContext中移除域属性

  通过以上方法就可以实现多个Servlet间共享数据,这个具体实例就不贴代码了,网上可参考的资料很多,比如可以点击javaweb学习总结(六)——Servlet开发(二)。

5、参考资料

  1、《Java Web程序开发入门》Servlet技术章节

  2、javaweb学习总结(六)——Servlet开发(二)