【问题标题】:Java polling 5 times after every 5 secs每 5 秒后 Java 轮询 5 次
【发布时间】:2023-03-29 13:10:01
【问题描述】:

单击下载按钮从 SAN 位置获取 PDF。但有时由于 XYZ 原因,文档在 SAN 不可用。我需要实现一个轮询机制,以便在每 5 秒后单击下载在 SAN 位置搜索文档 5 次,并返回迭代号。搜索成功后在日志中。

package abc.documentdownload;

import abc.util.Email;

import java.io.BufferedOutputStream;
import java.io.IOException;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;

import javax.servlet.*;
import javax.servlet.http.*;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class DownloadDocServlet extends HttpServlet {
    private static final Log log = LogFactory.getLog(DownloadDocServlet.class);
    private static final String CONTENT_TYPE = "text/html; charset=windows-1252";

    public void init(ServletConfig config) throws ServletException {
        super.init(config);
    }

    public void doGet(HttpServletRequest request,
                      HttpServletResponse response) throws ServletException,
                                                           IOException {
        doPost(request, response);
    }

    public void doPost(HttpServletRequest request,
                       HttpServletResponse response) throws ServletException,
                                                            IOException {
        response.setContentType(CONTENT_TYPE);
        DownloadDocDAO DownloadInstance = new DownloadDocDAO();
        String downloadType = request.getParameter("downloadType");
        String pNumber = request.getParameter("PNumber");
        BufferedOutputStream output = null;
        String strFileName = pNumber + ".pdf";
        if(downloadType != null && downloadType.equalsIgnoreCase("download")){
            try{
                byte[] content=DownloadInstance.getP(pNumber);                
                log.info("COnverting content into PDF in EmailServlet");
                System.out.println("COnverting content into PDF in EmailServlet");
                response.setContentType("application/pdf");
                response.setHeader("Content-Disposition","attachment; filename=\"" + strFileName + "\"");
                response.setHeader("Cache-Control","no-cache"); 
                response.setHeader("Cache-Control","no-store"); 
                response.setHeader("Pragma","no-cache");
                response.setDateHeader("Expires", 0);
                output = new BufferedOutputStream(response.getOutputStream());
                output.write(content);
                output.flush();                            
                output.close();                

            }
            catch (Exception ex) {
                ex.printStackTrace();
                log.error("Error in DownloadDocServlet ", ex);
                /* Using the below block to trigger the email whenever there is a error*/
                Writer result = new StringWriter();
                PrintWriter printWriter = new PrintWriter(result);
                ex.printStackTrace(printWriter);
                Email emailSend = new Email();                                  
                int strEmailConfirm = emailSend.sendEmail("Exception in DownloadDocServlet of documentdownload package for pno :"+pNumber,"<B>Please find Exception Details for the DownloadDocServlet of documentdownload package</b><br><br>"+result.toString());
                log.info("strEmailConfirm in DownloadDocServlet"+strEmailConfirm); // if value is 1 ,  mail will be trigger is successful 
            } 
        }        
    }


}

【问题讨论】:

  • 很好 - 有什么问题吗?
  • @ScaryWombat - 我不知道如何使用计时器/轮询机制。如果你能帮忙写代码
  • 来个简单的5秒睡眠循环怎么样
  • @ScaryWombat 我很害怕,一个简单的 sleep 循环就可以解决问题

标签: java arrays timer polling


【解决方案1】:

您也可以使用awaitility 来完成此操作。使用方法请查看this link

【讨论】:

    【解决方案2】:

    线程睡眠对我来说效果很好

     for(int i=0;i<5;i++)
                     {
                         content=getPDAO.getPFromEb( strPN);
                          DateFormat df = new SimpleDateFormat("dd/MM/yy HH:mm:ss");
                          Date dateobj = new Date();
                        if(content==null) 
    
                         {  
                            Thread.sleep(5000);
                            }
                        else {
                            content=getPDAO.getPFromEb( strPN);
                            break;
                        }
                     } 
    

    【讨论】:

      【解决方案3】:

      你需要的是某种计时器。这是一个关于如何使用TimerTasks的示例。

      首先是Timer

      Timer downloadTimer = new Timer();
      

      在您安排TimerTask 之前,它不会执行任何操作:

      TimerTask downloadTask = new TimerTask() {
          @Override
          public void run() {
             //try to download here
          };
      }
      

      现在您需要安排任务:

      downloadTimer.schedule(downloadTask,1000,5000); 
      

      这告诉您的downloadTimer,您希望downloadTask 在 1 秒内第一次执行 (1000 milliseconds),然后每 5 秒执行一次 (5000 milliseconds)。

      但它会持续运行,除非您在成功下载或任务执行 5 次后停止任务:

      private int count;
      public void run() {
         if(count++==5){
             downloadTimer.cancel();  // will stop the timer
             downloadTimer.purge();   // will remove all canceled tasks from the timer
             return;   // makes sure the task will not be executed to the end
         }
         // try to download here
         // if download successful cancel and purge as well
      };
      

      这应该可以解决问题,但我不能说这是否是您问题的最佳解决方案。

      【讨论】:

      • Thnx @gamedroids 但请您帮忙解释为什么计时器在这里很特别。正如上面可怕的袋熊所说,睡眠的简单循环不会做同样的事情。 while(content!=null || counter
      • Thread.sleep 也可能是一个不错的选择。这取决于您的情况,以及您要“休眠”的线程是否保留任何资源并因此为其他线程阻塞它们。也许this post 可以对此有所了解并帮助您决定什么是最好的。您还应该考虑,最好让“调用者”每 5 秒重试一次,还是让“servlet”重试一次。请注意,当 servlet 响应时间过长时,调用方可能会遇到超时。
      • 谢谢,我使用了 sleep 并且效果很好。我如何在我的代码中添加等待加载器,直到线程休眠?
      • 由于它是一个 servlet,您的等待加载器位于前端的其他位置 - 无论是 html 还是其他,您都应该能够显示动画 gif 或无尽的进度条。但是你应该为此提出一个新问题,展示一些前端代码。
      猜你喜欢
      • 2015-12-29
      • 2013-04-25
      • 1970-01-01
      • 1970-01-01
      • 2016-03-21
      • 2012-04-04
      • 1970-01-01
      • 2019-10-12
      • 2019-01-31
      相关资源
      最近更新 更多