`

Servlet

    博客分类:
  • Java
阅读更多

 

一、认识 Servlet

         Servlet :服务器端小程序,是 Java 实现的 CGI( 通用网管接口程序 ) ,但是与传统的 CGI 不同的是, Servlet 程序采用的是多线程的处理方式,而传统的 CGI 是使用多线程的处理方式,所以 Servlet 要比传统的 CGI 快。

         所有的 Servlet 程序必须放在 WEB 目录中执行,依靠 WEB 容器执行

         Servlet 本身就是一个类。本身不需要由主方法调用执行

         Servlet JavaBean 一样必须保存在 WEB-INF/classes 目录之中

         一个类必须继承 HttpServlet ,那么此类才称为是一个 Servlet 程序

         Servlet 程序必须放在一个包中。

 

在开发时,需要配置其环境变量,通过分析 Tomcat 的执行流程: *.jsp--->*.java--->*.class 文件,可以发现 Tomcat 中有需要的扩展包“ D:\apache-tomcat-6.0.33-windows-x64\lib\servlet-api.jar , 所以我们可以把这个 jar 包拷贝到 JDK 的编译环境下“ D:\Program Files\Java\jre6\lib\ext ”,此文件夹表示的是存放所有的扩展文件。

         前面我们说了,一个 Servlet 程序本身是不能直接使用主方法调用的,必须放在 WEB 容器中执行, WEN-INF WEB 目录中最安全的文件夹,所以外部肯定无法执行访问,所以,如果想让一个 Servlet 程序可以正常使用,则必须在 web.xml 中配置( Eclipse 中创建 Servlet 会自动在 web.xml 中配置)。

 

二、 Servlet 生命周期:

装载 --> 创建 --> 初始化 --> 服务(多次执行) --> 销毁 --> 卸载

上面的周期对于 Servlet 本身只会关心初始化、服务、销毁三个操作。

         1 、初始化:正常情况下只有一次初始化,但是如果一个 Servlet 长时间不使用之后又再次使用,则会重新初始化;

public void init(ServletConfig config) throws ServletException//可以取得初始化参数
public void init() throw ServletException//如果不需要取得初始化参数的话则使用此方法

 

 

2 、服务:一个 Servlet 肯定会服务多次,如果一个 Servlet 长时间不服务,则认为没用了,等待销毁;

public void service(ServletRequest req,ServletResponse res) throws ServletException,
java.io.IOException
//一般不会直接直接覆写此方法,而是覆写:
protected void doGet(HttpServletRequest request, HttpServletResponse response) 
		throws ServletException, IOException {}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException {}

 

3 、销毁:正常情况下也只有一次,容器关闭时销毁,当然,如果一个 Servlet 长时间不使用,则也会被自动销毁;

注:

         ·如果现在存在两个初始化方法,则肯定先使用存在 ServletConfig 对象的初始化方法,因为要取得初始化参数。

         ·默认情况下,一个 Servlet 只在第一次运行的时候初始化,也可以经过配置,让其在容器启动的时候就可以进行初始化操作,修改 web.xml 即可

<load-on-startup>1</load-on-startup>
 

 

         Servlet doGet doPost 方法定义里可以发现, doGet doPost 本身就直接存在 request response 对象,所以我们需要关心的只是如何取得 session application 对象即可。

HttpSession session= request.getSession() ServletContext application=this.getServletContext();

这里还会涉及到一个服务器端跳转和客户端跳转,简单理解是服务器端跳转地址栏内容不变,可以通过 request.getRequestDispatcher("success.jsp").forward(request,response) 实现,可以传递 request 范围值,而客户端跳转则相反,并且通过 response.sendRedirect("fail.jsp") ,详细的可以看 Get Post ,客户端跳转与服务器端跳转

 

 

我们知道 JSP 可以完成的功能 Servlet 都可以完成,但是 Servlet 有一些功能是 JSP 无法完成的,因为 Servlet 在使用的时候分为三种:

                   ·普通 Servlet :引申出来就是 MVC 设计模式: JSP+Servlet+JavaBean

                   ·过滤 Servlet :过滤器

                   ·监听 Servlet :监听器

 

三、过滤器

         如何一个程序要想实现过滤器,则直接实现 Filter 接口即可,此接口中存在:初始化、过滤、销毁三个方法。

         过滤器技术是 Servlet2.3 规范中新增的功能,它与 Servlet 有点类似,都可以通过配置截获和处理特定的 HTTP 请求与响应。

         过滤器与 Servlet 的区别在于通常 Servlet 是面向功能的用于充当控制器对单一请求进行处理,而过滤器是面向资源的,它对某一类资源的请求进行统一处理。过滤器可以在请求到达资源之前和响应返回用户前进行加工处理,也就是说它可以在用户请求被响应资源( JSP Servlet )处理前、处理后动态的修改 Request Response 对象。

其适用场景:

         1 、字符编码过滤

                   在用户请求被 Servlet 处理前,设置 Request 的字符编码以解决乱码问题;

         2 、用户登陆与权限控制

                   用户请求到达资源前判断用户是否登陆( Session , 是否对资源有权限,如果没有则请求重定位到登陆或出错页;

         3 、统一缓存控制

                   对某类资源如图片文件夹、 CSS 文件夹下的资源请求在 Response 响应头上添加缓存有效期设置,对经常变化的页面如首页、新闻在 Response

         4 、资源保护

范例:字符编码过滤 CharsetFilter.java

package org.lxh.util;
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 CharsetFilter implements Filter {
	private String charset;
    	public CharsetFilter() {
   	 }
	public void destroy() {
	}
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		request.setCharacterEncoding(charset);
		
		chain.doFilter(request, response);//如果存在多个过滤器,这里的chain就是用来传递到下一个的,这里的FilterChain表示一个过滤链,它就表示放行,而此类中存在一个doFilter方法,表示将请求转送到目的地。过滤器要执行两次,FilterChain之前执行一次,之后在执行一次
	}
	public void init(FilterConfig fConfig) throws ServletException {
		charset = fConfig.getInitParameter("charset");//读取web.xml中的配置文件下的参数值
	}

}
 

web.xml

<filter>
    <display-name>CharFilter</display-name>
    <filter-name>CharFilter</filter-name>
    <filter-class> org.lxh.util.CharsetFilter</filter-class>
    <init-param>
      <description>charset</description>
      <param-name>charset</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>CharFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

 

此时过滤器的映射路径“ /* ”表示对一切的请求进行过滤,从根目录下开始过滤。

 

范例 2 ,判断权限 UserFilter.java

package com.theone.control;

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;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;

/**
 * Servlet Filter implementation class UserFilter
 */
public class UserFilter implements Filter {
	
	private static Logger logger=Logger.getLogger(UserFilter.class);
    /**
     * Default constructor. 
     */
    public UserFilter() {
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see Filter#destroy()
	 */
	public void destroy() {
		// TODO Auto-generated method stub
	}

	/**
	 * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
	 */
	public void doFilter(ServletRequest requ, ServletResponse res, FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request=(HttpServletRequest)requ;
		HttpServletResponse response=(HttpServletResponse)res;
		HttpSession session=request.getSession();
		if(session.getAttribute("user")==null){
			logger.info("不能访问此页面");
			//response.sendRedirect(request.getContextPath()+"/login.jsp");
			java.io.PrintWriter out = response.getWriter();  
		    out.println("<html>");  
		    out.println("<script>");  
		    out.println("window.open ('"+request.getContextPath()+"/login.jsp','_top')");  
		    out.println("</script>");  
		    out.println("</html>");  
			return;
		}
		// place your code here

		// pass the request along the filter chain
		chain.doFilter(request, response);
	}

	/**
	 * @see Filter#init(FilterConfig)
	 */
	public void init(FilterConfig fConfig) throws ServletException {
		// TODO Auto-generated method stub
	}

}

 

web.xml

<filter>
    <display-name>UserFilter</display-name>
    <filter-name>UserFilter</filter-name>
    <filter-class>com.theone.control.UserFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>UserFilter</filter-name>
    <url-pattern>/servlet/*</url-pattern>
  </filter-mapping>
  <filter-mapping>
    <filter-name>UserFilter</filter-name>
    <url-pattern>/page/*</url-pattern>
  </filter-mapping>
 

 

这里指定过滤 page 下的,一般在过滤操作中,除了编码过滤可以指定“ /* ”之外,大部分的过滤都要求指定一个具体的文件夹。

 

从上面我们可以简单总结出来过滤器的使用比 Servlet 要简单一些,是以一种组件的形式插入到程序之中的,是通过 web.xml 进行配置,只要实现 Filter 接口就可以完成过滤器操作。

 

四、监听器

         监听整个 WEB 容器的运行环境,譬如:服务器启动,服务器关闭 or 有新用户来了,在整个 WEB 中监听主要分为以下两种:对上下文和 session 监听。

1 ServletContextListener: 对一个应用进行全局监听 . 随应用启动而启动 , 随应用消失而消失主要有两个方法 :

· contextDestroyed(ServletContextEvent event) :在应用关闭的时候调用

· contextInitialized(ServletContextEvent event) :在应用启动的时候调用

2 HttpSessionListener: 这个监听器主要监听一个 Session 对象被生成和销毁时发生的事件 . 对应有两个方法 :

· public void sessionCreated(HttpSessionEvent se)

· public void sessionDestroyed(HttpSessionEvent se)

 

一般来说 , 一个 session 对象被 create , 可以说明有一个新客端进入 . 可以用来粗略统计在线人数 , 注意这不是精确的 , 因为这个客户端可能立即就关闭了 , sessionDestroyed 方法却会按一定 的策略很久以后才会发生。

事件监听器可用于:

·当部署或者关闭 web 应用时,管理数据库链接或外部资源

·实现计数器

·监测 HTTPSession 的状态和属性

 

范例: AppStatuListener.java

package org.lxh.util;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import org.apache.log4j.Logger;
public class AppStatuListener implements ServletContextListener,
		HttpSessionListener, ServletRequestListener {
	public int sessionNumber;
	public int requestNumber;
	public Date appStartTime;
	public static AppStatuListener instance;
	public static Logger logger = Logger.getLogger(AppStatuListener.class.getName());

	public String getAppStartTime() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
		return sdf.format(appStartTime);
	}
	public String getAppStartedTime() {
		long mils = System.currentTimeMillis() - appStartTime.getTime();
		long s = mils / 1000 % 60;
		long m = mils / 1000 / 60 % 60;
		long h = mils / 1000 / 60 / 24;
		return h + "小时" + m + "分" + s + "秒";
	}
	public int getSessionNumber() {
		return sessionNumber;
	}
	public int getRequestNumber() {
		logger.info("发送了一个请求!");
		return requestNumber;
	}
	public static AppStatuListener getInstance() {
		return instance;
	}
	public AppStatuListener() {
		instance = this;
	}

	public void requestDestroyed(ServletRequestEvent arg0) {

	}
	/**
	 *应用程序启动
	 * @see ServletContextListener#contextInitialized(ServletContextEvent)
	 */
	public void contextInitialized(ServletContextEvent arg0) {
		appStartTime = new Date();
	}
	public void sessionCreated(HttpSessionEvent arg0) {
		sessionNumber++;
	}
	public void sessionDestroyed(HttpSessionEvent arg0) {
		sessionNumber--;
	}
	/**
	 * 请用程序销毁
	 * @see ServletContextListener#contextDestroyed(ServletContextEvent)
	 */
	public void contextDestroyed(ServletContextEvent arg0) {
		
	}
	public void requestInitialized(ServletRequestEvent arg0) {
		requestNumber++;
	}

}

 

web.xml

  <listener>
  	<listener-class>org.lxh.util.AppStatuListener</listener-class>
  </listener>

 

可以发现监听器的配置比过滤器和简单 Servlet 都容易,而且在一个项目中,如果同时出现了过滤器、监听器、简单的 Servlet ,则 web.xml 中的配置顺序如下:

<filter><filter-mapping>

<listener>

<servlet><servlet-mapping>

如果要配置 Session 超时,则在 web.xml 文件中添加:

<session-config>
  	<session-timeout>1</session-timeout>
  </session-config>

 

 

 

 

分享到:
评论

相关推荐

    javax.servlet jar包---解决找不到javax.servlet.*等问题

    当你遇到“找不到javax.servlet.*”这样的错误时,通常是因为你的项目缺少了这个库,所以需要引入`javax.servlet.jar`来解决问题。 1. **Java Servlet简介** Java Servlet是Java平台上的一个标准,用于扩展服务器...

    servlet基础与servlet容器模型

    Servlet是一个Java类,遵循javax.servlet.Servlet接口,它允许开发者扩展服务器的功能。当用户向Web服务器发送一个请求时,Servlet会接收到这个请求,处理数据,然后返回响应。Servlet的主要生命周期方法包括:`init...

    用于servlet程序的开发的servlet-jar包

    Servlet是Java平台上的一个核心组件,它允许开发者创建动态web应用程序。Servlet API是Java Servlet规范的一部分,它定义了服务器端程序如何与HTTP协议交互以及如何处理来自web客户端的请求并返回响应。`servlet.jar...

    jakarta-servletapi-4-src.zip servlet源码

    《深入理解Jakarta Servlet API 4.0源码》 Servlet技术是Java Web开发的核心,它为Web应用程序提供了服务器端的编程接口。Jakarta Servlet API 4.0是Servlet规范的最新版本,它包含了对HTTP协议处理、生命周期管理...

    Servlet基础知识总结

    ### Servlet基础知识总结 #### 一、Servlet简介 Servlet是一种服务器端的小程序,是Java平台上的一个重要的技术之一,主要用于处理客户端的HTTP请求并生成动态网页。Servlet是在服务器端运行的,能够提供各种服务...

    servlet线程安全问题

    Servlet 线程安全问题 Servlet 线程安全问题是指在使用 Servlet 编程时,如果不注意多线程安全性问题,可能会导致难以发现的错误。Servlet/JSP 技术由于其多线程运行而具有很高的执行效率,但这也意味着需要非常...

    javaEE servlet-api

    Servlet API还提供了Filter的概念,允许开发者在请求到达Servlet之前和响应离开Servlet之后对其进行拦截和处理。`javax.servlet.Filter`接口定义了`doFilter()`方法,这使得我们可以实现如认证、日志记录、数据过滤...

    Servlet3.0参考手册

    Servlet3.0是Java Web开发中的一个重要里程碑,它在Servlet2.5的基础上引入了许多新特性,极大地提高了开发效率和灵活性。这份"Servlet3.0参考手册"无疑为开发者提供了全面的API参考和实用指南。 首先,Servlet3.0...

    Java用注解的方式定义一个Servlet

    用注解的方式定义一个Servlet,就不用在web.xml中配置了。Servlet的访问URL是Servlet的必选属性,可以选择使用urlPatterns或者value定义。  像上面的AnnotationServlet可以描述成@WebServlet(name="Annotation...

    servlet-api 各种版本

    Servlet-API是Java Servlet技术的核心部分,它定义了服务器端与客户端之间交互的一系列接口和类。这个压缩包包含了Servlet-API的多个版本,分别是2.2、2.3、2.4、2.5以及3.0。每个版本的发布都带来了新的功能和改进...

    serlvet 源码 servlet-src 源文件

    `servlet-src`通常指的是Servlet的源代码,这对于理解Servlet的工作原理、学习如何编写Servlet以及进行自定义功能扩展非常有用。在这个压缩包中,我们可能会找到`javax`包,这是Java标准库的一部分,包含了Servlet...

    servlet-api中文文档

    它是Java Servlet和JavaServer Pages (JSP)技术的基础,提供了服务器端程序与Web客户端交互的能力。在这个压缩包中,包含的是对Servlet API的中文文档,可能是作者因为无法找到官方的源码和javadoc而自行整理的笔记...

    javax.servlet.jar下载

    Files contained in javax.servlet.jar: META-INF/MANIFEST.MF javax/servlet/http/LocalStrings.properties javax.servlet.http.HttpSessionBindingListener.class javax.servlet....

    Servlet3.1规范(最终版)

    Servlet3.1规范是Java服务器端编程的重要里程碑,它在原有的Servlet技术基础上进行了多项改进和扩展,极大地提升了Web应用的性能和开发效率。这个规范主要关注于Servlet、过滤器(Filter)和监听器(Listener)的...

    servlet3.0与mybatis整合的示例

    在Java Web开发中,Servlet和MyBatis是两个非常重要的技术。Servlet3.0作为Java Servlet规范的一个版本,引入了许多新特性,而MyBatis则是一个优秀的持久层框架,简化了数据库操作。本文将深入探讨如何将Servlet3.0...

    javax.servlet-api-4.0.1.jar中文文档.zip

    javax.servlet-api-***.jar中文文档.zip,java,javax.servlet-api-***.jar,javax.servlet,javax.servlet-api,***,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,javax,servlet,api,中文API文档,手册,开发...

    Head First Servlet & JSP

    《Head First Servlet & JSP》是一本非常受欢迎的IT教程,专为准备SCWCD(Sun Certified Web Component Developer)认证的读者设计。本书以其独特的学习风格,深入浅出地介绍了Servlet和JSP(JavaServer Pages)这两...

    Servlet3.1规范官方文档(中文版)

    根据提供的文件内容,以下是对Servlet3.1规范官方文档(中文版)中的知识点的详细说明。 首先,Servlet3.1官方文档是Java™ Servlet规范版本3.1的中文翻译版本。它详细描述了servlet技术规范的各个方面,包括对...

    jakarta.servlet-api-4.0.4-API文档-中英对照版.zip

    赠送jar包:jakarta.servlet-api-4.0.4.jar; 赠送原API文档:jakarta.servlet-api-4.0.4-javadoc.jar; 赠送源代码:jakarta.servlet-api-4.0.4-sources.jar; 赠送Maven依赖信息文件:jakarta.servlet-api-4.0.4....

Global site tag (gtag.js) - Google Analytics