使用Spring application对象存储全局变量,统计链接的点击量

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/yansong_8686/article/details/50225995

 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()
展开阅读全文

没有更多推荐了,返回首页