2012-10-19 763 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