web监听器的使用场景很多,比如监听servlet用来初始化数据,监听HttpSession用来获取当前在线人数,自定义一个监听器用来处理一些业务之类的。
一、监听Servlet上下文对象缓存数据,这样每次用户请求过来就可以直接在上下文对象中获取到相应的的数据,不至于每次都去数据库查询
- 首先定义一个监听器类实现ApplicationListener<ContextRefreshedEvent>,重写里面的onApplicationEvent方法
@Component
public class MyApplicationListen implements ApplicationListener<ContextRefreshedEvent> {
private static final Logger log = LoggerFactory.getLogger(MyApplicationListen.class);
@Override
public void onApplicationEvent(ContextRefreshedEvent refreshedEvent) {
log.info("进入到MyApplicationListen中的onApplicationEvent方法中");
// 获取上下文对象
ApplicationContext applicationContext = refreshedEvent.getApplicationContext();
// 获取用户对象
UserService userService = applicationContext.getBean(UserService.class);
UserEntry userEntry = userService.getUser();
// 将用户对象放在application域中
ServletContext servletContext = applicationContext.getBean(ServletContext.class);
servletContext.setAttribute("user",userEntry);
}
}
- 定义一个Controller进行测试
@GetMapping("/getUserInApplication")
@ApiOperation("测试从application缓存中获取数据")
public JsonResult getUserInApplication(HttpServletRequest request){
log.info("进入到MyListenerConotroller中的getUserInApplicaiton方法中");
ServletContext context = request.getServletContext();
UserEntry userEntry = (UserEntry) context.getAttribute("user");
return new JsonResult(userEntry);
}
- 在浏览器中数据http://localhost:8080/getUserInApplication进行测试,测试结果及控制台日志打印如下:
在应用启动的时候控制台打印信息如下:可以看到在应用启动的时候就已经将需要的数据查询回来并保存在了application上下文中
二、监听HttpSession统计在线人数
- 定义一个监听器类,实现HttpSessionListener,重写里面的sessionCreated和sessionDestroyed方法,定义一个count变量用来记录上下线的人数
@Component
public class MyHttpSessionListener implements HttpSessionListener {
private static final Logger log = LoggerFactory.getLogger(MyHttpSessionListener.class);
public Integer count = 0;
@Override
public synchronized void sessionCreated(HttpSessionEvent se) {
log.info("新用户上线了");
count++;
se.getSession().getServletContext().setAttribute("count",count);
}
@Override
public synchronized void sessionDestroyed(HttpSessionEvent se) {
log.info("用户下线了");
count--;
se.getSession().getServletContext().setAttribute("count",count);
}
}
- 定义一个Controller类进行测试
@GetMapping("/getSessionCount")
@ApiOperation("测试HttpSession保存cookie")
public String testHttpSessionListener (HttpServletRequest request , HttpServletResponse response) throws UnsupportedEncodingException {
// 浏览器添加cookie
Cookie cookie = new Cookie("JSESSIONID", URLEncoder.encode(request.getSession().getId(),"utf-8"));
cookie.setPath("/");
// 设置session过期时间
cookie.setMaxAge(1*60*60);
response.addCookie(cookie);
log.info("进入到MyListenerController中的testHttpSessionListener方法中");
Integer count = (Integer) request.getSession().getServletContext().getAttribute("count");
return "当前在线人数:"+count;
}
- 在不同浏览器中进行测试
三、自定义监听器的实现
- 首先定义一个Event事件类继承ApplicationEvent对象
public class MyEvent extends ApplicationEvent {
private UserEntry userEntry;
/**
* Create a new {@code ApplicationEvent}.
*
* @param source the object on which the event initially occurred or with
* which the event is associated (never {@code null})
*/
public MyEvent(Object source,UserEntry userEntry) {
super(source);
this.userEntry = userEntry;
}
public UserEntry getUserEntry() {
return userEntry;
}
public void setUserEntry(UserEntry userEntry) {
this.userEntry = userEntry;
}
}
- 定义一个监听器类实现ApplicationEvent<T>类
@Component
public class MyListener implements ApplicationListener<MyEvent> {
private static Logger log = LoggerFactory.getLogger(MyListener.class);
@Override
public void onApplicationEvent(MyEvent event) {
log.info("进入到MyListener的onApplicationEvent方法中");
UserEntry userEntry = event.getUserEntry();
// 实际业务场景中可以在监听到有事件发布的时候进行其他业务处理
log.info("获取到的信息:{}",userEntry.getName());
}
}
- 定义一个Service用来发布事件,获取到上下文对象,使用publishEvent方法进行事件发布
@Service
public class MyListenerService {
private static Logger log = LoggerFactory.getLogger(MyListenerService.class);
@Autowired
private ApplicationContext applicationContext;
public void getUser2(){
UserEntry userEntry = new UserEntry("测试","123456");
MyEvent myEvent = new MyEvent(this,userEntry);
applicationContext.publishEvent(myEvent);
}
}
- 创建一个Controller类进行测试
@Autowired
private MyListenerService myListenerService;
@GetMapping("/public")
@ApiOperation("测试自定义监听器")
public String myListener(){
log.info("进入到MyListenerController中的myListener方法中");
myListenerService.getUser2();
return "success";
}
- 在浏览器中输入http://localhost:8080/public进行测试,控制台打印日志如下:
在实际业务场景中,可以用上面的方式自定义一个监听器,A服务在处理完业务之后需要通知B服务进行相应的业务处理等场景。