2012-02-14 64 views
0

我真的有一个相当简单的问题。 我为供应商写了一个servlet来上传XML文件。 这些文件被写入到服务器上的某个位置。 所有文件都被重新命名为一个时间戳。Servlet文件并发

下面的代码是否存在并发问题的风险? 我问,因为我们收到来自供应商的文件,看起来像 他们有2个不同的XML的文件

内容
protected void doGet(HttpServletRequest request, 
     HttpServletResponse response) throws ServletException, IOException { 
    processRequest(request, response); 
} 

protected void doPost(HttpServletRequest request, 
     HttpServletResponse response) throws ServletException, IOException { 
    processRequest(request, response); 
}   

public String getServletInfo() { 
    return "Short description"; 
}// </editor-fold> 

protected void processRequest(HttpServletRequest request, 
     HttpServletResponse response) throws ServletException, IOException { 

    File dirToUse; 
    boolean mountExists = this.getDirmount().exists(); 
    if (!mountExists) { 
     this.log("MOUNT " + this.getDirmount() + " does not exist!"); 
     dirToUse = this.getDiras400(); 

    } else { 
     dirToUse = this.getDirmount(); 
    } 

    boolean useSimpleRead = true; 
    if (request.getMethod().equalsIgnoreCase("POST")) { 
     useSimpleRead = !ServletFileUpload.isMultipartContent(request); 
    } 

    if (useSimpleRead) { 
     this.log("Handle simple request."); 
     handleSimpleRequest(request, response, dirToUse); 

    } else { 
     this.log("Handle Multpart Post request."); 
     handleMultipart(request, response, dirToUse); 
    } 
} 

protected void handleMultipart(HttpServletRequest request, 
     HttpServletResponse response, File dir) throws IOException, 
     ServletException { 
    try { 
     FileItemFactory fac = new DiskFileItemFactory(); 
     ServletFileUpload upload = new ServletFileUpload(fac); 
     List<FileItem> items = upload.parseRequest(request); 

     if (items.isEmpty()) { 
      this.log("No content to read in request."); 
      throw new IOException("No content to read in request."); 
     } 

     boolean savedToDisk = true; 
     Iterator<FileItem> iter = items.iterator(); 
     while (iter.hasNext()) { 
      FileItem item = (FileItem) iter.next(); 

      getFilename(request); 
      File diskFile = new File(dir, this.getFilename(request)); 
      item.write(diskFile); 

      if (!diskFile.exists()) { 
       savedToDisk = false; 
      } 
     } 

     if (!savedToDisk) { 
      throw new IOException("Data not saved to disk."); 
     } 

    } catch (FileUploadException fue) { 
     throw new ServletException(fue); 

    } catch (Exception e) { 
     throw new IOException(e.getMessage()); 
    } 
} 

protected void handleSimpleRequest(HttpServletRequest request, 
     HttpServletResponse response, File dir) throws IOException { 
    // READINPUT DATA TO STRINGBUFFER 
    InputStream in = request.getInputStream(); 
    BufferedReader reader = new BufferedReader(new InputStreamReader(in)); 

    StringBuffer sb = new StringBuffer(); 
    String line = reader.readLine(); 
    while (line != null) { 
     sb.append(line + "\r\n"); 
     line = reader.readLine(); 
    } 

    if (sb.length() == 0) { 
     this.log("No content to read in request."); 
     throw new IOException("No content to read in request."); 
    }  

    //Get new Filename 
    String newFilename = getFilename(request); 
    File diskFile = new File(dir, newFilename); 
    saveDataToFile(sb, diskFile); 

    if (!diskFile.exists()) { 
     throw new IOException("Data not saved to disk."); 
    } 
} 

protected abstract String getFilename(HttpServletRequest request); 

protected void saveDataToFile(StringBuffer sb, File diskFile) throws IOException { 
    BufferedWriter out = new BufferedWriter(new FileWriter(diskFile)); 

    out.write(sb.toString()); 
    out.flush(); 
    out.close(); 
} 

执行的getFileName:

@Override 
protected String getFilename(HttpServletRequest request) { 
    Calendar current = new GregorianCalendar(TimeZone.getTimeZone("GMT+1")); 
    long currentTimeMillis = current.getTimeInMillis(); 

      System.out.println(currentTimeMillis); 
    return "disp_" + request.getRemoteHost() + "_" + currentTimeMillis + ".xml"; 
} 

无论如何,在此先感谢!

+0

请问你的servlet维护任何状态(类级别的变量)?如果没有,我认为你没事。 – kosa 2012-02-14 16:03:29

+0

感谢回复,是的,在类中的一些实例变量,但它们都是最终的...(目录信息,服务器IP地址,电子邮件地址)。 – Treurwilg 2012-02-14 16:07:20

+0

记住,最终并不意味着对象状态不能改变,引用不能改变。只要你的类变量用于读取目的,我认为它是可以的。 – kosa 2012-02-14 16:30:50

回答

0

世上本没有同步问题,但可以有竞争条件,例如,两个线程可能会返回使用该方法的getFileName()相同的文件名

+0

真的吗?你的意思是getTimeInMillis()可以返回相同的值为2个线程?我会环顾网络,看看是否有更好的解决方案。 – Treurwilg 2012-02-15 07:25:58

+0

使用java.util.UUID会更好吗? – Treurwilg 2012-02-15 08:58:37

+0

是UUID是更好的选择,您也可以使用数据库序列来生成唯一标识符 – Gaurav 2012-02-17 07:14:50