> Java > java지도 시간 > 본문

Java의 필터, 서블릿 및 리스너에 대한 자세한 소개

黄舟
풀어 주다: 2017-07-30 13:18:36
원래의
1467명이 탐색했습니다.

이 글은 주로 Filter, Servlet, Listener 학습 자료를 소개하고 있으니 참고할만한 가치가 있으니 관심 있는 분들은

Java의 Filter, Servlet, Listener 학습 자료를 참고하시기 바랍니다.

1. 필터 기능

사용자가 요청을 변경하고 응답을 수정할 수 있는 필터 기능은 응답을 생성할 수 없으며 요청이 서블릿에 도달하기 전에 전처리할 수 있습니다. 서블릿을 떠날 때 응답을 처리할 수도 있습니다. 즉, 필터는 실제로 "서블릿 체인"(서블릿 체인)입니다.

필터에는 다음이 포함됩니다.

1) 서블릿이 호출되기 전에 차단됩니다. , 서블릿이 호출되기 전에 서블릿 요청을 확인하고;
3) 필요에 따라 요청 헤더와 요청 데이터를 수정하고;
4) 필요에 따라 응답 헤더와 응답 데이터를 수정하고;
5) 서블릿이 호출된 후 가로채기합니다.

Server setFilterConfig 메소드는 필터 처리를 준비하기 위해 매번 한 번만 호출되며, doFilter 메소드는 다양한 요청을 처리하기 위해 여러 번 호출됩니다. FilterConfig 인터페이스에는 필터 이름과 초기화 매개변수 정보를 찾는 메소드가 있습니다. FilterConfig가 비어 있으면 필터가 종료되었음을 나타냅니다.

각 필터는 doFilter() 메소드에서 현재 요청 및 응답을 가져옵니다. 이 메소드에서는 요청 및 응답에 대한 모든 작업을 수행할 수 있습니다(데이터 수집, 데이터 패키징 등 포함). ) 이 메서드는 제어권을 다음 필터로 넘깁니다. 필터는 doFilter() 메서드로 끝납니다. 필터가 요청 처리를 중단하고 응답을 완전히 제어하려는 경우
예:
먼저 새 필터를 만듭니다. Filter


/** 
 * 
 */ 
package com.ee.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; 
 
/** 
 * @author Administrator 
 * 
 */ 
public class LogFilter implements Filter { 
 private FilterConfig filterConfig; 
 
 public FilterConfig getFilterConfig() { 
  System.err.println("...getFilterConfig..."); 
  return filterConfig; 
 } 
 
 public void setFilterConfig(FilterConfig filterConfig) { 
  System.err.println("...setFilterConfig..."); 
  this.filterConfig = filterConfig; 
 } 
 
 /* (non-Javadoc) 
  * @see javax.servlet.Filter#destroy() 
  */ 
 @Override 
 public void destroy() { 
  System.err.println("...filter destroy..."); 
 } 
 
 /* (non-Javadoc) 
  * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) 
  */ 
 @Override 
 public void doFilter(ServletRequest request, ServletResponse response, 
   FilterChain chain) throws IOException, ServletException { 
  System.err.println("...doFilter..."); 
  chain.doFilter(request, response);//看到这没,这只要是传递下一个Filter 
 } 
 
 /* (non-Javadoc) 
  * @see javax.servlet.Filter#init(javax.servlet.FilterConfig) 
  */ 
 @Override 
 public void init(FilterConfig filterConfig) throws ServletException { 
  System.err.println("...init Filter..."); 
  this.filterConfig = filterConfig; 
 } 
 
}
로그인 후 복사

가 웹에 구성되어 있습니다. 내부에는...doFilter...가 인쇄되는 것을 볼 수 있습니다.


2. 서블릿 기능

1). 서블릿이란 무엇입니까?

 Servlet은 Java Servlet API(애플리케이션 프로그래밍 인터페이스)와 관련 클래스 및 메소드를 사용하는 Java 프로그램입니다. Java Servlet API 외에도 서블릿은 API를 확장하고 추가하는 Java 클래스 패키지를 사용할 수도 있습니다. 서블릿은 Java 지원 웹 서버 또는 애플리케이션 서버에서 실행되며 해당 서버의 기능을 확장합니다. Java 서블릿은 웹 브라우저에 대한 Java 애플릿과 마찬가지로 웹 서버에 대한 것입니다. 서블릿은 웹 서버에 로드되어 웹 서버 내에서 실행되는 반면, 애플릿은 웹 브라우저에 로드되어 웹 브라우저 내에서 실행됩니다. Java Servlet API는 서블릿과 Java 지원 서버 간의 표준 인터페이스를 정의하여 서블릿을 서버 간 플랫폼으로 만듭니다.

 서블릿은 웹에서 요청 및 응답 서비스를 제공하는 프레임워크를 생성하여 서버의 기능을 확장합니다. 클라이언트가 서버에 요청을 보내면 서버는 요청 정보를 서블릿에 보내고 서블릿이 서버가 클라이언트에 반환하는 응답을 빌드하도록 할 수 있습니다. 웹 서버가 시작되거나 클라이언트가 처음으로 서비스를 요청할 때 서블릿이 자동으로 로드될 수 있습니다. 로드 후 서블릿은 다른 클라이언트가 요청할 때까지 계속 실행됩니다. 서블릿에는 다양한 기능이 있습니다. 예를 들어, Servlet은 다음 기능을 완료할 수 있습니다. (1) 고객 요청의 성격에 따라 동적 콘텐츠가 포함된 완전한 HTML 페이지를 생성하고 반환합니다.
 (2) 기존 HTML 페이지에 삽입할 수 있는 HTML 페이지의 일부(HTML 조각)를 만듭니다.
 (3) 다른 서버 리소스(데이터베이스 및 Java 기반 애플리케이션 포함)와 통신합니다.

 (4) 여러 클라이언트를 사용하여 연결을 처리하고, 여러 클라이언트로부터 입력을 받고, 결과를 여러 클라이언트에 브로드캐스트합니다. 예를 들어, 서블릿은 다중 참가자 게임 서버일 수 있습니다.

 (5) 단일 연결 모드에서 데이터 전송이 허용되는 경우, 서버에서 브라우저의 애플릿으로 새로운 연결을 열고 연결을 유지하세요. 애플릿은 또한 클라이언트의 브라우저와 서버 간의 연결을 시작할 수 있으므로 클라이언트와 서버가 간단하고 효율적으로 세션을 수행할 수 있습니다. 통신은 IIOP와 같은 맞춤형 프로토콜이나 표준을 통해 이루어질 수 있습니다.
 (6) 이미지 변환, 서버측 포함(SSI) 등 특수 처리를 위해 MIME 유형 필터링 데이터를 사용합니다.

 (7) 모든 서버에 대해 표준 루틴에 대한 맞춤형 처리를 제공합니다. 예를 들어 서블릿은 사용자 인증 방법을 수정할 수 있습니다.


2). 서블릿의 생명주기

서블릿의 생명주기는 웹 서버의 메모리에 로드될 때 시작되어 서블릿이 종료되거나 다시 로드될 때 끝납니다.

(1) 초기화
다음 시간에 서블릿을 로드합니다.
자동 로드 옵션이 구성된 경우 서버 시작 시 자동으로 로드됩니다.
클라이언트가 이후 처음으로 서블릿에 요청할 때 다시 로드합니다. 서버가 시작됩니다
서블릿이 로드되면 서버는 서블릿 인스턴스를 생성하고 서블릿의 init() 메서드를 호출합니다. 초기화 단계 동안 Servlet 초기화 매개변수는 Servlet 구성 객체에 전달됩니다.

(2) 요청 처리
 서버에 도착하는 클라이언트 요청에 대해 서버는 해당 요청에 특정한 "요청" 객체와 "응답" 객체를 생성합니다. 서버는 "요청" 및 "응답" 개체를 전달하는 데 사용되는 서블릿의 service() 메서드를 호출합니다. service() 메서드는 "요청" 개체에서 요청 정보를 얻고, 요청을 처리하고, "응답" 개체의 메서드를 사용하여 응답을 클라이언트에 다시 전달합니다. service() 메서드는 요청을 처리하기 위해 doGet(), doPost() 또는 기타 메서드와 같은 다른 메서드를 호출할 수 있습니다.

(3) 종료
 서버에 더 이상 서블릿이 필요하지 않거나 서블릿의 새 인스턴스를 다시 로드하면 서버는 서블릿의 destroy() 메서드를 호출합니다.

3) Java Servlet API
 JSDK(Java Servlet Development Tool)는 Servlet을 작성할 때 필요한 여러 소프트웨어 패키지를 제공합니다. 여기에는 모든 서블릿에 대한 두 가지 기본 패키지인 javax.servlet 및 javax.servlet.http가 포함됩니다. Java Servlet 개발 도구는 Sun 웹사이트에서 다운로드할 수 있습니다. 다음은 javax.servlet.http에서 제공하는 HTTP Servlet 응용 프로그래밍 인터페이스를 주로 소개합니다.
 HTTP 서블릿은 HTML 형식을 사용하여 데이터를 보내고 받습니다. HTTP 서블릿을 생성하려면 특수 메서드를 사용하여 HTML 테이블을 처리하는 GenericServlet의 하위 클래스인 HttpServlet 클래스를 확장하세요. HTML 양식은

양식에는 일반적으로 입력 필드(예: 텍스트 입력 필드, 확인란, 라디오 버튼, 선택 목록)와 데이터 제출용 버튼이 포함되어 있습니다. 정보를 제출할 때 서버가 실행해야 하는 서블릿(또는 기타 프로그램)도 지정합니다. HttpServlet 클래스에는 init(), destroy(), service() 및 기타 메소드가 포함되어 있습니다. init() 및 destroy() 메소드는 상속됩니다.

(1) init() 메소드

 서블릿의 라이프 사이클에서 init() 메소드는 한 번만 실행됩니다. 서버가 서블릿을 로드할 때 실행됩니다. 서버가 시작될 때 또는 클라이언트가 처음으로 서블릿에 액세스할 때 서블릿을 로드하도록 서버를 구성할 수 있습니다. 얼마나 많은 클라이언트가 서블릿에 액세스하더라도 init()는 반복적으로 실행되지 않습니다.
 기본 init() 메서드는 일반적으로 요구 사항을 충족하지만 일반적으로 서버 측 리소스를 관리하기 위해 사용자 정의 init() 메서드로 재정의할 수도 있습니다. 예를 들어, GIF 이미지를 한 번만 로드하도록 사용자 정의 init()를 작성하여 GIF 이미지를 반환하고 여러 클라이언트 요청을 포함하는 서블릿의 성능을 향상시킬 수 있습니다. 또 다른 예는 데이터베이스 연결을 초기화하는 것입니다. 기본 init() 메소드는 서블릿의 초기화 매개변수를 설정하고 ServletConfig 객체 매개변수를 사용하여 구성을 시작하므로 init() 메소드를 재정의하는 모든 서블릿은 이러한 작업이 계속 수행되도록 super.init()를 호출해야 합니다. service() 메서드를 호출하기 전에 init() 메서드가 완료되었는지 확인해야 합니다.

(2) service() 메소드
 service() 메소드는 서블릿의 핵심이다. 클라이언트가 HttpServlet 객체를 요청할 때마다 객체의 service() 메소드가 호출되고 "요청"(ServletRequest) 객체와 "응답"(ServletResponse) 객체가 이 메소드에 매개변수로 전달됩니다. service() 메소드는 HttpServlet에 이미 존재합니다. 기본 서비스 기능은 HTTP 요청 메소드에 해당하는 do 함수를 호출하는 것입니다. 예를 들어 HTTP 요청 메서드가 GET이면 기본적으로 doGet()이 호출됩니다. 서블릿은 서블릿이 지원하는 HTTP 메서드에 대한 기능을 재정의해야 합니다. HttpServlet.service() 메서드는 요청 메서드가 적절한 핸들러를 호출하는지 확인하므로 service() 메서드를 재정의할 필요가 없습니다. 해당 do 메소드를 재정의하면 완료됩니다.
클라이언트가 HTML 양식을 통해 HTTP POST 요청을 하면 doPost() 메서드가 호출됩니다. POST 요청과 관련된 매개변수는 별도의 HTTP 요청으로 브라우저에서 서버로 전송됩니다. 서버 측 데이터를 수정해야 하는 경우 doPost() 메서드를 사용해야 합니다.
클라이언트가 HTML 양식을 통해 HTTP GET 요청을 하거나 URL을 직접 요청하는 경우 doGet() 메서드가 호출됩니다. GET 요청과 관련된 매개변수는 URL 끝에 추가되어 이 요청과 함께 전송됩니다. doGet() 메소드는 서버 측 데이터가 수정되지 않을 때 사용해야 합니다.
 서블릿의 응답은 다음 유형 중 하나일 수 있습니다.
 브라우저가 콘텐츠 유형(예: 텍스트/HTML)에 따라 해석하는 출력 스트림.
 HTTP 오류 응답은 다른 URL, 서블릿, JSP로 리디렉션됩니다.

(3) destroy() 方法
  destroy() 方法仅执行一次,即在服务器停止且卸装Servlet 时执行该方法。典型的,将 Servlet 作为服务器进程的一部分来关闭。缺省的 destroy() 方法通常是符合要求的,但也可以覆盖它,典型的是管理服务器端资源。例如,如果 Servlet 在运行时会累计统计数据,则可以编写一个 destroy() 方法,该方法用于在未装入 Servlet 时将统计数字保存在文件中。另一个示例是关闭数据库连接。
当服务器卸装 Servlet 时,将在所有 service() 方法调用完成后,或在指定的时间间隔过后调用 destroy() 方法。一个Servlet 在运行service() 方法时可能会产生其它的线程,因此请确认在调用 destroy() 方法时,这些线程已终止或完成。

(4) GetServletConfig()方法
  GetServletConfig()方法返回一个 ServletConfig 对象,该对象用来返回初始化参数和  ServletContext。ServletContext 接口提供有关servlet 的环境信息。

(5) GetServletInfo()方法
  GetServletInfo()方法是一个可选的方法,它提供有关servlet 的信息,如作者、版本、版权。
  当服务器调用sevlet 的Service()、doGet()和doPost()这三个方法时,均需要 “请求”和“响应”对象作为参数。“请求”对象提供有关请求的信息,而“响应”对象提供了一个将响应信息返回给浏览器的一个通信途径。javax.servlet 软件包中的相关类为ServletResponse和ServletRequest,而javax.servlet.http 软件包中的相关类为HttpServletRequest 和 HttpServletResponse。Servlet 通过这些对象与服务器通信并最终与客户机通信。Servlet 能通过调用“请求”对象的方法获知客户机环境,服务器环境的信息和所有由客户机提供的信息。Servlet 可以调用“响应”对象的方法发送响应,该响应是准备发回客户机的。

例子:
创建一个servlet


/** 
 * 
 */ 
package com.ee.servlet; 
 
import java.io.IOException; 
 
import javax.servlet.ServletException; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
 
/** 
 * @author Administrator 
 * 
 */ 
public class LogServlet extends HttpServlet { 
 
 /** 
  * 
  */ 
 private static final long serialVersionUID = 1L; 
 
 @Override 
 protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
   throws ServletException, IOException { 
  doPost(req, resp); 
 } 
  
 @Override 
 protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
   throws ServletException, IOException { 
  System.err.println("...doPost(req, resp)..."); 
 } 
}
로그인 후 복사

在web.xml中的配置:


<servlet> 
 <servlet-name>LogServlet</servlet-name> 
 <servlet-class>com.ee.servlet.LogServlet</servlet-class> 
</servlet> 
 
<servlet-mapping> 
 <servlet-name>LogServlet</servlet-name> 
 <url-pattern>/*</url-pattern><!-- 看到此没有,这个拦截所有路径 --> 
</servlet-mapping>
로그인 후 복사

它的拦截规则:

当一个请求发送到servlet容器的时候,容器先会将请求的url减去当前应用上下文的路径作为servlet的映射url,比如我访问的是http://localhost/test/aaa.html,我的应用上下文是test,容器会将http://localhost/test去掉,剩下的/aaa.html部分拿来做servlet的映射匹配。这个映射匹配过程是有顺序的,而且当有一个servlet匹配成功以后,就不会去理会剩下的servlet了(filter不同,后文会提到)。其匹配规则和顺序如下:
1.精确路径匹配。例子:比如servletA 的url-pattern为 /test,servletB的url-pattern为 /* ,这个时候,如果我访问的url为http://localhost/test ,这个时候容器就会先 进行精确路径匹配,发现/test正好被servletA精确匹配,那么就去调用servletA,也不会去理会其他的servlet了。
2.最长路径匹配。例子:servletA的url-pattern为/test/*,而servletB的url-pattern为/test/a/*,此时访问http://localhost/test/a时,容器会选择路径最长的servlet来匹配,也就是这里的servletB。
3.扩展匹配,如果url最后一段包含扩展,容器将会根据扩展选择合适的servlet。例子:servletA的url-pattern:*.action
4.如果前面三条规则都没有找到一个servlet,容器会根据url选择对应的请求资源。如果应用定义了一个default servlet,则容器会将请求丢给default servlet

3、Listener功能

它是基于观察者模式设计的,Listener 的设计对开发 Servlet 应用程序提供了一种快捷的手段,能够方便的从另一个纵向维度控制程序和数据。目前 Servlet 中提供了 5 种两类事件的观察者接口,它们分别是:4 个 EventListeners 类型的,ServletContextAttributeListener、ServletRequestAttributeListener、ServletRequestListener、HttpSessionAttributeListener 和 2 个 LifecycleListeners 类型的,ServletContextListener、HttpSessionListener。如下图所示:

Listener是Servlet的监听器,它可以监听客户端的请求、服务端的操作等。通过监听器,可以自动激发一些操作,比如监听在线的用户的数量。当增加一个HttpSession时,就激发sessionCreated(HttpSessionEvent se)方法,这样就可以给在线人数加1。常用的监听接口有以下几个:

ServletContextAttributeListener监听对ServletContext属性的操作,比如增加、删除、修改属性。
ServletContextListener监听ServletContext。当创建ServletContext时,激发contextInitialized(ServletContextEvent sce)方法;当销毁ServletContext时,激发contextDestroyed(ServletContextEvent sce)方法。
HttpSessionListener监听HttpSession的操作。当创建一个Session时,激发session Created(HttpSessionEvent se)方法;当销毁一个Session时,激发sessionDestroyed (HttpSessionEvent se)方法。
HttpSessionAttributeListener监听HttpSession中的属性的操作。当在Session增加一个属性时,激发attributeAdded(HttpSessionBindingEvent se) 方法;当在Session删除一个属性时,激发attributeRemoved(HttpSessionBindingEvent se)方法;当在Session属性被重新设置时,激发attributeReplaced(HttpSessionBindingEvent se) 方法。

下面我们开发一个具体的例子,这个监听器能够统计在线的人数。在ServletContext初始化和销毁时,在服务器控制台打印对应的信息。当ServletContext里的属性增加、改变、删除时,在服务器控制台打印对应的信息。
要获得以上的功能,监听器必须实现以下3个接口:

HttpSessionListener
ServletContextListener
ServletContextAttributeListener

例子:


/** 
 * 
 */ 
package com.ee.listener; 
 
import javax.servlet.ServletContextAttributeEvent; 
import javax.servlet.ServletContextAttributeListener; 
import javax.servlet.ServletContextEvent; 
import javax.servlet.ServletContextListener; 
import javax.servlet.http.HttpSessionEvent; 
import javax.servlet.http.HttpSessionListener; 
 
/** 
 * @author Administrator 
 * 
 */ 
public class OnlineUserListener implements HttpSessionListener, 
  ServletContextListener, ServletContextAttributeListener { 
 private long onlineUserCount = 0; 
 
 public long getOnlineUserCount() { 
  return onlineUserCount; 
 } 
 
 /* (non-Javadoc) 
  * @see javax.servlet.ServletContextAttributeListener#attributeAdded(javax.servlet.ServletContextAttributeEvent) 
  */ 
 @Override 
 public void attributeAdded(ServletContextAttributeEvent arg0) { 
 
 } 
 
 /* (non-Javadoc) 
  * @see javax.servlet.ServletContextAttributeListener#attributeRemoved(javax.servlet.ServletContextAttributeEvent) 
  */ 
 @Override 
 public void attributeRemoved(ServletContextAttributeEvent arg0) { 
 
 } 
 
 /* (non-Javadoc) 
  * @see javax.servlet.ServletContextAttributeListener#attributeReplaced(javax.servlet.ServletContextAttributeEvent) 
  */ 
 @Override 
 public void attributeReplaced(ServletContextAttributeEvent attributeEvent) { 
  System.err.println("...attributeReplaced..."); 
 } 
 
 /* (non-Javadoc) 
  * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent) 
  */ 
 @Override 
 public void contextDestroyed(ServletContextEvent arg0) { 
 
 } 
 
 /* (non-Javadoc) 
  * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent) 
  */ 
 @Override 
 public void contextInitialized(ServletContextEvent arg0) { 
 
 } 
 
 /* (non-Javadoc) 
  * @see javax.servlet.http.HttpSessionListener#sessionCreated(javax.servlet.http.HttpSessionEvent) 
  */ 
 @Override 
 public void sessionCreated(HttpSessionEvent httpSessionEvent) { 
  onlineUserCount ++; 
  toUpdateCount(httpSessionEvent); 
 } 
 
 /* (non-Javadoc) 
  * @see javax.servlet.http.HttpSessionListener#sessionDestroyed(javax.servlet.http.HttpSessionEvent) 
  */ 
 @Override 
 public void sessionDestroyed(HttpSessionEvent httpSessionEvent) { 
  onlineUserCount --; 
  toUpdateCount(httpSessionEvent); 
 } 
 
 private void toUpdateCount(HttpSessionEvent httpSessionEvent){ 
  httpSessionEvent.getSession().setAttribute("onlineUserCount", onlineUserCount); 
 } 
}
로그인 후 복사

Web.xml


<listener> 
 <listener-class>com.ee.listener.OnlineUserListener</listener-class> 
</listener>
로그인 후 복사

JSP页面:


<%@ page language="java" contentType="text/html; charset=UTF-8" 
 pageEncoding="UTF-8"%> 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
<title>主页</title> 
</head> 
<body> 
 <h4>你好!</h4> 
 在线人数:<h1><%=request.getSession().getAttribute("onlineUserCount") %></h1> 
</body> 
</html>
로그인 후 복사

위 내용은 Java의 필터, 서블릿 및 리스너에 대한 자세한 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿