任务要求:
在一些站点中,经常会看到网站计数器的功能。要点:
网站的来访人数可能会很多,有可能超过20位整数,大整数类BigInteger
使用application范围的属性保存计数。
用户每次在第一次访问时才需要进行计数的操作,而重复刷新页面时则不应重复计数,使用isNew()判断用户是否是第一次访问。
Web开发属于多线程操作,所以在进行更改、保存时需要进行同步操作。
首先看一下普通的网站计数器
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%!
int i = 0 ;
synchronized void count(){
i++;
}
%>
<%
count();
%>
您是第<%=i %>个访问该页面的人
</body>
</html>
对于上面的普通累加计数器,刷新页面是可以累积加1的,而且就算是关闭浏览器重新再打开浏览器进行运行的话也是继续进行原本的累加.
再看一下application对象普通的网站计数器
<%@ page contentType="text/html; charset=gb2312" language="java" errorPage="" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>计数器</title>
</head>
<body>
<%
int number=0;
if(application.getAttribute("number")==null){
number=1;
}else{
number=Integer.parseInt((String)application.getAttribute("number"));
number=number+1;
}
out.print("您是第"+number+"位访问者!");
application.setAttribute("number",String.valueOf(number));
%>
</body>
</html>
对于上面的application对象普通累加计数器,刷新页面也是可以累积加1的,而且就算是关闭浏览器重新再打开浏览器进行运行的话也是继续进行原本的累加.
这次看一下符合任务要求的application对象的使用:
<%@page import="java.math.BigInteger"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
BigInteger counter = (BigInteger)application.getAttribute("count");//当没有count属性的时候,返回的是null
if(counter == null){
counter = new BigInteger("0");
}
if(session.isNew()){//判断是否是新的用户(刷新的时候session不会变,所以不进行累加)
synchronized (this){
counter = counter.add(new BigInteger("1"));//大整数进行加1
application.setAttribute("count", counter);//application修饰全局
}
}
%>
<font color="red" size=6>您是第<%=counter %>个访问该网站的用户</font>
</body>
</html>
这样就完成了网站计数器的任务,刷新页面不会进行累加,当关闭浏览器重新运行的时候就会再次累加
再看一个同样效果,复杂的实现:(初学者不推荐使用)
<%@ page language="java" contentType="text/html; charset=GBK"
pageEncoding="GBK"%>
<%@ page import="java.io.*"%> <%--由于要使用IO操作,必须导入java.io包--%>
<%@ page import="java.util.*"%> <%--Scanner在java.util包中定义--%>
<%@ page import="java.math.*"%> <%--BigInteger定义在java.math包中--%>
<!DOCTYPE html>
<html>
<head>
<!-- <meta charset="UTF-8"> -->
<title>Insert title here</title>
</head>
<body>
<%!
BigInteger count=null; //定义成全局变量
%>
<%!
public BigInteger load(File file){ //读取计数文件
BigInteger count=null; //接受计数文件
try{
if(file.exists()){ //如果文件存在,则读取
Scanner scan=null; //定义Scanner对象
scan=new Scanner(new FileInputStream(file));//从文件中读取
if(scan.hasNext()){ //存在内容
count=new BigInteger(scan.next());//将内容放到BigInteger类中
}
scan.close(); //关闭输入流
}else{ //文件不惨在则创建新的
count=new BigInteger("0"); //第一次访问
save(file,count); //调用save(),保存新的文件
}
}catch(Exception e){
e.printStackTrace();
}
return count; //返回读取后的数据
}
public void save(File file,BigInteger count){ //保存计数文件
try{
PrintStream ps=null; //定义输出流对象
ps=new PrintStream(new FileOutputStream(file));//打印流对象
ps.println(count);//保存数据
ps.close();//关闭输出流
}catch(Exception e){
e.printStackTrace();
}
}
%>
<%
String fileName=this.getServletContext().getRealPath("/")+"count.txt"; //文件路径
File file =new File(fileName);
if(session.isNew()){
synchronized(this){ //必须进行同步操作
count=load(file);
count=count.add(new BigInteger("1"));//自增操作
save(file,count); //保存修改后的数据
}
}
%>
<h2>您是第<%=count==null?0:count%>位访客!</h2>
</body>
</html>