Servlet技术

Servlet是用Java语言编写应用到Web服务器端的扩展技术,它先于JSP产生,可以方便地对Web应用中的HTTP请求产生处理。在Java Web程序开发中,Servlet主要用于处理各种业务逻辑,它比JSP更具有业务逻辑层的意义,而且Servlet的安全性、扩展性以及性能方面都十分优秀,它在Java Web程序开发以及MVC模式的应用方面起到了极其重要的作用。

1.Servlet基础

(1).Servlet结构体系

Servlet实质上就是按Servlet规范编写的Java类,但它可以处理Web应用中的相关请求。Servlet是一个标准,其具体细节由Servlet容器进行实现,如Tomcat、JBoss等。在J2EE架构中,Servlet结构体系的UML图如下图所示。
在这里插入图片描述
图中,Servlet对象、ServletConfig对象与Serializable对象是接口对象,其中Serializable是java.io包中的序列化接口,Servlet对象和ServletConfig对象是javax.servlet包中定义的对象,这两个对象定义了Servlet的基本方法以及封装了Servlet的相关配置信息。GenericServlet对象是一个抽象类,它分别实现了上述3个接口,该对象为Servlet接口及ServletConfig接口提供了部分实现,但它并没有对HTTP请求处理进行实现,这一操作由它的子类HttpServlet进行实现。这个对象为HTTP请求中POST、GET等类型提供了具体的操作方法,所以通常情况下,我们所编写的Servlet对象都是继承于HttpServlet,在开发中,所使用的具体的Servlet对象就是HttpServlet对象,原因是HttpServlet是Servlet的实现类,并提供了HTTP请求的具体方法。

(2).Servlet技术特点

Servlet使用Java语言编写,它不仅继承了Java语言中的优点,而且还对Web的相关应用进行了封装,同时Servlet容器还提供了对应用的相关扩展,无论是在功能、性能、安全等方面都十分优秀,其技术特点表现在以下几方面。

功能强大

Servlet采用Java语言编写,它可以调用Java API中的对象及方法。此外,Servlet对象对Web应用进行了封装,提供了Servlet对Web应用的编程接口,还可以对HTTP请求进行相应的处理,如处理提交数据、会话跟踪、读取和设置HTTP头信息等。由于Servlet既拥有Java提供的API,而且还可以调用Servlet封装的ServletAPI编程接口,因此,它在业务功能方面十分强大。

可移植

Java语言是跨平台的,所谓跨平台是指程序的运行不依赖于操作系统平台,它可以运行到多个系统平台中,如目前常用的操作系统Windows、Linux和UNIX等,由于Servlet使用Java语言编写,所以,Servlet继承了Java语言的优点,程序一次编码,多平台运行,拥有超强的可移植性。

性能高效

Servlet对象在Servlet容器启动时被初始化,当第一次被请求时,Servlet容器将其实例化,此时它贮存于内存中。如果存在多个请求,Servlet不会再被实例化,仍然由此Servlet对其进行处理。每一个请求是一个线程,而不是一个进程,因此,Servlet对请求处理的性能是十分高效的。

安全性高

Servlet使用了Java的安全框架,同时Servlet容器还可以为Servlet提供额外的功能,它的安全性是非常高的。

可扩展

Java语言是面向对象的编程语言,Servlet由Java语言编写,所以它继承了Java的面向对象的优点。在业务逻辑处理中,可以通过封装、继承等来扩展实际的业务需要,其扩展性非常强。

(3).Servlet与JSP的区别

Servlet是使用Java Servlet接口(API)运行在Web应用服务器上的Java程序,其功能十分强大,它不但可以处理HTTP请求中的业务逻辑,而且还可以输出HTML代码来显示指定页面。而JSP是一种在Servlet规范之上的动态网页技术,在JSP页面中,同样可以编写业务逻辑处理HTTP请求,也可以通过HTML代码来编辑页面,在实现功能上,Servlet与JSP貌似相同,实质存在一定的区别,主要表现在以下几个方面

角色不同

JSP页面可以存在HTML代码与Java代码并存的情况,而Servlet需要承担客户请求与业务处理的中间角色,只有调用固定的方法才能将动态内容输出为静态的HTML,所以,JSP更具有显示层的角色。

编程方法不同

使用Servlet开发Web应用程序需要遵循Java的标准,而JSP需要遵循一定脚本语言规范。Servlet中,需要调用Servlet提供的相关API接口方法才可以对HTTP请求及业务进行处理,对业务逻辑方面的处理功能更加强大。JSP中,通过HTML代码与JSP内置对象实现对HTTP请求以及页面的处理,其显示功能更加强大。

Servlet需要编译后进行

Servlet需要在Java编译器编译后才可以运行,JSP由JSP Container对其进行管理,所以无论JSP文件被创建还是修改,都不需要对其编译即可执行。

速度不同

在每次执行不同内容的动态JSP页面时,JSP Container都要对其自动编译,所以,它的效率低于Servlet的执行效率。

(4).Servlet代码结构

Java中,Servlet是指HttpServlet对象,在声明一个对象为Servlet时,需要继承HttpServlet类。HttpServlet是Servlet接口的一个实现类,继承该类后,重写HttpServlet类中的方法对HTTP请求进行处理。

package org.life.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import sun.security.krb5.internal.crypto.Des;

public class TestServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
    public TestServlet() {
        super();
    }
    
    //初始化方法
    public void init() throws ServletException {
    }
    //处理HTTP Get请求
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	}
	//处理HTTP Post请求
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	}
	//处理HTTP Put请求
	protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
	}
	//处理HTTP Delete请求
	protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
	}
	//销毁方法
	public void destroy() {
		super.destroy();
	}
	
}

上述代码显示了一个Servlet对象的代码结构,Test Servlet类通过继承HTTP Servlet类被声明为一个Servlet对象。该类中包含6个方法,其中init()方法与destory()方法为Servlet初始化与生命周期结束所调用的方法,其余的4个方法为Servlet针对处理不同的HTTP请求类型所提供的方法。

2. ServletAPI编程常用接口和类

Servlet是运行在服务器端的Java应用程序,由Servlet容器对其进行管理,当用户对容器发送HTTP请求时,容器将通知相应的Servlet对象进行处理,完成用户与程序之间的交互。

(1).Servlet接口

Servlet的运行需要Servlet容器的支持,Servlet容器通过调用Servlet对象提供的标准API接口,对请求进行处理。在Servlet开发中,任何一个Servlet对象都要直接或间接地实现javax.servlet.Servlet接口。在该接口中包含5个方法,其功能及作用如下表所示。

方法说明
public void init(ServletConfig config)Servlet实例化后,Servlet容器调用该方法来玩完成初始化工作
public void service(ServletRequest request, ServletResponse response)用于处理客户端的请求
public void destroy()当Servlet对象从Servlet容器中移除时,容器调用该方法,以便释放资源
public ServletConfig getServletConfig()用于获取Servlet对象的配置信息,返回ServletConfig对象
public String getServletInfo()返回有关Servlet信息,它是纯文本格式的字符串,如作者、版本等

(2).ServletConfig接口

ServletConfig接口位于javax.servlet包中,它封装了Servlet的配置信息,在Servlet初始化期间被传递。每一个Servlet都有且只有一个ServletConfig对象。该对象定义了4个方法

方法说明
public String getInitParameter(String name)返回String类型名称为name的初始化参数值
public Enumeration getInitParameterNames()获取所有初始化参数名的枚举类型
public ServletContext getServletContext()用于获取Servlet上下文对象
public String getServletName()返回Servlet对象的实例名

(3).HttpServletRequest接口

HttpServletRequest接口位于javax.servlet.http包中,继承了javax.servlet.ServletRequest接口

方法说明
public String getContextPath()返回请求的上下文路径,此路径以"/"开头
public Cookie[] getCookies()返回请求中发送的所有cookie对象,返回值为cookie数组
public String getMethod()返回请求所使用的HTTP类型,如get、post等
public String getQueryString()返回请求中参数的字符串形式,如请求MyServlet?username=mr,则返回username=mr
public String getRequestURI()返回主机名到请求参数之间的字符串形式
public StringBuffer getRequestURL()返回请求的URL,此URL中不包含请求的参数。注意此方法返回的数据类型为StringBuffer
public String getServletPath()返回请求URI中的Servlet路径的字符串,不包含请求中的参数信息
public HttpSession getSession()返回与请求相关的HttpSession对象

(4).HttpServletResponse接口

HttpServletResponse接口位于javax.servlet.http包中,它继承了javax.servlet.ServeltResponse接口,同样是一个非常重要的对象

方法说明
public void addCookie(Cookie cookie)向客户端写入cookie信息
public void sendError(int sc)发送一个错误状态码为sc的错误响应到客户端
public void sendError(int sc, String msg)发送一个包含错误状态码以及错误信息的响应到客户端,参数sc为错误状态码,参数msg为错误信息
public void sendRedirect(String location)使用客户端重定向到新的URL,参数location为新的地址

(5).GenericServlet类

在编写一个Servlet对象时,必须实现javax.servlet.Servlet接口,在Servlet接口中包含5个方法,也就是说创建一个Servlet对象要实现这5个方法,这样操作非常不方便。javax.servlet.GenericServelt类简化了此操作,实现了Servlet接口。

public abstract class GenericServlet extends Object implements Servlet,ServletConfig,Serializable

GenericServlet类是一个抽象类,分别实现了Servlet接口与ServletConfig接口。该类实现了除service()之外的其他方法,在创建Servlet对象时,可以继承GenericServlet类来简化程序中的代码,但需要实现service()方法。

(6).HttpServlet类

javax.servlet.http.HttpServlet类对GenericServlet类进行了扩展,为HTTP请求的处理提供了灵活的方法。

public abstract class GenericServlet extends GenericServlet implements Serializable

HttpServlet类仍然是一个抽象类,实现了service()方法,并针对HTTP1.1中定义的7种请求类型提供了相应的方法——doGet()、doPost()、doPut()、doDelete()、doHead()、doTrace()、doOptions()方法。在这7个方法中,除了对doTrace()与doOptions()方法进行简单实现外,HttpServlet类并没有对其他方法进行实现,需要开发人员在使用过程中根据实际需求对其进行重写。

3.Servlet开发

(1).Servlet配置

要使Servlet对象正常地运行,需要进行适当的配置,以告知Web容器哪一个请求调用哪一个Servlet对象处理,对Servlet起到一个注册的作用。Servlet的配置包含在web.xml文件中,主要通过以下两步进行设置

1.声明Servlet对象

在web.xml文件中,通过<servlet>标签声明一个Servlet对象。在此标签下包含两个主要子元素,分别为<servlet-name>与<servlet-class>。其中,<servlet-name>元素用于指定Servlet的名称,该名称可以为自定义的名称;<servlet-class>元素用于指定Servlet对象的完整位置,包含Servlet对象的包名与类名,其语句声明如下:

<servlet>
	<servlet-name>SimpleServlet</servlet-name>
	<servlet-class>com.life.SimpleServlet</servlet-class>
</servlet>
2.映射Servlet

在web.xml文件中声明了Servlet对象后,需要映射访问Servlet的URL。该操作使用<servlet-mapping>标签进行配置。<servlet-mapping>标签包含两个子元素,分别为<servlet-name>与<url-pattern>。其中,<servlet-name>元素与<servlet>标签中的<servlet-name>元素相对应,不可以随便命名。<url-pattern>元素用于映射访问URL。其配置方法如下:

<servlet-mapping>
	<servlet-name>SimpleServlet</servlet-name>
	<servlet-class>/SimpleServlet</servlet-class>
</servlet-mapping>

4.Servlet过滤器

Servlet过滤器主要用于对客户端(浏览器)的请求进行过滤处理,现将过滤后的请求转交给下一资源,它在javaWeb开发中具有十分重要的作用

(1).什么是过滤器

Servlet过滤器与Servlet十分相似,但它具有拦截客户端(浏览器)请求的功能,Servlet过滤器可以改变请求中的内容来满足实际开发中的需要。对于程序开发人员而言,过滤器实质上就是在Web应用服务器上的一个Web应用组件,用于拦截客户端(浏览器)与目标资源的请求,并对这些请求进行一定过滤处理再发送给目标资源。过滤器的处理方式如下所示。
在这里插入图片描述
从上图可以看出,在Web服务器中部署了过滤器以后,不仅客户端发送的请求会经过过滤器的处理,而且请求在发送到目标资源处理以后,请求的回应信息也同样要经过过滤器。
如果一个Web应用中使用一个过滤器不能解决实际中的业务需要,那么可以部署多个过滤器对业务请求进行多次处理,这样做就组成了一个过滤器链。,如下图所示:
在这里插入图片描述

(2).过滤器核心对象

过滤器对象放置在javax.servlet包中,其名称为Filter,它是一个接口。除这个接口外,与过滤器相关的对象还有FilterConfig对象与FilterChain对象,这两个对象也同样是接口对象,位于javax.servlet包中,分别为过滤器的配置对象与过滤器的传递工具。在实际开发中,定义过滤器对象只需要直接或间接地实现Filter接口即可。
在这里插入图片描述

Filter接口

每一个过滤器对象都要直接或间接地实现Filter接口,在Filter接口中定义了3个方法,分别为init()方法,doFilter()方法和destroy()方法,其方法声明及说明如下所示

方法 声明说明
public void init(FilterConfig filterConfig) throws ServletException过滤器初始化方法,该方法在过滤器初始化时调用
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,ServletException对请求进行过滤处理
public void destroy()销毁方法,以便释放资源
FilterConfig接口

FilterConfig接口由Servlet容器进行实现,主要用于获取过滤器中的配置信息,其方法声明及其说明如下所示。

方法 声明说明
public String getFilterName()用于获取过滤器的名字
public ServletContext getServletCOntext()获取Servlet上下文
public String getInitParameter(String name)获取过滤器的初始化参数
public Enumeration getInitParameterNames()获取过滤器的所有初始化参数
FilterChain接口

FilterChain接口仍然由Servlet容器进行实现,在这个接口中只有一个方法,其方法声明如下:

public void doFilter(ServletRequest request, ServletResponse response) throws IOException,ServletException

该方法用于将过滤后的请求传递给下一个过滤器,如果此过滤器已经是过滤器链中的最后一个过滤器,那么将请求传送给目标资源。

(3).过滤器创建与配置

package org.life.filter;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class MyFilter implements Filter {
    public MyFilter() {
    }
    
    //初始化方法
  	public void init(FilterConfig fConfig) throws ServletException {
  		//初始化处理
  	}

  	//过滤处理方法
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		// 过滤处理
		chain.doFilter(request, response);
	}

	public void destroy() {
		// TODO Auto-generated method stub
	}
}

过滤器中的init()方法用于对过滤器的初始化进行处理,destroy()方法是过滤器的销毁方法,主要用于释放资源,对于过滤处理的业务逻辑需要编写到doFilter()方法中,在请求过滤处理后,需要调用chain参数的doFilter()方法将请求向下传递给下一过滤器或目标资源。

Tips:使用过滤器并不一定要将请求向下传递到下一过滤器或目标资源,如果业务逻辑需要,也可以在过滤处理后,直接回应于客户端。

过滤器与Servlet十分相似,在创建之后同样需要对其进行配置,过滤器的配置主要分为声明过滤器对象和创建过滤器映射。

<!-- 过滤器声明 -->
  <filter>
  	<!-- 过滤器的名称 -->
  	<filter-name>MyFilter</filter-name>
  	<!-- 过滤器的完整类名 -->
  	<filter-class>org.life.MyFilter</filter-class>
  </filter>
  <!-- 过滤器映射 -->
  <filter-mapping>
  	<!-- 过滤器名称 -->
  	<filter-name>MyFilter</filter-name>
  	<!-- 过滤器URL映射 -->
  	<url-pattern>/MyFilter</url-pattern>
  </filter-mapping>

<filter>标签用于声明过滤器对象,在这个标签中必须配置两个子元素,分别为过滤器的名称与过滤器完整类名,其中<filter-name>用于定义过滤器的名称,<filter-class>用于指定过滤器的完整类名。
<filter-mapping>标签用于创建过滤器的映射,它的主要作用就是指定Web应用中,哪些URL应用哪一个过滤器进行处理。在<filter-mapping>标签中需要指定过滤器的名称与过滤器的URL映射,其中<filter-name>用于定义过滤器的名称,<url-pattern>用于指定过滤器应用的URL。

这里举一个例子,用来实现创建一个过滤器,实现网站访问计算器的功能,并在web.xml文件的配置中将网站访问量的初始指设置为5000。

(4).字符编码过滤器

在这里插入图片描述
java Web程序开发中,由于Web容器内部所使用的编码格式不支持中文字符集,所以处理浏览器请求中的中文数据就会出现乱码现象。
解决此问题的方法非常简单,在业务处理中重新指定中文字符集进行编码即可解决。在实际开发中,如果通过每一个业务处理指定中文字符集编码,则操作过于繁琐,而且容易遗漏某一个业务中的字符编码设置;如果通过过滤器来处理字符编码,就可以做到简单又万无一失。
这里再举一个例子,用于实现图书信息的添加功能,并创建字符编码过滤器,避免中文乱码现象的产生。

5.Servlet监听器

在Servlet技术中已经定义了一些事件,并且可以针对这些事件来编写相关的事件监听器,从而对事件做出相应处理。例如,想要在Web应用程序启动和关闭时执行一些任务(如数据库连接的建立和释放),或者想要监控Session的创建和销毁,那么就可以通过监听器来实现。

(1).Servlet监听器简介

监听器的作用是监听Web容器的有效期事件,因此它是由容器管理的。利用Listener接口监听在容器中的某个执行程序,并且根据其应用程序的需求做出适当的响应
在这里插入图片描述

(2).Servlet上下文监听

Servlet上下文监听可以监听ServletContext对象的创建、删除以及属性添加、删除和修改操作,该监听器需要用到如下两个接口:

1.ServletContextListener接口

该接口存放在javax.servlet包内,它主要实现监听ServletContext的创建和删除。ServletContextListener接口提供了两个方法,它们也被称为“Web应用程序的生命周期方法”。下面分别进行介绍。
contextInitialized(ServletContextEvent event)方法:通知正在收听的对象,应用程序已经被加载及初始化。
contextDestroyed(ServletContextEvent event)方法:通知正在收听的对象,应用程序已经被载出,即关闭。

2.ServletAttributeListener接口

该接口存放在javax.servlet包内,主要实现监听ServletContext属性的增加、删除和修改。ServletAttributeListener接口提供了以下3个方法。
attributeAdded(ServletContextAttributeEvent event)方法:当有对象加入Application的范围内时,通知正在收听的对象。
attributeReplaced(ServletContextAttributeEvent event)方法:当在Application的范围内有对象取代另一个对象时,通知正在收听的对象
attributeRemoved(ServletContextAttributeEvent event)方法:当有对象从Application的范围移除时,通知正在收听的对象。

:创建监听器,代码如下:

public class MyContentListener implements ServletContextListener {
	...//省略了监听器中间的相关代码
}

要让Web容器在Web应用程序启动时通知MyServletContextListener,需要在web.xml文件中使用<listener>元素来配置监听器类,对于本实例,在web.xml中需要配置

<listener>
	<listener-class>com.life.listener.MyContentListener</listener-class>
</listener>

(3).HTTP会话监听

HTTP会话监听(HTTPSession)信息,有4个接口可以进行监听。

1.HttpSessionListener接口

HttpSessionListener接口实现监听HTTP会话创建、销毁。HttpSessionListener接口提供了以下两个方法。
sessionCreated(HttpSessionEvent event)方法:通知正在收听的对象,session已经被加载及初始化。
sessionDestroyed(HttpSessionEvent event)方法:通知正在收听的对象,session已经被载出(HttpSessionEvent类的主要方法是getSession(),可以使用该方法回传一个session对象)。

2.HttpSessionActivationListener接口

HttpSessionActivationListener接口实现监听HTTP会话active和passivate。HttpSessionActivationListener接口提供了以下3个方法。
attributeAdded(HttpSessionBindingEvent event)方法:当有对象加入session的范围时,通知正在收听的对象
attributeReplaced(HTTPSessionBindingEvent event)方法:当在session的范围有对象取代另一个对象时,通知正在收听的对象。
attributeRemoved(HttpSessionBindingEvent event)方法:当有对象从session的范围移除时,通知正在收听的对象(HttpSessionBindingEvent类主要有3个方法:getNames()、getSession()和getValues()。

3.HttpBindingListener接口

HttpBindingListener接口实现监听HTTP会话中对象的绑定信息,它是唯一不需要再web.xml文件中设定Listener的。HttpBindingListener接口提供了以下两个方法。
valueBound(HttpSessionBindingEvent event)方法:当有对象加入session的范围内会被自动调用
valueUnbound(HttpSessionBindingEvent event)方法:当有对象从session的范围内移除时会被自动调用。

4.HttpSessionAttributeListener接口

HttpSessionAttributeListener接口实现监听HTTP会话中属性的设置请求。HttpSessionAttributeListener接口提供了以下两个方法。
sessionDidActivate(HttpSessionEvent event)方法:通知正在收听的对象,它的session已经变为有效状态。
sessionWillPassivate(HttpSessionEvent event)方法:通知正在收听的对象,它的session已经变为无效状态。

(4).Servlet请求监听

在Servlet2.4规范中新增加了一个技术,就是可以监听客户端请求。一旦能够在监听程序中或取客户端请求,就可以对请求进行统一处理。要实现客户端的请求和请求参数设置的监听需要实现两个接口。

1.ServletRequestListener接口

ServletRequestListener接口提供了以下两个办法。
requestInitialized(ServletRequestEvent event)方法:通知正在收听的对象,ServletRequest已经被加载及初始化。
requestDestroyed(ServletRequestEvent event)方法:通知正在收听的对象,ServletRequest已经被载出,即关闭。

2.ServletRequestAttributeListener接口

ServletRequestAttributeListener接口提供了以下3个方法
attributeAdded(ServletRequestAttributeEvent event)方法:当有对象加入request的范围内,通知正在收听的对象。
attributeReplaced(ServletRequestAttributeEvent event)方法:当在request的范围内有对象取代另一个对象时,通知正在收听的对象。
attributeRemoved(ServletRequestAttributeEvent event)方法:当有对象从request的范围内移除,通知正在收听的对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值