TechGuy TechGuy - 1 year ago 45
Java Question

Is the below method the best way to count the number of users who has visited a website?

The doGet() method of my ActionServlet reads the data from a textfile which has the count value (Initially 0) and increments it the number of times the ActionServlet is called. And stores this value back in the same file. Is this the best method to count the number of users who has visited my webpage? Am I missing anything? To make it thread-safe can I place this code inside the synchonized block? Does it affect the performance?

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
File file = new File("C:\\Users\\abcd\\workspace\\HitCounter_ForEver\\HitCountFile");
if (file.exists() && !file.isDirectory()) {
BufferedReader br = new BufferedReader(new FileReader(file));
int count = Integer.parseInt(br.readLine());
System.out.println("The Count is :" + count);
count = count + 1;
PrintWriter writer = new PrintWriter(file);

Answer Source

More cleaner approach

  1. Obtain the IP Address of user (String ipAddress = request.getRemoteAddr();) and add it to the Set
  2. The Set should be stored in Application scope
  3. Since you want to persist the hit Count, the size of this set gives you the number of unique users who visited your website
  4. You persist the hit count by implementing ServletContextListener inside contextDestroyed() method
  5. You can retain the previous hit count by reading the previously persisted value using same ServletContextListener inside contextInitialized() method

Note: There is a flaw here and in the previous solution suggested by @Guy Sela. Since you are just persisting the count, if user with same IP visits after your application is restarted, his is counted again, which is incorrect. I would rather serialize the Set during context destruction and deserialize and store it back to Application scope during context initialization