2012-02-14 58 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