【问题标题】:Starting a thread in a java servlet doPost method, cant return back exception messages在 java servlet doPost 方法中启动线程,无法返回异常消息
【发布时间】:2016-05-17 19:53:46
【问题描述】:

我正在制作一个网络应用程序以在线使用 JAVE 库 (http://www.sauronsoftware.it/projects/jave/):

  • 用户填写表格
  • 上传视频
  • 视频由服务器转换
  • 用户下载视频

该界面是一个带有表单的jsp页面,一个上传进度条(使用http://malsup.com/jquery/form/#download制作)和一个用JS制作的进度条,用于在进度servlet上启动ajax轮询(上传进度完成后)。进度 servlet 从 HttpSession 获取编码器监听器,该编码器监听器提供编码进度的 % 值。 我在转换任务时遇到了麻烦,因为它阻止了处理表单的 servlet 的 doPost 方法。因此,用户永远不会收到将进度条的 JS sn-p 置于 complete 状态以启动 ajax-polling 的响应。我想把它放在一个线程中,以便 doPost 方法在转换进行时返回,并且 JS 脚本通过 ProgressServlet 跟踪它。现在的问题是我无法再将异常消息打印回用户。我能做些什么? 这里有一些代码:

Converter 类只是在 try/catch 中执行 enc.encode(...) 方法。

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    Part part = request.getPart("filename");
    InputStream inStream = part.getInputStream();
    String fileName = part.getSubmittedFileName();
    //upload path
    File uploads = new File(System.getProperty("user.home")+System.getProperty("file.separator"));
    File file = new File(uploads,fileName);
    OutputStream outStream = new FileOutputStream(file);
    byte[] buffer = new byte[8 * 1024];
    int bytesRead;
    while ((bytesRead = inStream.read(buffer)) != -1) {
        outStream.write(buffer, 0, bytesRead);
    }
    outStream.close();
    PrintWriter writer = response.getWriter();
    response.setContentType("text/html");
    writer.println("File uploaded");        

    AudioAttributes audio = new AudioAttributes();
    VideoAttributes video = new VideoAttributes();
    EncodingAttributes attrs = new EncodingAttributes();
    Encoder enc = new Encoder();
    EncoderListener elist = new EncoderListener();      
    HttpSession session = request.getSession();
    session.setAttribute("listener", elist);

    File target = new File(System.getProperty("user.home")+System.getProperty("file.separator"),request.getParameter("outFile"));

    attrs.setFormat(request.getParameter("formats"));

    setAttributes(request,audio,video);

    attrs.setVideoAttributes(video);
    attrs.setAudioAttributes(audio);

    //long running task
    Converter conv = new Converter(file,target,enc,elist,attrs);
    Thread t = new Thread(conv);
    t.start();      

}

这是处理上传进度条的sn-p,和转换进度条。

<script>
$(function() {

    var bar = $("#bar");
    var percent = $("#percent");
    var status = $('#status');

    $('form').ajaxForm({
        beforeSend: function() {
            status.empty();
            var percentVal = '0%';
            bar.width(percentVal);
            percent.html(percentVal);
            $("#ConversionBar").width(percentVal);
    		$("#ConversionPercent").html(percentVal);
        },
        uploadProgress: function(event, position, total, percentComplete) {
            var percentVal = percentComplete + '%';
            bar.width(percentVal);
            percent.html(percentVal);
        },
        complete: function(xhr) {
        	status.html(xhr.responseText);
        	var IntervalID = setInterval(function(){
            	$.get("/ElaboratoAT/ProgressServlet",function(data,status){
            		$("#ConversionBar").width(data/10+'%');
            		$("#ConversionPercent").html(data/10+'%');
            		if( data/10 >= 100)
            			clearInterval(IntervalID);
            		$("#download").show();
            	})
            },100);
        }
    });
}); 
</script>
这是提供进度的 servlet。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    HttpSession session = request.getSession();
    response.setContentType("text/html");
    EncoderListener elist = (EncoderListener)session.getAttribute("listener");
    response.getWriter().println(elist.getProgress());
}

感谢您的帮助和时间。

【问题讨论】:

    标签: javascript java multithreading exception servlets


    【解决方案1】:

    为每个请求启动新线程并不是一个好的解决方案。线程应用程序可以启动是有限制的。它最终会耗尽资源。

    要执行长时间运行的任务,您需要异步 servlet。解决方案:

    1. 使用 servlet 中的线程池编写您自己的实现并在其中执行任务。
    2. 使用现有的解决方案,例如Asynchronous processing

    Here is code examples.

    【讨论】:

    • 回复正确的可以接受,让其他人看到。
    猜你喜欢
    • 2011-08-18
    • 1970-01-01
    • 2019-03-04
    • 1970-01-01
    • 2018-11-19
    • 2014-09-27
    • 1970-01-01
    • 2012-02-27
    • 2011-02-01
    相关资源
    最近更新 更多