使用Spring application对象存储全局变量,统计链接的点击量
2015-12-09 01:22
369 查看
application对象作为JSP的9大内置对象之一,实现了用户间数据的共享,可存放全局变量。它开始于服务器的启动,直到服务器的关闭,在此期间,此对象将一直存在;这样在用户的前后连接或不同用户之间的连接中,可以对此对象的同一属性进行操作;在任何地方对此对象属性的操作,都将影响到其他用户对此的访问。服务器的启动和关闭决定了application对象的生命。它是ServletContext类的实例。
基于上述理由,将点击量作为全局变量,存在application对象中,统计全网的点击量。
1、在web.xml中自定义监听器
<listener>
<listener-class>xxx.xxx.web.listener.InitListener</listener-class>
</listener>
2、在xxx.xxx.web.listener.InitListener的contextInitialized()方法中设置全局变量,用来存点击量,存入ServletContext域对象(application)中,在contextDestroyed()方法中更新数据库中的点击量字段,并移除全局变量。
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
* @ClassName: MyServletContextListener
* @Description:InitListener类实现了ServletContextListener接口,
* 因此可以对ServletContext对象的创建和销毁这两个动作进行监听。
*/
public class InitListener implements
ServletContextListener {
private static ApplicationContext applicationContext = null;
public void contextInitialized(ServletContextEvent sce) {
//System.out.println("ServletContext对象创建");
//初始化 ApplicationContext 对象
applicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(sce.getServletContext());
//设置点击量
sce.getServletContext().setAttribute("increaseCountMap",newConcurrentHashMap<Integer,AtomicInteger>());
}
public void
contextDestroyed(ServletContextEvent sce) {
//System.out.println("ServletContext对象销毁");
WebApplicationContext webApplicationContext=
ContextLoader.getCurrentWebApplicationContext();
//获取业务层service Bean
CourseServiceImpl courserService
= (CourseServiceImpl)webApplicationContext.getBean("CourseServiceImpl");
courserService.updateRateUtilization();//更新点击量
sce.getServletContext().removeAttribute("increaseCountMap");//移除全局变量--点击量
}
//用于那些非控制层中使用直接获取到的Spring Bean的获取,如接口
public static ApplicationContext getApplicatonContext(){
returnapplicationContext ;
}
}
3、在CourseController.java控制器中:
private static Object
obj = new Object();
static ConcurrentHashMap<Integer,AtomicInteger> increaseCountMap=
new ConcurrentHashMap<Integer,AtomicInteger>();
@RequestMapping(value="/showCourseDetail.do",method=RequestMethod.GET)
public ModelAndView showCourseDetail(HttpServletRequest request){
//其他内容忽略,至关注点击量的业务处理
String courseId = null;
synchronized(obj){//加锁防止并发
courseId = request.getParameter("courseId");
calClickRate(request,courseId );
}
//............
return new ModelAndView("/page/courseDetail.jsp");
}
private void calClickRate(HttpServletRequest request,String courseIdStr){
Integer courseId = Integer.valueOf(courseIdStr);
increaseCountMap = (ConcurrentHashMap<Integer,AtomicInteger>)request.getSession().getServletContext().
getAttribute("increaseCountMap");
Iterator it =increaseCountMap.entrySet().iterator();
while(it.hasNext()){
Map.Entry<Integer,AtomicInteger>
me = (Map.Entry<Integer,AtomicInteger>)it.next();
if(me.getKey().intValue()
== courseId.intValue()){
increaseCountMap.putIfAbsent(courseId,new
AtomicInteger(me.getValue().getAndIncrement()));
}else{
increaseCountMap.putIfAbsent(courseId,new
AtomicInteger(1));
}
}
if(!it.hasNext()){
increaseCountMap.putIfAbsent(courseId,newAtomicInteger(1));
}
request.getSession().getServletContext().setAttribute("increaseCountMap",increaseCountMap);
}
4、在CourseServiceImpl.java中 更新点击量
public void updateRateUtilization(){
WebApplicationContext
webApplicationContext =
ContextLoader.getCurrentWebApplicationContext();
ConcurrentHashMap<Integer,AtomicInteger> countMap =(ConcurrentHashMap<Integer,AtomicInteger>)
webApplicationContext .getServletContext().getAttribute("increaseCountMap");
Iterator it =countMap.entrySet().iterator();
while(it.hasNext()){
Map.Entry<Integer,AtomicInteger>
me = (Map.Entry<Integer,AtomicInteger>)it.next();
courseMapper.updateCourseClickRate(me.getKey(),me.getValue().intValue());//更新数据库
}
webApplicationContext.getServletContext().setAttribute("increaseCountMap",
new ConcurrentHashMap<Integer,AtomicInteger>());
}
//======================
updateCourseClickRate()对应的sql:
update t_course set click_rate
= #{clickRate} + IFNULL(click_rate,0) where id = #{courseId}
5、最后使用定时任务,每10分钟一次,更新点击量
CourseServiceImpl.java-->updateRateUtilization()
基于上述理由,将点击量作为全局变量,存在application对象中,统计全网的点击量。
1、在web.xml中自定义监听器
<listener>
<listener-class>xxx.xxx.web.listener.InitListener</listener-class>
</listener>
2、在xxx.xxx.web.listener.InitListener的contextInitialized()方法中设置全局变量,用来存点击量,存入ServletContext域对象(application)中,在contextDestroyed()方法中更新数据库中的点击量字段,并移除全局变量。
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
* @ClassName: MyServletContextListener
* @Description:InitListener类实现了ServletContextListener接口,
* 因此可以对ServletContext对象的创建和销毁这两个动作进行监听。
*/
public class InitListener implements
ServletContextListener {
private static ApplicationContext applicationContext = null;
public void contextInitialized(ServletContextEvent sce) {
//System.out.println("ServletContext对象创建");
//初始化 ApplicationContext 对象
applicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(sce.getServletContext());
//设置点击量
sce.getServletContext().setAttribute("increaseCountMap",newConcurrentHashMap<Integer,AtomicInteger>());
}
public void
contextDestroyed(ServletContextEvent sce) {
//System.out.println("ServletContext对象销毁");
WebApplicationContext webApplicationContext=
ContextLoader.getCurrentWebApplicationContext();
//获取业务层service Bean
CourseServiceImpl courserService
= (CourseServiceImpl)webApplicationContext.getBean("CourseServiceImpl");
courserService.updateRateUtilization();//更新点击量
sce.getServletContext().removeAttribute("increaseCountMap");//移除全局变量--点击量
}
//用于那些非控制层中使用直接获取到的Spring Bean的获取,如接口
public static ApplicationContext getApplicatonContext(){
returnapplicationContext ;
}
}
3、在CourseController.java控制器中:
private static Object
obj = new Object();
static ConcurrentHashMap<Integer,AtomicInteger> increaseCountMap=
new ConcurrentHashMap<Integer,AtomicInteger>();
@RequestMapping(value="/showCourseDetail.do",method=RequestMethod.GET)
public ModelAndView showCourseDetail(HttpServletRequest request){
//其他内容忽略,至关注点击量的业务处理
String courseId = null;
synchronized(obj){//加锁防止并发
courseId = request.getParameter("courseId");
calClickRate(request,courseId );
}
//............
return new ModelAndView("/page/courseDetail.jsp");
}
private void calClickRate(HttpServletRequest request,String courseIdStr){
Integer courseId = Integer.valueOf(courseIdStr);
increaseCountMap = (ConcurrentHashMap<Integer,AtomicInteger>)request.getSession().getServletContext().
getAttribute("increaseCountMap");
Iterator it =increaseCountMap.entrySet().iterator();
while(it.hasNext()){
Map.Entry<Integer,AtomicInteger>
me = (Map.Entry<Integer,AtomicInteger>)it.next();
if(me.getKey().intValue()
== courseId.intValue()){
increaseCountMap.putIfAbsent(courseId,new
AtomicInteger(me.getValue().getAndIncrement()));
}else{
increaseCountMap.putIfAbsent(courseId,new
AtomicInteger(1));
}
}
if(!it.hasNext()){
increaseCountMap.putIfAbsent(courseId,newAtomicInteger(1));
}
request.getSession().getServletContext().setAttribute("increaseCountMap",increaseCountMap);
}
4、在CourseServiceImpl.java中 更新点击量
public void updateRateUtilization(){
WebApplicationContext
webApplicationContext =
ContextLoader.getCurrentWebApplicationContext();
ConcurrentHashMap<Integer,AtomicInteger> countMap =(ConcurrentHashMap<Integer,AtomicInteger>)
webApplicationContext .getServletContext().getAttribute("increaseCountMap");
Iterator it =countMap.entrySet().iterator();
while(it.hasNext()){
Map.Entry<Integer,AtomicInteger>
me = (Map.Entry<Integer,AtomicInteger>)it.next();
courseMapper.updateCourseClickRate(me.getKey(),me.getValue().intValue());//更新数据库
}
webApplicationContext.getServletContext().setAttribute("increaseCountMap",
new ConcurrentHashMap<Integer,AtomicInteger>());
}
//======================
updateCourseClickRate()对应的sql:
update t_course set click_rate
= #{clickRate} + IFNULL(click_rate,0) where id = #{courseId}
5、最后使用定时任务,每10分钟一次,更新点击量
CourseServiceImpl.java-->updateRateUtilization()
相关文章推荐
- Xcode 6/7添加创建Empty Application方式
- Android FoldingLayout 折叠布局 原理及实现(一)(转)
- Android ListView下拉与上拉刷新加载更多数据 二
- Android Loader
- Android ListView下拉与上拉刷新加载更多(一)
- Android设置虚线、圆角、渐变
- iOS动画编程1-仿射变换
- Android样式开发——常用标签
- Android Studio 出现非法字符 'ufeff'错误
- PHP判断手机是IOS还是Android
- 微信支付PHP SDK之微信公众号支付代码详解
- shadowColor 图片阴影 iOS
- IOS研发之路-Xcode7.1真机调试出现"Could not find Developer
- ios系统中各种设置项的url链接 ,实现跳转系统页面设置
- 《IT蓝豹》一个不错的loading效果
- mutating的使用(swift2.0)
- as在swift中的应用
- 适配iOS9系统
- iOS拨打电话(三种方法)
- ios 应用之间的跳转和数据传输