文章目录
零、学习目标
- 掌握使用路径扫描方式整合Servlet
- 掌握使用路径扫描方式整合Filter
- 掌握使用路径扫描方式整合Listener
在Spring Boot中,使用路径扫描的方式整合内嵌式Servlet容器的Servlet、Filter、Listener三大组件时,首先需要在自定义组件上分别添加
@WebServlet
、@WebFilter
和@WebListener
注解进行声明,并配置相关注解属性,然后在项目主程序启动类上使用@ServletComponentScan
注解开启组件扫描即可。
一、创建Spring Boot项目 - IntegrateThreeComponents02
二、使用路径扫描方式整合Servlet三大组件
(一)创建MyServlet类
package net.hw.lesson13.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 功能:自定义Servlet
* 作者:华卫
* 日期:2021年02月28日
*/
@WebServlet("/hello")
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
System.out.println(req.getAttribute("hello"));
System.out.println(req.getServletContext().getAttribute("message"));
resp.setDateHeader("Expires", -1); // 浏览器不缓存
resp.getWriter().println("Servlet向你问候:牛年大吉!");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doGet(req, resp);
}
}
- 通过注解
@WebServlet("/hello")
给MyServlet定义了urlPattern
(二)创建CodeServlet类
package net.hw.lesson13.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Random;
/**
* 功能:生成6位字母数字验证码
* 作者:华卫
* 日期:2021年02月28日
*/
@WebServlet("/code")
public class CodeServlet extends HttpServlet {
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
System.out.println(req.getAttribute("hello"));
System.out.println(req.getServletContext().getAttribute("message"));
resp.setDateHeader("Expires", -1);// 浏览器不缓存
resp.getWriter().println(randomCode(6));
}
@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doGet(req, resp);
}
/**
* 产生指定位数随机码
*
* @param len
* @return
*/
public String randomCode(int len) {
char[] codes = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4',
'5', '6', '7', '8', '9'};
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < len; i++) {
int index = new Random().nextInt(35);
buffer.append(codes[index]);
}
return buffer.toString();
}
}
(三)创建MyFilter类
package net.hw.lesson13.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
/**
* 功能:自定义过滤器
* 作者:华卫
* 日期:2021年02月28日
*/
@WebFilter(value = {
"/hello", "/code"})
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
//过滤器可以对request请求处理之前进行一些预处理
servletRequest.setAttribute("hello", "过滤器向你问候:牛年大吉!");
//也可以在request请求处理之后进行一些处理
servletResponse.setCharacterEncoding("UTF-8");//解决中文乱码
servletResponse.setContentType("text/html;charset=utf8");
filterChain.doFilter(servletRequest, servletResponse); // 不要忘记了此句,否则程序正常请求流程就不走了
}
@Override
public void destroy() {
}
}
- 通过注解
@WebFilter(value = {"/hello", "/code"})
让MyFilter过滤两个指定的请求。
(四)创建MyListener类
package net.hw.lesson13.listener;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
/**
* 功能:自定义监听器
* 作者:华卫
* 日期:2021年02月28日
*/
@WebListener("/")
public class MyListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("ServletContext对象创建完成!");
// 可以把相关数据写到context中
ServletContext context = sce.getServletContext();
context.setAttribute("message", "ServletContext初始化完成了!");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("ServletContext对象已经销毁!");
// 在context环境消亡时,可以更新数据等
}
}
- 通过注解
@WebListener("/")
监听一切请求。
(五)修改入口类,添加ServletComponentScan注解
(六)启动应用,测试效果
- 启动应用后查看控制台输出
- 访问
http://localhost:8080/hello
- 访问
http://localhost:8080/code
- 可以看到,跟上一讲的项目,运行结果完全一致。
三、路径扫描整合Servlet三大组件小结
使用注解方式,可以省配置文件(比如ServletConfig、FilterConfig和ListenerConfig),大大简化了操作,实际应用时尽量采用此方式来整合Servlet三大组件。