2012-10-19 651 views
1

我有一個系統,其中前端位於javascript/ajax中,後端是使用REST(球衣)編寫的。從服務器下載csv文件

我想使用我的系統下載文件。我尋覓各種論壇和如下實施的REST Web方法:

@POST 
@Produces({"text/csv"}) 
@Consumes(MediaType.APPLICATION_FORM_URLENCODED) 
@Path("getcsv") 
public Response getcsv(
     @FormParam("usernamecsv") String userid, 
     @FormParam("filename") String filename 
     ) 
{ 
    final File fobj = new File("c:/" +userid + "/output/" + filename); 
    try 
    { 
     final FileInputStream f = new FileInputStream(fobj); 
ContentDisposition cd = 
     ContentDisposition.type("file").fileName(fobj.toString()).build(); 
Response response = Response 
.ok() 
.lastModified(new Date(fobj.lastModified())) 
.type("application/octet-stream") 
.header("Content-Disposition", cd) 
.entity(f) 
.build(); 
return response; 
    } 
    catch (FileNotFoundException e1) 
    { 
     // TODO Auto-generated catch block 
     e1.printStackTrace(); 
    } 
    return null; 

}

最初我曾使用StreamingOutput類並實現了write方法吧。在那個方法中,我返回了從文件中讀取的字符串。但是我發現這與上面的實現沒有區別。兩者都返回文件內的字符串。

在我的前端,這是我做了什麼

<!DOCTYPE html > 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> 
<script type="text/javascript" src="jquery-1.7.1.min.js"></script> 
<title>Insert title here</title> 
<script type="text/javascript"> 
function fun1() 
{ 
$.ajax({ 
    url: '/RestWSGS/jersey/UserAuthentication/getcsv', 
    async: false, 
    data: $('#form2').serialize(), 
    type: 'POST', 
    cache: false, 
    contentType: "application/x-www-form-urlencoded", 
    processData: false, 
    dataType: "text", 
    success: function(data) 
    { 
     var iframe; 
     iframe = document.getElementById("hiddenDownloader"); 
     if (iframe === null) 
     { 
      var iframe; 
      iframe = document.getElementById("hiddenDownloader"); 
      if (iframe === null) 
      { 
       iframe = document.createElement('iframe'); 
       iframe.id = "hiddenDownloader"; 
       //iframe.style.visibility = 'hidden'; 
       $("#mydiv").append(iframe); 
      } 
      iframe.src = "http:\\localhost:8080\\c:\[email protected]#26 8 2012 13 5 49/gr1/output/test.csv"; 
//iframe.src = data; 

     } 

     alert('Hi'); 

    } 
}); 
} 
$(function() 
     { 
      $(document).delegate("#mydiv","click",function(ev) 
      { 
      fun1(); 

      }); 
     }); 

</script> 
</head> 
<body> 
<div id="mydiv" style='position:absolute;width:20px;height:20px;background:black'></div> 
<form id="form2" enctype="multipart/form-data" method="post" > 
<input id ="usernamecsv" name="usernamecsv" type="hidden" value="[email protected]#26 8 2012 13 5 49/gr1"/> 
    <input id ="filename" name="filename" type="hidden" value="test.csv" /> 
</form> 

</body> 
</html> 

我的問題是,我得到找不到文件的響應(雖然數據變量的文件的內容),如果我給你的iframe .src與數據變量

如果我把Web服務的uri(我給ajax調用)給iframe.src,我不知道我將如何發送參數。

我真的需要向用戶顯示下載提示,並允許他將文件保存到本地文件系統。我不認爲我的REST是正確的,因爲它應該在POST期間在螢火蟲中顯示文件對象而不是文件的內容!

我可以只返回字符串並填充任何textarea/div,然後讓用戶將其粘貼到他的文件中!但這看起來不夠流暢或優雅!

請幫幫忙, 卡維塔

編輯: 試圖改變@Produces和類型Response.type()爲「application/CSV」以及「應用/的東西」,但它總是試圖追加內容由服務器返回到當前網址的文件,並打開搜索作爲文件顯然沒有找到!

編輯: 我試着在POST中轉換POST到GET並使用返回的數據。然後它返回一個DOCUMENT,但仍然無法打開文件

+0

如果你通過瀏覽器訪問資源,你會得到文件嗎? – BanksySan

+0

什麼給contentType:「text/csv」,? –

+0

@roasted'@Produces({「text/csv」})'註釋會執行。 – BanksySan

回答

0

經過大量的RnD,我認爲我找到了解決我的問題的方法。這可能不是理想的解決方案,請讓我知道是否有任何重大問題。

基本上我試圖訪問我的文件在服務器上,只能從docroot文件夾(PATH = C:\ glassfish3 \ glassfish \ domains \ domain1 \ docroot)訪問它。所以我意識到我必須將我的文件從服務器上的任何位置複製到此位置。我在Web服務中這樣做了。我在某處閱讀,並試圖從Web服務發送文件本身。這個改變後,我錯誤地發回了一個純文本,其路徑相對於docroot。

然後還有另一個挫折,因爲我的文件必須位於一個文件夾內,而文件夾名稱包含一個#字符。它似乎#不允許和iframe只是不會問我的下載!

現在我已經修改我的代碼如下: REST:

@POST 
@Produces(MediaType.TEXT_PLAIN) 
@Consumes(MediaType.APPLICATION_FORM_URLENCODED) 
@Path("getcsv") 
public String getcsv(
     @FormParam("usernamecsv") String userid, 
     @FormParam("filename") String filename 
     ) 
{ 
    System.out.println("1 = " + getClass().getResource("/" +getClass().getName().substring(
      0, getClass().getName().indexOf("."))).getPath()); 
    System.out.println("2 = " + getClass().getResource("/" +getClass().getName().substring(
      0, getClass().getName().indexOf("."))).getPath() + "../../../../../docroot/" + userid + "/" + filename); 
    final File fobj = new File("c:/" +userid + "/output/" + filename); 
    try 
    { 
     final FileInputStream f = new FileInputStream(fobj); 
    int content; 
     ByteArrayOutputStream b = new ByteArrayOutputStream(); 
     try 
     { 
      while ((content = f.read()) != -1) 
      { 
       //b[j] = 0; 
       // convert to byte 
       b.write(content); 
      } 

     } catch (IOException e) 
     { 
      e.printStackTrace(); 
     } 
     finally 
     { 
      try 
      { 
       if (f != null) 
        f.close(); 
      } catch (IOException ex) 
      { 
       ex.printStackTrace(); 
      } 

     } 
     File f1 = new File(getClass().getResource("/"+getClass().getName().substring(
       0, getClass().getName().indexOf("."))).getPath() + "../../../../../docroot/" + userid.substring(0,userid.indexOf("#")) + "/"); 
     f1.mkdirs(); 
     try 
     { 
     boolean f2 = new File(getClass().getResource("/" +getClass().getName().substring(
       0, getClass().getName().indexOf("."))).getPath() + "../../../../../docroot/" + userid.substring(0,userid.indexOf("#")) + "/" + filename).createNewFile(); 
     System.out.println(f2); 

     } 
     catch (IOException e2) 
     { 
      // TODO Auto-generated catch block 
      e2.printStackTrace(); 
     } 
    FileOutputStream fout = new FileOutputStream(new File(getClass().getResource("/" +getClass().getName().substring(
      0, getClass().getName().indexOf("."))).getPath() + "../../../../../docroot/" + userid.substring(0,userid.indexOf("#")) + "/" + filename)); 
    try 
    { 
     fout.write(b.toByteArray()); 
    } 
    catch (IOException e) 
    { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
     try 
     { 
      fout.close(); 
     } 
     catch (IOException e1) 
     { 
      // TODO Auto-generated catch block 
      e1.printStackTrace(); 
     } 
    } 
    try 
    { 
     fout.close(); 
    } 
    catch (IOException e) 
    { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 
    catch (FileNotFoundException e1) 
    { 
     // TODO Auto-generated catch block 
     e1.printStackTrace(); 
    } 
    return "/" + userid.substring(0,userid.indexOf("#")) + "/" + filename; 

我的客戶方代碼:

<!DOCTYPE html > 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> 
<script type="text/javascript" src="jquery-1.7.1.min.js"></script> 
<title>Insert title here</title> 
<script type="text/javascript"> 
function fun1() 
{ 
$.ajax({ 
    url: '/RestWSGS/jersey/UserAuthentication/getcsv', 
    async: false, 
    data: $('#form2').serialize(), 
    type: 'POST', 
    cache: false, 
    contentType: "application/x-www-form-urlencoded", 
    processData: false, 
    dataType: "text", 
    success: function(data) 
    { 
     var iframe; 
     iframe = document.getElementById("hiddenDownloader"); 
     if (iframe === null) 
     { 
      var iframe; 
      iframe = document.getElementById("hiddenDownloader"); 
      if (iframe === null) 
      { 
       iframe = document.createElement('iframe'); 
       iframe.id = "hiddenDownloader"; 
       //iframe.style.visibility = 'hidden'; 
       $("#mydiv").append(iframe); 
      } 


     } 
     iframe.src = data; 
     alert('Hi'); 

    } 
}); 
} 
$(function() 
     { 
    $(document).delegate("#hiddenDownloader","onload",function(ev) 
      { 
     alert('in onload'); 
      }); 

      $(document).delegate("#mydiv","click",function(ev) 
      { 
      fun1(); 

    }); 
     }); 
    </script> 
</head> 
<body> 
<a id ='myhref' href=""></a> 
<div id="mydiv" style='position:absolute;width:20px;height:20px;background:black'></div> 
<form id="form2" enctype="multipart/form-data" method="post" > 
<input id ="usernamecsv" name="usernamecsv" type="hidden" value="[email protected]#26 8 2012 13 5 49/gr1"/> 
    <input id ="filename" name="filename" type="hidden" value="test.csv" /> 
</form> 

    </body> 
</html> 

希望有人發現它有用! 感謝您的意見!

Kavita

+0

下載的文件存在問題。該文件實際上並沒有在我的解決方案中返回,只有從docroot開始的路徑是。有時它會產生字符編碼錯誤,並且不會下載文件。 「框架文檔的字符編碼沒有被聲明,如果沒有文檔框架,文檔可能會出現不同。」這可能是由於未設置文件數據的內容類型。有什麼建議麼?? – kavita

2

您的@Produces標記與您設置的內聯類型衝突。如果你們都讓他們application/octet-stream我希望更好的結果。

+0

這是我用戶iframe.src = data後給我的,並將@produces更改爲app/oct ..但它仍然沒有要求我保存下載。我也改變了dataType:「application/octet-stream」,在ajax中調用 – kavita

+0

Accepts頭只是拼圖的一部分。瀏覽器也會對響應的內容類型作出反應。 – iwein