【Java Web开发学习】Spring MVC添加自定义Servlet、Filter、Listener

转载:https://www.cnblogs.com/yangchongxing/p/9968483.html

自定义Servlet

package cn.ycx.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class MyServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public MyServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("myservlet");
response.getWriter().append("Served at: ").append(request.getContextPath());
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}

自定义Filter

package cn.ycx.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 destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("myfilter");
chain.doFilter(request, response);
}
public void init(FilterConfig fConfig) throws ServletException {
}
}

静态资源处理Filter

package cn.ycx.filter;

import java.io.FileInputStream;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
public class StaticFilter implements Filter {
public StaticFilter() {
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("StaticFilter");
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String path = httpServletRequest.getServletPath();
String realPath = httpServletRequest.getServletContext().getRealPath(path);
System.out.println(realPath);
ServletOutputStream out = response.getOutputStream();
FileInputStream in = new FileInputStream(realPath);
byte[] buf = new byte[2048];
int len = -1;
while((len = in.read(buf)) != -1) {
out.write(buf, 0, len);
}
in.close();
out.flush();
out.close();
}
public void init(FilterConfig fConfig) throws ServletException {
}
}

自定义Listener

package cn.ycx.listener;

import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener; public class MyServletRequestListener implements ServletRequestListener {
@Override
public void requestDestroyed(ServletRequestEvent sre) {
System.out.println("requestDestroyed");
}
@Override
public void requestInitialized(ServletRequestEvent sre) {
System.out.println("requestInitialized");
}
}

方式一、基于Java初始化器WebApplicationInitializer添加(支持Servlet3.0的容器)

package cn.ycx.initializer;

import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration; import org.springframework.web.WebApplicationInitializer; import cn.ycx.filter.MyFilter;
import cn.ycx.filter.StaticFilter;
import cn.ycx.listener.MyServletRequestAttributeListener;
import cn.ycx.listener.MyServletRequestListener;
import cn.ycx.servlet.MyServlet; public class MyInitializer implements WebApplicationInitializer { @Override
public void onStartup(ServletContext servletContext) throws ServletException {
System.out.println(">>>>>>>>>>>> 自定义 onStartup ..."); // 自定义Servlet
ServletRegistration.Dynamic myServlet = servletContext.addServlet("myservlet", MyServlet.class);
myServlet.addMapping("/myservlet"); // 自定义Filter
FilterRegistration.Dynamic staticFilter = servletContext.addFilter("staticfilter", StaticFilter.class);
staticFilter.addMappingForUrlPatterns(null, false, "/static/*");
FilterRegistration.Dynamic myFilter = servletContext.addFilter("myfilter", MyFilter.class);
myFilter.addMappingForUrlPatterns(null, false, "/*"); // 自定义Listener
servletContext.addListener(MyServletRequestListener.class);
servletContext.addListener(MyServletRequestAttributeListener.class.getName());
}
}

addServlet 重载方法

public ServletRegistration.Dynamic addServlet(String servletName, String className);
public ServletRegistration.Dynamic addServlet(String servletName, Servlet servlet);
public ServletRegistration.Dynamic addServlet(String servletName,Class <? extends Servlet> servletClass);

addFilter 重载方法

public FilterRegistration.Dynamic addFilter(String filterName, String className);
public FilterRegistration.Dynamic addFilter(String filterName, Filter filter);
public FilterRegistration.Dynamic addFilter(String filterName,Class <? extends Filter> filterClass);

addListener 重载方法

public void addListener(String className);
public <T extends EventListener> void addListener(T t);
public void addListener(Class <? extends EventListener> listenerClass);

addMappingForUrlPatterns方法第二个参数isMatchAfter相同时,Filter的执行顺序由其在onStartup方法中的添加顺序决定,为false的优先级比为true高

/**
* Adds a filter mapping with the given url patterns and dispatcher
* types for the Filter represented by this FilterRegistration.
*
* <p>Filter mappings are matched in the order in which they were
* added.
*
* <p>Depending on the value of the <tt>isMatchAfter</tt> parameter, the
* given filter mapping will be considered after or before any
* <i>declared</i> filter mappings of the ServletContext from which
* this FilterRegistration was obtained.
*
* <p>If this method is called multiple times, each successive call
* adds to the effects of the former.
*
* @param dispatcherTypes the dispatcher types of the filter mapping,
* or null if the default <tt>DispatcherType.REQUEST</tt> is to be used
* @param isMatchAfter true if the given filter mapping should be matched
* after any declared filter mappings, and false if it is supposed to
* be matched before any declared filter mappings of the ServletContext
* from which this FilterRegistration was obtained
* @param urlPatterns the url patterns of the filter mapping
*
* @throws IllegalArgumentException if <tt>urlPatterns</tt> is null or
* empty
* @throws IllegalStateException if the ServletContext from which this
* FilterRegistration was obtained has already been initialized
*/
public void addMappingForUrlPatterns(EnumSet<DispatcherType> dispatcherTypes, boolean isMatchAfter, String... urlPatterns);

为什么实现这个接口容器就能加载自定义类呢?

因为在Servlet3.0环境中,容器会在类路径中查找实现javax.servlet.ServletContainerInitializer接口的类,并用它来配置Servlet容器。Spring提供了这个接口的实现类名为SpringServletContainerInitializer,这个类会查找实现WebApplicationInitializer接口的类,并将任务交给他们来完成。

SpringServletContainerInitializer类源码

@HandlesTypes(WebApplicationInitializer.class)
public class SpringServletContainerInitializer implements ServletContainerInitializer {
@Override
public void onStartup(Set<Class<?>> webAppInitializerClasses, ServletContext servletContext)
throws ServletException { List<WebApplicationInitializer> initializers = new LinkedList<WebApplicationInitializer>(); if (webAppInitializerClasses != null) {
for (Class<?> waiClass : webAppInitializerClasses) {
// Be defensive: Some servlet containers provide us with invalid classes,
// no matter what @HandlesTypes says...
if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) &&
WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
try {
initializers.add((WebApplicationInitializer) waiClass.newInstance());
}
catch (Throwable ex) {
throw new ServletException("Failed to instantiate WebApplicationInitializer class", ex);
}
}
}
} if (initializers.isEmpty()) {
servletContext.log("No Spring WebApplicationInitializer types detected on classpath");
return;
} servletContext.log(initializers.size() + " Spring WebApplicationInitializers detected on classpath");
AnnotationAwareOrderComparator.sort(initializers);
for (WebApplicationInitializer initializer : initializers) {
initializer.onStartup(servletContext);//我们自定义的WebApplicationInitializer类在这里被执行
}

} }

【Java Web开发学习】Spring MVC添加自定义Servlet、Filter、Listener的更多相关文章

  1. SpringBoot整合WEB开发--(九)整合Servlet,Filter,Listener

    简介: 如果需要整合第三方框架时,可能还是不得不使用Servlet,Filter,Listener,Springboot中也有提供支持. @WebServlet("/my") pu ...

  2. 【Java Web开发学习】Spring MVC异常统一处理

    [Java Web开发学习]Spring MVC异常统一处理 文采有限,若有错误,欢迎留言指正. 转载:https://www.cnblogs.com/yangchongxing/p/9271900. ...

  3. 【Java Web开发学习】Spring MVC 拦截器HandlerInterceptor

    [Java Web开发学习]Spring MVC 拦截器HandlerInterceptor 转载:https://www.cnblogs.com/yangchongxing/p/9324119.ht ...

  4. 【Java Web开发学习】Spring MVC文件上传

    [Java Web开发学习]Spring MVC文件上传 转载:https://www.cnblogs.com/yangchongxing/p/9290489.html 文件上传有两种实现方式,都比较 ...

  5. 【Java Web开发学习】Spring MVC 使用HTTP信息转换器

    [Java Web开发学习]Spring MVC 使用HTTP信息转换器 转载:https://www.cnblogs.com/yangchongxing/p/10186429.html @Respo ...

  6. 【Java Web开发学习】Spring环境profile

    [Java Web开发学习]Spring 环境profile 转载:http://www.cnblogs.com/yangchongxing/p/8890702.html 开发.测试.生产环境往往是不 ...

  7. 【Java Web开发学习】Spring JPA

    [Java Web开发学习]Spring JPA 转载:https://www.cnblogs.com/yangchongxing/p/10082864.html 1.使用容器管理类型的JPA JND ...

  8. 【Java Web开发学习】Servlet、Filter、Listener

    [Java Web开发学习]Servlet 转发:https://www.cnblogs.com/yangchongxing/p/9274739.html 1.Servlet package cn.y ...

  9. 【Java Web开发学习】Spring加载外部properties配置文件

    [Java Web开发学习]Spring加载外部properties配置文件 转载:https://www.cnblogs.com/yangchongxing/p/9136505.html 1.声明属 ...

随机推荐

  1. ndk编译出来的executable动态库入口函数的参数错乱

    早些时间用ndk编译带main入口函数的动态库,测试可运行.今天要作它用时,发现在这个入口函数并没有传入正确的参数. hello.cpp有main函数,用ndk分别编译成可执行文件和动态库文件,使两者 ...

  2. Mysql 添加字段 修改字段 删除字段

    1.添加字段(alter.add) mysql> alter table users add name varchar(30) not null after id; 2.修改字段(alter.m ...

  3. Nginx+SpringBoot实现负载均衡

    前言 在上一篇中介绍了Nginx的安装,本篇文章主要介绍的是Nginx如何实现负载均衡. 负载均衡介绍 介绍 在介绍Nginx的负载均衡实现之前,先简单的说下负载均衡的分类,主要分为硬件负载均衡和软件 ...

  4. 《master the game of GO wtth deep neural networks and tree search》研究解读

    现在”人工智能“如此火爆的一大直接原因便是deepmind做出的阿尔法狗打败李世石,从那时开始计算机科学/人工智能成为了吹逼的主流.记得当时还是在学校晚新闻的时候看到的李世石输的消息,这个新闻都是我给 ...

  5. docker快速部署DNS,实现快速上线

    概念Docker 是一个开源的应用容器引擎,Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.这里我将使用do ...

  6. php基础文档

    目录 PHP简介 PHP概述和名词解释 PHP常见数据类型 PHP运算符 PHP流程控制语句 PHP函数 PHP类与对象 PHP会话session与缓存cookie(扩展) 1.PHP简介 PHP,即 ...

  7. JAVA中快速生成get与set

    快捷键 ctrl+Alt+S generate getters and setters

  8. linux 内核版本和发行版本区别

    内核版本:我的理解是,内核是系统的心脏,是linux中最基层的代码.版本号如 Linux version 3.10.0-514.el7.x86_64 查看内核版本可使用.uname -a 或者cat ...

  9. 自学python day 10 函数的动态参数、命名空间、作用域

    作业提升: s为字符串 s.isalnum() 所有字符都是字母或者数字 s.isalpha() 所有字符都是字母 s.isdigit() 所有字符否是数字 2. for i in range(1,1 ...

  10. 运维与开发的开车现场之MySQL5.7创建触发器报错解决过程

    报错内容如下: ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds ...