Cyh的博客

Email:kissyan4916@163.com
posts - 26, comments - 19, trackbacks - 0, articles - 220

sturts2的上传和下载以及中文转码问题

Posted on 2009-05-22 23:06 啥都写点 阅读(1069) 评论(1)  编辑  收藏 所属分类: J2EE
     关于如何在项目中添加struts2这里就不在多说了,struts2上传下载所需要的jar包大家可以去www.apache.org进行下载,在Jakarta下的选择
 Commons,然后下载FileUpload 和 IO这两个jar包。解压后拷贝到你的项目lib文件夹下就OK了。

     下面直接开始struts2的上传:

     首先创建一个文件上传的Action,以下注释部分为批量上传时的代码,大同小异!
    
public class UploadAction extends ActionSupport {
  
   。。。省略了 getter 和 setter方法
  
   
private String title;
    
//单个文件 
    private File upload;
    
    
    
// 多个文件
    
// private String[] upload;
    
//保存上传文件的文件夹名字,可在配置文件中动态指定
   
    
private String savePath;
    
    
private String uploadContentType;
   
    
private String uploadFileName;

    
public String getSavePath() {
         String s 
=  ServletActionContext.getRequest().getRealPath(savePath);
         System.out.println(s);
         
return s;
    }

    @Override
    
public String execute() throws Exception {
        System.out.println(
"进入 execute方法");
        
//查看上传文件的大小
        System.out.println("所上传的文件的大小为"+getUpload().length());
        
        
//查看上传文件的名字
        System.out.println("UploadFileName:"+getUploadFileName());
        
        
//指定上传文件到哪个文件夹
        FileOutputStream fos = new FileOutputStream(savePath+"\\"
                
+getUploadFileName());
        
//取得一个将要上传的文件的一个输入流
        FileInputStream fis = new FileInputStream(getUpload());
        
        
//当图片需要存储进数据库时,可以将图片的连接存储进数据库,譬如:
        
//path路径是需要读进数据库滴,所以这里不能使用 getSavePath(),因为这样返回的是绝对路径。
        String path = savePath+"\\"+getUploadFileName();
        
        
byte[] buffer = new byte[1024];
        
        
int len = 0 ;
        
        
while((len = fis.read(buffer))>0) {
            fos.write(buffer, 
0, len);
        }
        System.out.println(
"文件已上传");
        
        
return SUCCESS;
    }

    
//完成多个文件的上传
//    public String execute() throws Exception {
//
//        
//        //查看上传文件的名字
//        System.out.println("UploadFileName:"+getUploadFileName());
//        
//        //指定上传文件到哪个文件夹
//        FileOutputStream fos = new FileOutputStream(savePath+"\\"
//                +getUploadFileName());
//        
//        String[] ss = getUpload();
//        for(int i=0;i<ss.length;i++){
//            //取得一个将要上传的文件的一个输入流
//        FileInputStream fis = new FileInputStream(ss[i]);
//        
//        //当图片需要存储进数据库时,可以将图片的连接存储进数据库,譬如:
//        //path路径是需要读进数据库滴
//        String path = savePath+"\\"+getUploadFileName();
//        
//        byte[] buffer = new byte[1024];
//        
//        int len = 0 ;
//        
//        while((len = fis.read(buffer))>0) {
//            fos.write(buffer, 0, len);
//        }    

//        return SUCCESS ; 
//    }
  

    
}

文件上传的页面index.jsp
<body>
      
<s:fielderror/>
      
<s:form action="ryanUpload" enctype="multipart/form-data">
        
<s:textfield label="title" name="title"/>
            
<!-- 单个文件上传 -->
         
<s:file name="upload" label="文件1"/>     
        
<!-- 多个文件上传 
       
        
<s:file name="upload" label="文件1"/>
        
<s:file name="upload" label="文件2"/>
        
<s:file name="upload" label="文件3"/>

      
-->
      
<s:submit/>
      
</s:form>
  
</body>
在来看看struts.xml中的配置,
<struts>
     
<constant name="struts.i18n.encoding" value="GBK"/>
     
     
<package name="ryan" extends="struts-default">
     
        
<action name="ryanUpload" class="com.UploadAction">
            
<result name="success">/succ.jsp</result>
          
            
<result name="input">/index.jsp</result>
           
            
<!-- 动态指定上传文件的目录 -->
             
<param name="savePath">/upload</param>   <!--  在此处可以动态的指定服务器上存储图片的文件夹 --> 
            
            
<interceptor-ref name="fileUpload">
               
<param name="allowedTypes">image/bmp,image/png,image/gif,image/jpeg</param>
               
<param name="maximumSize">3000000000</param>  <!--  这里的单位为字节  -->
            
</interceptor-ref>
            
            
<interceptor-ref name="defaultStack"/>
        
</action>
      
         
        
    
</package>

</struts>

struts2下载(参考了beansoft的文章):
   
   
  一般在项目中所用到下载都是直接根据数据库读出的地址来进行下载,譬如有下面一个链接:
 
   <!-- 假设有这样一条从数据库中读出的数据 ,它的存储路径为 downLoad/ryan.jsp ,文件名字为ryan.jsp
                很明显这是一张图片,那么我们点击下载时就会根据path来进行下载
                                                     
-->

    <s:url action="downLoad" id="down">
      <s:param name="inputPath">downLoad/ryan.jsp</s:param>
      <s:param name="fileName">ryan.jsp</s:param>
    </s:url>
   
    <s:a href="%{down}">downLoad</s:a>


来看看我们的struts.xml中的配置

<struts>
  
<package  name="technicalInformationAction"   extends="Action">
   
    
<default-action-ref name="download"/>
 

     
<action name="downLoad" class="com.DownLoadAction">
               
                <!--这里的返回值并不是字符串,而是一个流类型-->  
                
<result name="success" type="stream">
                
                
<param name="contentType">application/octet-stream;charset=ISO8859-1</param>
                
                
<param name="inputName">inputStream</param>
             
       
                 <!--这里需要将文件名进行转码,转码后将值赋予
downloadFileName, 对应文中的getDownloadFileName()-->        
                
<param name="contentDisposition">attachment;filename="${downloadFileName}"</param> 
               
                
<param name="bufferSize">4096</param>
                
                
</result> 
     
</action> 
  
  
</package>
</struts>

下载文件的DownLoadAction:

public class DownLoadAction implements Action{

    
private String fileName;// 初始的通过param指定的文件名属性

    
private String inputPath;// 指定要被下载的文件路径
    
    String username 
= "chenyanhu";

    
public InputStream getInputStream() throws Exception {

    
// 通过 ServletContext,也就是application 来读取数据
   
    
return ServletActionContext.getServletContext().getResourceAsStream("/"+inputPath);

    }
    
     /**
      *   execute中代码的含义是为了防止他人恶意的下载项目的WEB-INF/web.xml文件,譬如在浏览器中输入
      *  http://......./downLoad.action?inputPath=WEB-INF/web.xml  这样将下载下的文件后缀名改为xml就可以查看你的项目的web.xml了

      *  execute中代码的意思是将文件存储的真实目录与地址栏的路径进行对比。
发现企图下载不在/download下的文件,就显示内容为空
      */ 
   

public
 String execute()
        
        
// 文件下载目录路径

        String downloadDir = ServletActionContext.getServletContext().getRealPath("/technicalInformationDirectory"+"/"+username);

        
// 文件下载路径

        String downloadFile 
= ServletActionContext.getServletContext().getRealPath("/"+inputPath);

        java.io.File file 
= new java.io.File(downloadFile);
   try{
        downloadFile 
= file.getCanonicalPath();// 真实文件路径,去掉里面的..等信息

        
if(!downloadFile.startsWith(downloadDir)) {

        
return null;

        }
   }catch (IOException io) {
        // TODO: handle exception
        System.out.println("IO异常!!路径发生错误!");
        io.printStackTrace();
    }catch (SecurityException se) {
        // TODO: handle exception
        System.out.println("安全性异常!!");
        se.printStackTrace();
    }catch (NullPointerException  npe ) {
        System.out.println("空指针异常");
        npe.printStackTrace();
    }catch (Exception e) {
        System.out.println("出现异常了!");
        e.printStackTrace();
    }
        
return SUCCESS;     
        

    }



    
// 提供转换编码后的供下载用的文件名 

    
public String getDownloadFileName() {

    String downFileName 
= fileName;

    
try {

    downFileName 
= new String(downFileName.getBytes(), "ISO8859-1");

    } 
catch (UnsupportedEncodingException e) {

    e.printStackTrace();

    }

    
return downFileName;

    }
  


    }
   


关于中文转码的问题:
    
      我在项目中遇到了一个问题,那就是下载文件的时候,不能对含有中文名字的文件进行下载,老是出现乱码,但是数据库中
  
    是没有乱码的,今天花了比较长的时间去解决这个问题,不过现在我已经把这个问题解决, 就是需要修改tomcat的server.xml文件  :
 
              <Connector port="8641" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" URIEncoding="utf-8"/>
  
    加上红色部分就OK了!!




                                                                                                       --    学海无涯
        

Feedback

# re: sturts2的上传和下载以及中文转码问题  回复  更多评论   

2009-09-05 09:21 by aasd
sdf

只有注册用户登录后才能发表评论。


网站导航: