加载顺序是:context-param -> listener -> filter -> servlet ,而同个类型之间的实际程序调用的时候的顺序是根据对应的 mapping 的顺序进行调用的。

下面从几个方面阐述一下题目中四个概念的区别与联系:
1、概念
2、生命周期
3、职责
4、执行过程

一、概念:
1、servlet:servlet是一种运行服务器端的Java应用程序,具有独立于平台和协议的特性,并且可以动态的生成web页面,它工作在客户端请求与服务器响应的中间层。
2、filter:filter是一个可以复用的代码片段,可以用来转换HTTP请求、响应和头信息。
Filter不像Servlet,它不能产生一个请求或者响应,它只是修改对某一资源的请求,或者修改从某一的响应。
3、listener:监听器,从字面上可以看出listener主要用来监听只用。通过listener可以监听web服务器中某一个执行动作,并根据其要求作出相应的响应。通俗的语言说就是在application,session,request三个对象创建消亡或者往其中添加修改删除属性时自动执行代码的功能组件。
4、interceptor:是在面向切面编程的,就是在你的service或者一个方法,前调用一个方法,或者在方法后调用一个方法,比如动态代理就是拦截器的简单实现,在你调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在你调用方法后打印出字符串,甚至在你抛出异常的时候做业务逻辑的操作。
5、servlet、filter、listener是配置到web.xml中,interceptor不配置到web.xml中,struts的拦截器配置到struts.xml中。spring的拦截器配置到spring.xml中。
二、生命周期:
1、servlet:servlet的生命周期始于它被装入web服务器的内存时,并在web服务器终止或重新装入servlet时结束。servlet一旦被装入web服务器,一般不会从web服务器内存中删除,直至web服务器关闭或重新结束。
(1)、装入:启动服务器时加载Servlet的实例;
(2)、初始化:web服务器启动时或web服务器接收到请求时,或者两者之间的某个时刻启动。初始化工作有init()方法负责执行完成;
(3)、调用:从第一次到以后的多次访问,都是只调用doGet()或doPost()方法;
(4)、销毁:停止服务器时调用destroy()方法,销毁实例。

2、filter:(一定要实现javax.servlet包的Filter接口的三个方法init()、doFilter()、destroy(),空实现也行)
(1)、启动服务器时加载过滤器的实例,并调用init()方法来初始化实例;
(2)、每一次请求时都只调用方法doFilter()进行处理;
(3)、停止服务器时调用destroy()方法,销毁实例。
3、listener:类似于servlet和filter
web.xml 的加载顺序是:context- param -> listener -> filter -> servlet
4、interceptor:以struts的拦截器为例,加载了struts.xml以后,初始化相应拦截器。当action请求来时调用intercept方法,服务器停止销毁interceptor。

三、职责
1、servlet:
创建并返回一个包含基于客户请求性质的动态内容的完整的html页面;
创建可嵌入到现有的html页面中的一部分html页面(html片段);
读取客户端发来的隐藏数据;
读取客户端发来的显示数据;
与其他服务器资源(包括数据库和java的应用程序)进行通信;
通过状态代码和响应头向客户端发送隐藏数据。
2、filter:
filter能够在一个请求到达servlet之前预处理用户请求,也可以在离开servlet时处理http响应:
在执行servlet之前,首先执行filter程序,并为之做一些预处理工作;
根据程序需要修改请求和响应;
在servlet被调用之后截获servlet的执行

3、listener:职责如概念。
servlet2.4规范中提供了8个listener接口,可以将其分为三类,分别如下:
第一类:与servletContext有关的listner接口。包括:ServletContextListener、ServletContextAttributeListener
第二类:与HttpSession有关的Listner接口。包括:HttpSessionListner、HttpSessionAttributeListener、HttpSessionBindingListener、 HttpSessionActivationListener;
第三类:与ServletRequest有关的Listener接口,包括:ServletRequestListner、ServletRequestAttributeListener

4、interceptor:与过滤器十分相似,通过层层拦截,处理用户的请求和响应。

备注:web.xml 的加载顺序是:context-param -> listener -> filter -> servlet 。了解了这几个概念的区别以后,不难理论这个加载顺序了。

四、几个区别:
1,servlet 流程是短的,url传来之后,就对其进行处理,之后返回或转向到某一自己指定的页面。它主要用来在 业务处理之前进行控制.
2,filter 流程是线性的, url传来之后,检查之后,可保持原来的流程继续向下执行,被下一个filter, servlet接收等,而servlet 处理之后,不会继续向下传递。
filter功能可用来保持流程继续按照原来的方式进行下去,或者主导流程,而servlet的功能主要用来主导流程。
filter可用来进行字符编码的过滤,检测用户是否登陆的过滤,禁止页面缓存等
3, servlet,filter都是针对url之类的,而listener是针对对象的操作的,如session的创建,session.setAttribute的发生,在这样的事件发生时做一些事情。

service返回JSON

/**
* 在Servlet返回JSON数据
*/
@WebServlet("/json.do")
public class JsonServlet extends HttpServlet {
private static final long serialVersionUID = 7500835936131982864L; /**
* 返回json格式数据
*/
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Map<String, Object> data = new HashMap<String, Object>(); data.put("date", new Date());
data.put("email", "accountwcx@qq.com");
data.put("age", 30);
data.put("name", "csdn");
data.put("array", new int[]{1,2,3,4}); ResponseJsonUtils.json(response, data);
}
}
/**
 * Servlet返回JSONP格式数据
 */
@WebServlet("/jsonp.do")
public class JsonpServlet extends HttpServlet {
  private static final long serialVersionUID = -8343408864035108293L;
  
  /**
   * 请求会发送callback参数作为回调函数,如果没有发送callback参数则使用默认回调函数
   */
  protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //客户端发送的回调函数
    String callback = request.getParameter("callback");
      
    Map<String, Object> data = new HashMap<String, Object>();
      
    data.put("date", new Date());
    data.put("email", "accountwcx@qq.com");
    data.put("age", 30);
    data.put("name", "csdn");
    data.put("array", new int[]{1,2,3,4});
      
    if(callback == null || callback.length() == 0){
      //如果客户端没有发送回调函数,则使用默认的回调函数
      ResponseJsonUtils.jsonp(response, data);
    }else{
      //使用客户端的回调函数
      ResponseJsonUtils.jsonp(response, callback, data);
    }
  }
}
import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.http.HttpServletResponse; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature; /**
*
* Web服务端返回JSON工具类
* 工具类依赖FastJSON
* 工具类支持返回JSON和JSONP格式数据
* @author accountwcx@qq.com
*
*/
public class ResponseJsonUtils {
/**
* 默认字符编码
*/
private static String encoding = "UTF-8"; /**
* JSONP默认的回调函数
*/
private static String callback = "callback"; /**
* FastJSON的序列化设置
*/
private static SerializerFeature[] features = new SerializerFeature[]{
//输出Map中为Null的值
SerializerFeature.WriteMapNullValue, //如果Boolean对象为Null,则输出为false
SerializerFeature.WriteNullBooleanAsFalse, //如果List为Null,则输出为[]
SerializerFeature.WriteNullListAsEmpty, //如果Number为Null,则输出为0
SerializerFeature.WriteNullNumberAsZero, //输出Null字符串
SerializerFeature.WriteNullStringAsEmpty, //格式化输出日期
SerializerFeature.WriteDateUseDateFormat
}; /**
* 把Java对象JSON序列化
* @param obj 需要JSON序列化的Java对象
* @return JSON字符串
*/
private static String toJSONString(Object obj){
return JSON.toJSONString(obj, features);
} /**
* 返回JSON格式数据
* @param response
* @param data 待返回的Java对象
* @param encoding 返回JSON字符串的编码格式
*/
public static void json(HttpServletResponse response, Object data, String encoding){
//设置编码格式
response.setContentType("text/plain;charset=" + encoding);
response.setCharacterEncoding(encoding); PrintWriter out = null;
try{
out = response.getWriter();
out.write(toJSONString(data));
out.flush();
}catch(IOException e){
e.printStackTrace();
}
} /**
* 返回JSON格式数据,使用默认编码
* @param response
* @param data 待返回的Java对象
*/
public static void json(HttpServletResponse response, Object data){
json(response, data, encoding);
} /**
* 返回JSONP数据,使用默认编码和默认回调函数
* @param response
* @param data JSONP数据
*/
public static void jsonp(HttpServletResponse response, Object data){
jsonp(response, callback, data, encoding);
} /**
* 返回JSONP数据,使用默认编码
* @param response
* @param callback JSONP回调函数名称
* @param data JSONP数据
*/
public static void jsonp(HttpServletResponse response, String callback, Object data){
jsonp(response, callback, data, encoding);
} /**
* 返回JSONP数据
* @param response
* @param callback JSONP回调函数名称
* @param data JSONP数据
* @param encoding JSONP数据编码
*/
public static void jsonp(HttpServletResponse response, String callback, Object data, String encoding){
StringBuffer sb = new StringBuffer(callback);
sb.append("(");
sb.append(toJSONString(data));
sb.append(");"); // 设置编码格式
response.setContentType("text/plain;charset=" + encoding);
response.setCharacterEncoding(encoding); PrintWriter out = null;
try {
out = response.getWriter();
out.write(sb.toString());
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
} public static String getEncoding() {
return encoding;
} public static void setEncoding(String encoding) {
ResponseJsonUtils.encoding = encoding;
} public static String getCallback() {
return callback;
} public static void setCallback(String callback) {
ResponseJsonUtils.callback = callback;
}
}
import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.web.filter.OncePerRequestFilter; import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter; @Override
protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
try {
...//业务逻辑 filterChain.doFilter(httpServletRequest, httpServletResponse);
} catch (BadCredentialsException e) {
httpServletResponse.setStatus(HttpStatus.UNAUTHORIZED.value());
httpServletResponse.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);

ResultData<Object> result = new ResultData<>(GlobalCode.INVALID_IDENTITY);
try (PrintWriter out = httpServletResponse.getWriter()) {
out.write(JSON.toJSONString(result));
out.flush();
}

}
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; /**
* Spring MVC返回JSON和JSONP数据
*/
@Controller
@RequestMapping("/json")
public class JsonController { /**
* 返回JSON数据
* @param request
* @param response
*/
@RequestMapping("/json.do")
public void json(HttpServletRequest request, HttpServletResponse response){
Map<String, Object> data = new HashMap<String, Object>(); data.put("date", new Date());
data.put("email", "accountwcx@qq.com");
data.put("age", 30);
data.put("name", "csdn");
data.put("array", new int[]{1,2,3,4}); ResponseJsonUtils.json(response, data);
} /**
* 返回JSONP数据
* @param callback JSONP的回调函数
* @param request
* @param response
*/
@RequestMapping("/jsonp.do")
public void json(String callback, HttpServletRequest request, HttpServletResponse response){
Map<String, Object> data = new HashMap<String, Object>(); data.put("date", new Date());
data.put("email", "accountwcx@qq.com");
data.put("age", 30);
data.put("name", "csdn");
data.put("array", new int[]{1,2,3,4}); if(callback == null || callback.length() == 0){
//如果客户端没有发送回调函数,则使用默认的回调函数
ResponseJsonUtils.jsonp(response, data);
}else{
//使用客户端的回调函数
ResponseJsonUtils.jsonp(response, callback, data);
}
}
}
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 com.ajun.exception.BsException; /**
* 业务异常过滤器
* @author ajun
* @http://blog.csdn.net/ajun_studio
*/
public class ExceptionFiler implements Filter { private String errorPage;//跳转的错误信息页面 public void destroy() { } public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
//捕获你抛出的业务异常
try {
chain.doFilter(req, res);
} catch (RuntimeException e) {
if(e instanceof BsException){//如果是你定义的业务异常
request.setAttribute("BsException", e);//存储业务异常信息类
request.getRequestDispatcher(errorPage).forward(request, response);//跳转到信息提示页面!!
}
e.printStackTrace();
}
}
//初始化读取你配置的提示页面路径
public void init(FilterConfig config) throws ServletException {
//读取错误信息提示页面路径
errorPage = config.getInitParameter("errorPage");
if(null==errorPage || "".equals(errorPage)){
throw new RuntimeException("没有配置错误信息跳转页面,请再web.xml中进行配置\n<init-param>\n<param-name>errorPage</param-name>\n<param-value>/error.jsp</param-value>\n </init-param>\n路径可以是你自己设定的任何有效路径页面!!");
//System.out.println("没有配置错误信息跳转页面");
}
} }

Filter在web.xml中的配置如下:

<filter>
<filter-name>ExceptionFilter</filter-name>
<filter-class>com.ajun.filter.ExceptionFiler</filter-class>
<init-param>
<param-name>errorPage</param-name>
<param-value>/error.jsp</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>ExceptionFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>

Servlet、Filter的更多相关文章

  1. Servlet、Filter、Listener、Interceptor

    首先,JSP/Servlet规范中定义了Servlet.Filter.Listener这三种角色,并没有定义Interceptor这个角 色,Interceptor是某些MVC框架中的角色,比如Str ...

  2. servlet、filter、listener、interceptor之间的区别和联系

    一.概念 1.servlet:servlet是一种运行服务器端的java应用程序,具有独立于平台和协议的特性,并且可以动态的生成web页面,它工作在客户端请求与服务器响应的中间层. 2.filter: ...

  3. j2ee Servlet、Filter、Listener

    首先,JSP/Servlet规范中定义了Servlet.Filter.Listener这三种角色,并没有定义Interceptor这个角色,Interceptor是某些MVC框架中的角色,比如Stru ...

  4. 基于注解的SpringMVC添加其他的Servlet、Filter以及Listener

    我们可以在AbstractAnnotationConfigDispatcherServletInitializer的实现类中重写onStartup(ServletContext servletCont ...

  5. SpringBoot 配置 Servlet、Filter、Listener

    SpringBoot 配置 Servlet.Filter.Listener 在SpringBoot应用中,嵌入式的 Servlet 3.0+ 容器不会直接使用 ServletContainerInit ...

  6. 【Web】servlet、filter和listener

    一般地,servlet.filter.listener是配置到web.xml中(web.xml 的加载顺序是:context-param -> listener -> filter -&g ...

  7. SpringBoot注册Servlet、Filter、Listener

    SpringBoot默认是以jar包的方式启动嵌入式的Servlet容易来启动SpringBoot的Web应用,没有web.xml文件 因此我们可以使用以下方式来注册Servlet.Filter.Li ...

  8. spring boot(18)-servlet、filter、listener

    servlet.filter.listener的用法就不讲了,只讲如何在spring boot中配置它们.有两种方式,一种是从servlet3开始提供的注解方式,另一种是spring的注入方式 ser ...

  9. Spring Boot使用Servlet、Filter或Listener的方式

    根据官方文档说明,有两种方式可以在你的Spring Boot应用中使用Servlet.Filter或Listener. 其一:将Servlet.Filter或Listener注册成Spring Bea ...

随机推荐

  1. UnityEditor下文件操作方法汇总(Unity3D开发之二十四)

    猴子原创,欢迎转载.转载请注明: 转载自Cocos2Der-CSDN,谢谢! 原文地址: http://blog.csdn.net/cocos2der/article/details/50595585 ...

  2. MIDle生命周期详解,以及工作原理

    当MIDlet被应用程序管理器成功地初始化之后,就开始展开了它的生命周期.MIDlet的生命周期完全由应用程序管理器控制,也就是说,当MIDlet要从一个状态变成另外一个状态时,应用程序管理器会调用对 ...

  3. wait和notify的理解与使用

    1.对于wait()和notify()的理解 对于wait()和notify()的理解,还是要从jdk官方文档中开始,在Object类方法中有: void notify() Wakes up a si ...

  4. java多继承

    众所周知,java面向对象语言中只有单继承的编程语言,也许你会说,通过实现多个接口这种变通的方式达到多继承的目的.没错,你说的对,不过这并不是本片文章要说到的内容,本文要讲到的内容是java中实实在在 ...

  5. Android平台的Swift—Kotlin

    WeTest 导读 Kotlin 已经出来较长一段时间了,有些同学已经对Kotlin进行了深入的学习,甚至已经运用到了自己的项目当中,但是还有较多同学可能只是听过Kotlin或简单了解过,这篇文章的目 ...

  6. 【redis】Java连接云服务器redis之JedisConnectionException的异常问题

    代码很简单: public static void main(String[] args) { Jedis jedis = new Jedis("116.85.10.216",63 ...

  7. 深入了解Map

    联系 Java中的Map类似于OC的Dictionary,都是一个个键值对组成,一键对应一值.我在之前的文章中讲解过Set,其实在JAVA底层Set依赖的也是Map,那我们都知道,Set是单列的(只有 ...

  8. Binary Tree Zigzag Level Order Traversal(z字形打印二叉树)

    Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to ...

  9. JFace dailog button事件中刷新透视图异常 Trying to execute the disabled command org.eclipse.ui.window.closePerspective

    报错的代码为 protected void buttonPressed(int buttonId) { Display.getDefault().syncExec(new Runnable() { p ...

  10. sql server对并发的处理-乐观锁和悲观锁

    https://www.cnblogs.com/dengshaojun/p/3955826.html sql server对并发的处理-乐观锁和悲观锁 假如两个线程同时修改数据库同一条记录,就会导致后 ...