2016-04-20 10 views
0

ポストパラメータとして巨大な文字列(apprx 301695の長さ)を受け取るサーブレットがあります。サーブレットへのポストパラメータとしての大きな文字列の受け渡し

毎分.netアプリケーションは、このような巨大な文字列をサーブレットに送信します。

当初、私は以下のように文字列を取得するために使用:

Line 1: String str = request.getParameter("data"); 

しかし、3-4時間後。私は次の例外を取得:前述したように、私は同じ例外を取得し、私のサーブレットのコードは、文字列を受信しない、にもかかわらず1:

java.lang.OutOfMemoryError: Java heap space 

をそれから私はラインをコメントしています。

私をご案内ください。この問題はどのように扱うべきですか?私はそれに関連する多くのブログや記事を読んで、ヒープサイズなどを増やしました。しかし、解決策が見つかりませんでした。

オリジナルのコードは以下のようなものだった:

private String scanType = ""; 
private static final String path = "D:\\Mobile_scan_alerts"; 
private static final String stockFileName = "stock.txt"; 
private static final String foFileName = "fo.txt"; 
private static Logger logger = null; 
private String currDate = ""; 
private DateFormat dateFormat; 
private StringBuffer stockData; 
private StringBuffer foData; 
StringBuffer data = new StringBuffer(""); 
// For average time of received data 
private static float sum = 0; 
private static float count = 0; 
private static float s_sum = 0; 
private static float s_count = 0; 
private static float fo_sum = 0; 
private static float fo_count = 0; 

private static final File dir = new File(path); 
private static final File stockFile = new File(path + "\\" + stockFileName); 
private static final File foFile = new File(path + "\\" + foFileName); 

public void init() { 

    logger = MyLogger.getScanAlertLogger(); 

    if(logger == null) { 
     MyLogger.createLog(); 
     logger = MyLogger.getScanAlertLogger(); 
    } 

} 

/** 
* Processes requests for both HTTP <code>GET</code> and <code>POST</code> 
* methods. 
* 
* @param request servlet request 
* @param response servlet response 
* @throws ServletException if a servlet-specific error occurs 
* @throws IOException if an I/O error occurs 
*/ 
protected void processRequest(HttpServletRequest request, HttpServletResponse response) 
     throws ServletException, IOException { 

    PrintWriter out = response.getWriter(); 
    response.setContentType("text/plain"); 
    String strScan = ""; 

    try { 

     String asof = null; 

     scanType = request.getParameter("type"); 
     scanType = scanType == null ? "" : scanType; 


     if(scanType.length() > 0){ 

      if(scanType.equalsIgnoreCase("s")) { 
       stockData = null; 
       stockData = new StringBuffer(request.getParameter("scanData")); 
       stockData = stockData == null ? new StringBuffer("") : stockData; 
      } else { 
       foData = null; 
       foData = new StringBuffer(request.getParameter("scanData")); 
       foData = foData == null ? new StringBuffer("") : foData; 
      } 

     } 

     asof = request.getParameter("asof"); 
     asof = asof == null ? "" : asof.trim(); 

     // Date format without seconds 
     DateFormat formatWithoutSec = new SimpleDateFormat("yyyy/MM/dd HH:mm"); 

     dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); 
     Date tmp = new Date(); 

     // format: yyyy/MM/dd HH:mm:ss 
     currDate = dateFormat.format(tmp); 

     //format: yyyy/MM/dd HH:mm 
     Date asofDate = formatWithoutSec.parse(asof); 
     Date cDate = formatWithoutSec.parse(currDate); 
     cDate.setSeconds(0); 


     System.out.println(asofDate.toString()+" || "+cDate.toString()); 

     int isDataExpired = asofDate.toString().compareTo(cDate.toString()); 

     if(isDataExpired > 0 || isDataExpired == 0) { 

      if(scanType != null && scanType.length() > 0) { 
       checkAndCreateDir(); 
       strScan = scanType.equalsIgnoreCase("s") ? "Stock Data Recieved at "+currDate 
         : "FO Data Recieved at "+currDate; 
       //System.out.println(strScan); 
      } else { 
       strScan = "JSON of scan data not received properly at "+currDate; 
       //System.out.println("GSAS: received null or empty"); 
      } 

     } else { 
      strScan = "GSAS: " + scanType + ": Received Expired Data of "+asofDate.toString()+" at "+cDate.toString(); 
      System.out.println(strScan); 
     } 
     scanType = null; 


    } catch (Exception ex) { 
     strScan = "Mobile server issue for receiving scan data"; 
     System.out.println("GSAS: Exception-1: "+ex); 
     logger.error("GetScanAlertServlet: processRequest(): Exception: "+ex.toString()); 
    } finally { 
     logger.info("GetScanAlertServlet: "+strScan); 
     out.println(strScan); 
    } 

} 

private void checkAndCreateDir() { 

    try { 
      boolean isStock = false; 
      Date ddate = new Date(); 
      currDate = dateFormat.format(ddate); 
      sum += ddate.getSeconds(); 
      count++; 
      logger.info("Total Average Time: "+(sum/count)); 

      if(scanType.equalsIgnoreCase("s")){ //For Stock 
       setStockData(stockData); 

       Date date1 = new Date(); 
       currDate = dateFormat.format(date1); 
       s_sum += date1.getSeconds(); 
       s_count++; 
       logger.info("Stock Average Time: "+(s_sum/s_count)); 

       //file = new File(path + "\\" + stockFileName); 
       isStock = true; 

      } else if (scanType.equalsIgnoreCase("fo")) { //For FO 
       setFOData(foData); 

       Date date2 = new Date(); 
       currDate = dateFormat.format(date2); 
       fo_sum += date2.getSeconds(); 
       fo_count++; 
       logger.info("FO Average Time: "+(fo_sum/fo_count)); 

       //file = new File(path + "\\" +foFileName); 
       isStock = false; 
      } 


      if(!dir.exists()) { // Directory not exists 
       if(dir.mkdir()) { 

        if(isStock) 
         checkAndCreateFile(stockFile); 
        else 
         checkAndCreateFile(foFile); 

       } 
      } else { // Directory already exists 

        if(isStock) 
         checkAndCreateFile(stockFile); 
        else 
         checkAndCreateFile(foFile); 
      } 

    } catch (Exception e) { 
     System.out.println("GSAS: Exception-2: "+e); 
     logger.error("GetScanAlertServlet: checkAndCreateDir(): Exception: "+e); 
    } 

} 

private void checkAndCreateFile(File file) { 

    try{ 
     if(!file.exists()){ // File not exists 

      if(file.createNewFile()){ 
       writeToFile(file); 
      } 

     } else { // File already exists 
      writeToFile(file); 
     } 
    } catch (Exception e) { 
     System.out.println("GSAS: Exception-3: "+e); 
     logger.error("GetScanAlertServlet: checkAndCreateFile(): Exception: "+e.toString()); 
    } 
} 


private void writeToFile(File file) { 

    FileOutputStream fop = null; 

    try{ 

     if(scanType.equalsIgnoreCase("s")){ //For Stock 
      data = getStockData(); 
     } else if (scanType.equalsIgnoreCase("fo")) { //For FO 
      data = getFOData(); 
     } 

     if(data != null && data.length() > 0 && file != null){ 

      fop = new FileOutputStream(file); 

      byte[] contentBytes = data.toString().getBytes(); 
      for(byte b : contentBytes){ 
       fop.write(b); 
      } 
      //fop.write(contentBytes); 

      fop.flush(); 


     } else { 

      System.out.println("GSAS: Data is null/empty string"); 
      logger.info("GSAS: Data is null or empty string"); 

     } 
     data = null; 
    } catch (Exception e) { 
     System.out.println("GSAS: Exception-4: "+e); 
     logger.info("GetScanAlertServlet: writeToFile(): Exception: "+e.toString()); 

    } finally { 

     try { 

      if(fop != null) 
       fop.close(); 

     } catch (IOException ex) { 
       java.util.logging.Logger.getLogger(GetScanAlertServlet.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
} 

private String readFromFile(String fileName){ 

    String fileContent = ""; 
    try{ 

     String temp = ""; 
     File file = new File(fileName); 
     if(file.exists()){ 

      FileReader fr = new FileReader(file); 
      BufferedReader br = new BufferedReader(fr); 

      while((temp = br.readLine()) != null) 
      { 
       fileContent += temp; 
      } 
      br.close(); 
     } else { 
      System.out.println("GSAS: File not exists to read"); 
      logger.info("GetScanAlertServlet: File not exists to read"); 
     } 

     temp = null; 
     file = null; 

    } catch (Exception e) { 
     System.out.println("GSAS: Exception-5: "+e); 
     logger.error("GetScanAlertServlet: readFromFile(): Exception: "+e.toString()); 
    } 
    return fileContent; 
} 

public StringBuffer getStockData() { 

    //String temp=""; 
    //StringBuffer temp = (StringBuffer)scanDataSession.getAttribute("stock"); 
    //if(temp != null && temp.length() > 0) { 
    // return temp; 
    //} 
    if(stockData != null && stockData.length() > 0){ 
     return stockData; 
    } else { 
     stockData = null; 
     stockData = new StringBuffer(readFromFile(path + "\\"+ stockFileName)); 
     return stockData; 
    } 
} 


public StringBuffer getFOData(){ 

    //String temp=""; 
    //StringBuffer temp = (StringBuffer)scanDataSession.getAttribute("fo"); 
    //if(temp != null && temp.length() > 0) { 
    // return temp; 
    //} 
    if(foData != null && foData.length() > 0) { 
     return foData; 
    } else { 
     foData = null; 
     foData = new StringBuffer(readFromFile(path + "\\" + foFileName)); 
     return foData; 
    } 
} 

} 
+0

多分stacktraceと関連するサーブレットコードをコピーすると、誰かがあなたを助けることができます。あなたがその行にコメントした場合、あなたの問題は巨大な文字列を読むこととは何の関係もないようです。 – RubioRic

+0

私はヒープサイズを追跡するためにvisual vmを使用しています。驚くべきことは、たとえ私がその行をコメントしたとしても。しばらくしても同じエラーが表示されます。しかし、古いコードを投稿する: –

+0

あなたのサーブレットはスレッドセーフではないと思います。それとも、SingleThreadModelを実装していますか? – saka1029

答えて

0

ヒープサイズを増やすには、この問題のために良い解決策ではありません。あなたのアップストリームアプリケーションはあなたのサーブレットに巨大な文字列を送るのを止めるべきです。

アップストリーム(.net)アプリケーションはすべてのデータをファイルに書き込むことを検討する必要があります。ファイルの場所をサーブレットのパラメータとして送信するだけで済みます。サーブレットがアップストリームから通知を受信すると、その場所からファイルをダウンロード/読み込みすることを検討します。

は、その後、私はラインを次のようにコメント(コメントとして)1はいっても、私のサーブレットコードは は、文字列を受信しない、私は上記の と同じ例外を取得します。

行:1はデータを読み込みます。あなたがコメントした場合、文字列は受け取られません。

+0

時間が重要なので、ファイルをダウンロードする余裕はありません。実際には、受け取る文字列はJSON文字列であり、jsonオブジェクトをスキャンしてそこからデータを取得する必要があります。 –

+0

あなたの現在のXmsとXmxは何ですか? –

+0

それぞれ128mと1024m –

0

あなたは、Apacheコモンズ・ファイルアップロードライブラリストリーミングAPI、この方法を使用することができ、あなたはストリームとしてアップロードしたファイルを取得し、ファイルに書き込む:あなたはそれを書くことができますので、今

ServletFileUpload upload = new ServletFileUpload(); 

// Parse the request 
FileItemIterator iter = upload.getItemIterator(request); 
while (iter.hasNext()) { 
    FileItemStream item = iter.next(); 
    String name = item.getFieldName(); 
    InputStream stream = item.openStream(); 
    if (item.isFormField()) { 
     System.out.println("Form field " + name + " with value " 
      + Streams.asString(stream) + " detected."); 
    } else { 
     System.out.println("File field " + name + " with file name " 
      + item.getName() + " detected."); 
     // Process the input stream 
     ... 
    } 
} 

あなたは、InputStreamを持っています出力ストリームに格納されます。

しかし、これを使用するには、String全体をリクエストパラメータとして送信するのではなく、.NETアプリケーションを使用してバイトをサーバーにアップロードする必要があります。

http://commons.apache.org/proper/commons-fileupload/streaming.html

0

あなたのVM引数を確認し、サーブレットに渡される文字列のを制御することはできません場合はapproriatelyそれらを変更してください。例:

set JAVA_OPTS=-Dfile.encoding=UTF-8 -Xms128m -Xmx1024m -XX:PermSize=64m -XX:MaxPermSize=256m 

完全な説明hereを確認してください。

0

文字列のサイズを小さくするためにGZip圧縮/圧縮解除を使用しました。そしてそれは効果的に働いた。

したがって、.netサービスは膨大な文字列を圧縮し、サーブレットに送信しました。その後、サーバーで解凍します。

関連する問題