struts2中通过Action以InputStream的下载文件以及在iOS以及Android端接收的实现方式

转载 2016年08月30日 09:41:08

struts2中通过Action以InputStream的下载文件以及在iOS以及Android端接收的实现方式

最近在移动开发中遇到了一些文件下载的问题,实现后特地记录一下,以备以后查阅。

最简单的下载的实现方式是将文件的在网络上的URL直接发送给手机,然后手机通过URL来请求这个文件,这么做有个缺点无法对请求的用户进行准确的验证。另一种方法是通过Action先对用户的身份验证通过后再发送文件给手持设备(请求端)。下面就来实现第二中方式。

 

  • 服务器端非常简单,就是写个xml的配置文件,和实现一个简单的action即可。

struts.xml的配置文件如下:

复制代码
<result name="download" type="stream">
  <param name="contentType">application/octet-stream</param>
  <param name="inputName">targetFile</param>
  <param name="contentDisposition">${suffix}</param>
  <param name="contentLength">${fileSize}</param>
  <param name="bufferSize">4096</param>
</result>
复制代码

说明:

contentType:指定文件的类型,application/octet-stream代表所有的文件类型,查看其他的文件类型描述;
inputName:文件的InputStream流,action中需要提供一个返回InputStream的getTargetFile()方法;

contentDisposition:下载文件的文件名,${suffix}指到action中获取getSuffix()方法的返回值;也可以在这里放置filename=${fileName},这样通过浏览器访问的时候浏览器会自动查找到文件名,并显示出来;
contentLength:下载的当前文件的大小,获取方式同上,类型是long
bufferSize:缓存的大小

action对象实现如下:
/**
     * 文件的输出流
     * @return
     * @throws Exception
     */
    public InputStream getTargetFile() throws Exception {
        java.io.File f = new java.io.File("D:\\test.avi");
        if (f.exists()) {
            return new FileInputStream(f);
        else {
            return null;
        }
    }
      
    /**
     * 设置返回的文件的名字
     * @return
     */
    public String getFileName() {
        return "test.avi";
    }
      
    /**
     * 设置返回的文件的大小
     * @return
     */
    public long getFileSize() {
        java.io.File f = new java.io.File("D:\\test.avi");
        return f.length();
    }
      
    /**
     * 执行请求的逻辑处理,然后根据结果来判断是否返回文件
     * @return
     */
    public String download() {
       //进行认证或其它的逻辑检查
        if(true){
            return "download";
        }
        return "error";
    }
  •  移动请求端实现如下:

    iOS端

网络访问端代码如下:

[objc] view plain copy
  1. NSURL *downloadURL = [NSURL URLWithString:url];  
  2. NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:downloadURL];  
  3. NSHTTPURLResponse *response = nil;  
  4. NSError *error = nil;  
  5. NSData *resData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];  
  6. if(error)  
  7. {  
  8.       NSLog(@"请求下载文件失败,错误信息:%@",error);  
  9.       return nil;  
  10. }  
  11. if(resData)  
  12. {  
  13.      if(response && [response respondsToSelector:@selector(allHeaderFields)])  
  14.    {  
  15.           NSDictionary *httpResponseHeaderFields = [response allHeaderFields];//获得相应的头  
  16.           long size = [[httpResponseHeaderFields objectForKey:@"Content-Length"] longLongValue];//获得文件的大小,是由服务器在相应头中传递过来的  
  17.           NSString *fileSuffix = [httpResponseHeaderFields objectForKey:@"Content-Disposition"];//我在的服务器端设置的存放后缀名  
  18.           VSFileUtil *fileUtil = [[VSFileUtil alloc]init];//自定义的一个文件工具类  
  19.           NSString *filePath = [fileUtil writeToFileWithNSData:resData FileName:[fileId stringByAppendingFormat:@".%@",fileSuffix]];//创建文件  
  20.           return filePath;  
  21.       }  
  22. }  

    文件工具类的代码如下:

[objc] view plain copy
  1. NSArray *dir = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);//获得Library/Caches目录,该目录程序退出不会清空,iTunes也不备份此目录  
  2. NSString *cDownloadBaseFolderPath = [[dir objectAtIndex:0] stringByAppendingPathComponent:@"FMADownload"];//创建Library/Caches/FMADownload目录作为下载目录  
  3. NSString *filePath = [cDownloadBaseFolderPath stringByAppendingPathComponent:file];//根据文件名和路径构建出文件的绝对路径  
  4. NSFileManager *fm = [NSFileManager defaultManager];//获取文件管理器  
  5. [fm removeItemAtPath:filePath error:nil];//如果文件已经存在则移除该文件,文件不存在时也不会抛出异常,如果想捕获提示信息,可以定义一个NSError传递给error参数即可  
  6. if([data writeToFile:filePath atomically:YES])//以原子处理的方式将内容写进文件中  
  7. {  
  8.    return filePath;  
  9. }  
  10. else  
  11. {  
  12.    return nil;  
  13. }  

 

    Android端

    这个由于是java开发的,这个过程将变得比iOS上简单n倍,具体代码如下:

 

[java] view plain copy
  1. public void download() throws Exception {  
  2.     InputStream is = null;  
  3.     BufferedInputStream bis = null;  
  4.     FileOutputStream fos = null;  
  5.     BufferedOutputStream bos = null;  
  6.     try {  
  7.         httpClient = new DefaultHttpClient(new BasicHttpParams());  
  8.         HttpPost httpRequest = new HttpPost(validateURL);//validateURL是的请求地址  
  9.         HttpResponse response = httpClient.execute(httpRequest);  
  10.         Header[] headers = response.getAllHeaders();  
  11.         long size = 0;//文件大小  
  12.         String suff = "";//文件后缀名  
  13.         for(Header h : headers) {  
  14.             if("Content-Disposition".equals(h.getName())) {  
  15.                 suff = h.getValue();  
  16.                 Log.i("janken", suff);  
  17.             } else if ("Content-Length".equals(h.getName())) {  
  18.                 size = Long.valueOf(h.getValue());  
  19.                 Log.i("janken", size + "");  
  20.             }  
  21.         }  
  22.         if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {  
  23.             throw new Exception("请求失败");  
  24.         }  
  25.         HttpEntity resEntity = response.getEntity();  
  26.         is = resEntity.getContent();//获得文件的输入流  
  27.         bis = new BufferedInputStream(is);  
  28.         File newFile = new File("/sdcard/test." + suff);  
  29.         fos = new FileOutputStream(newFile);  
  30.         bos = new BufferedOutputStream(fos);  
  31.               
  32.         byte[] bytes = new byte[4096];  
  33.         int len = 0;//最后一次的长度可能不足4096  
  34.         while((len = bis.read(bytes)) > 0) {  
  35.             bos.write(bytes,0,len);  
  36.         }  
  37.         bos.flush();  
  38.     } finally {  
  39.         if(bis != null)bis.close();  
  40.         if(bos != null)bos.close();  
  41.         if(fos != null)fos.close();  
  42.         httpClient.getConnectionManager().shutdown();  
  43.     }  
  44. }  

 

  

 转自:http://www.cnblogs.com/janken/archive/2012/06/06/2534977.html

sturts2上传文件,后台获取不到文件!

struts2上传文件,后台获取不到文件!         对于大部分程序员来说 文件上传功能应该并不会陌生,因为这个功能我们经常会用到!!       同样的,本人也经常用到这个功能,但是我发...

IOS文件操作的两种方式:NSFileManager操作和流操作

1、文件的创建   -(IBAction) CreateFile { //对于错误信息 NSError *error; // 创建文件管理器 NSFileMa...
  • likendsl
  • likendsl
  • 2012年12月20日 11:12
  • 45288

在 ios 下实现 DataOutputStream 和 DataInputStream

我们在java通讯,常用 DataOutputStream 和 DataInputStream 这两个数据流,客户端是android和j2me 的话没有什么大问题,如果是iphone和bada就比较麻...
  • jxncwzb
  • jxncwzb
  • 2011年08月17日 11:56
  • 4042

iOS之文件上传、下载(上传)

iOS中用系统提供的API能实现能实现文件的上传与下载,分别有两种方式。NSURLConnection与NSURLSession。 其中NSURLConnection是使用很久的的一种方式,NSUR...

struts2中通过Action以InputStream的下载文件以及在iOS以及Android端接收的实现方式

struts2中通过Action以InputStream的下载文件以及在iOS以及Android端接收的实现方式 最近在移动开发中遇到了一些文件下载的问题,实现后特地记录一下,以备以...

struts2使用action方式实现文件下载(支持中文文件名)

action类: [java] view plaincopy package com.fsti.ssh.action; import java.io.Inpu...
  • kkkennn
  • kkkennn
  • 2014年03月01日 21:41
  • 330

struts2使用action方式实现文件下载(支持中文文件名)

转载自:http://blog.csdn.net/lisq037/article/details/9014563 目录(?)[+] 【1】支持中文名称文件(源文...

struts2使用action方式实现文件下载(支持中文文件名)

【1】支持中文名称文件(源文件中文名称、下载另存为为中文名称)【2】加入session判断,还可进行权限控制 action类: package com.fsti.ssh.action; ...
  • lisq037
  • lisq037
  • 2013年06月03日 16:22
  • 7013

struts2自主学习之配置国际化资源文件,传统异常处理方式, 拦截器,实现action 控制类,访问servletAPI,使用拦截器注解

struts2自主学习之配置国际化资源文件,传统异常处理方式, 拦截器,实现action 控制类,访问servletAPI,使用拦截器注解...

struts2——文件的下载以及在Action中获取请求参数的方式

前一天,上传了关于struts2文件的下载方式,今天正好补上关于struts2文件下载的方式。 1、开发环境 jdk1.7.0-51 myEcplise10 struts-2.3.32 2.web....
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:struts2中通过Action以InputStream的下载文件以及在iOS以及Android端接收的实现方式
举报原因:
原因补充:

(最多只允许输入30个字)