zoukankan      html  css  js  c++  java
  • Struts 2读书笔记使用Struts 2控制文件下载

              一般来说,文件下载只需要直接在页面给出一个超级链接,该链接的href属性值等于要下载文件的文件名,就可以实现文件下载,如:<a href=checkbox.rar”>checkbox.rar</a>。但是这样下载存在着一些缺陷:如果该文件的文件名是中文文件名时,下载则会导致下载失败;如果在下载时需要对用户的身份进行判断,来验证用户是否有权限来下载该文件时,那么单独的超级链接是不可能实现的。这个时候,我们需要用Struts 2来控制文件下载。

              Struts 2提供了stream结果类型,该结果类型就是专门用于支持文件下载功能的。通过Struts 2的文件下载支持,允许系统控制浏览者下载文件的权限,实现文件名是非西欧字符的文件下载。

              首先介绍利用Struts 2实现简单的文件下载:

    public class FileDownloadAction implements Action { 
    
    	public InputStream getInputStream() throws Exception { 
    
    		return new ByteArrayInputStream("Struts 2 下载示例".getBytes()); 
    
    	} 
    
    	public String execute() throws Exception { 
    
    		return SUCCESS; 
    
    	} 
    
    }
    


     

              该类只是一个简单的Action处理类。它提供了一个返回inputStream输入流的方法。该输入流代表了下载文件的入口。这个方法用来给被下载的数据提供输入流。

     

              一、利用Struts 2实现文件名非西欧字符文件下载

              有如下一个下载页面代码:

    <a href="download1.action?image/美女_01.jpg" >下载图片</a>
    <a href="download2.action?image/meinv_01.rar">下载压缩文件</a>

              上面页面中包含了两个下载的链接。但是第一个链接资源的文件名为中文,这时如果我们单击第一个超级练级,将会出现如下页面:


             从上面的页面中我们可以看到大量的%字符,很明显,这种文件名师不能够实现下载的。这时我们可以使用Struts 2的文件下载支持来下载该文件。

             1、实现文件下载的Action

             Struts 2的文件下载Action需要提供一个返回InputStream流的方法。

             代码如下:

    public class FileDownloadAction extends ActionSupport{
    	//该属性可以在配置文件中动态指定该属性值
    	private String inputPath;
    
    	public void setInputPath(String inputPath) {
    		this.inputPath = inputPath;
    	}
    	
    	/*定义一个返回inputStream的方法
    	 * 该方法将作为下载文件的入口,且需要配置stream类型结果是指定inputName参数
    	 * inputName参数的值就是方法去掉get前缀、首字母小写的字符串
    	 */
    	public InputStream getTargetFile() throws Exception{
    		//servletContext提供getResourceAsStream()方法
    		//返回指定文件对应的输入流
    		return ServletActionContext.getServletContext().getResourceAsStream(inputPath);
    	}
    
    	@Override
    	public String execute() throws Exception {
    		return SUCCESS;
    	}
    }

             上面的Action中包含了一个getTargetFile()方法,该方法返回一个InputStream输入流。这个输入流返回的是下载目标文件的入口。该方法的方法名为getTargetFile,则stream类型的结果映射中inputName参数值是targetFile.

             注:返回InputStream的方法需要配置Stream类型结果时指定inputName参数;该参数值就是方法吗去掉get前缀,首字母小写的字符串。

             2、配置Action

             配置文件下载的Action关键是需要配置一个类型为stream的结果,该stream类型的结果将使用文件下载作为响应。配置时需要指定以下四个属性


             由于Stream结果类型的逻辑试图是返回给客服端一个输入流,因此不需要指定location属性。

             配置如下:

    		<action name="download1" class="com.app.action.FileDownloadAction">
    			<!-- 指定被下载资源的位置 -->
    			<param name="inputPath">\image\美女_01.jpg</param>
    			<!-- 配置结果类型为stream的结果 -->
    			<result name="success" type="stream">
    				<!-- 指定下载文件的文件类型 -->
    				<param name="contentType">image/jpg</param>
    				<!-- 指定由getTargetFile()方法返回被下载文件的inputStream -->
    				<param name="inputName">targetFile</param>
    				<param name="contentDisposition">attachment;filename="meinv1_01.jpg"</param>
    				<!-- 指定下载文件的缓冲大小 -->
    				<param name="bufferSize">4096</param>
    			</result>
    		</action>

             通过上面的配置后,就可以实现包含中文文件名的文件下载了。如果在点击就可以实现下载了。如下:


             二、下载前的授权控制

             有时用户下载文件之前,我们需要对用户的身份进行验证,判断用户是否具有权限来下载该文件。这时我们通过Struts 2 的文件下载支持,就可以实现下载前的授权控制。

             下面的Action,首先通过判断session里面的user属性是否为chenssy,如果用户通过了验证就允许下载,否则直接返回登录界面。

             代码如下:

    public class AuthorityDownAction implements Action {
    
    	private String inputPath;
    
    	public void setInputPath(String inputPath) {
    		this.inputPath = inputPath;
    	}
    
    	public InputStream getTargetFile() throws Exception{
    		//ServletContext提供了getResourceAsStream()方法
    		return ServletActionContext.getServletContext().getResourceAsStream(inputPath);
    	}
    	public String execute() throws Exception {
    		//取得ActionContext实例
    		ActionContext ctx = ActionContext.getContext();
    		//通过ActionContext访问用户的HttpSession
    		Map session = ctx.getSession();
    		String user = (String) session.get("user");
    		//判断session里的user是否通过检查
    		if(user!=null&&user.equals("chenssy")){
    			return SUCCESS;
    		}
    		ctx.put("tip", "您还没有登录,或者登录的用户名不正确,请重新登录!!!");
    		return LOGIN;
    	}
    
    }

             上面的Action在校验失败后,会返回一个login逻辑视图名,所以在配置该Action时,还需要配置一个名为login的结果。

                      <action name="download2" class="com.app.action.AuthorityDownAction">
    			<!-- 定义被下载文件的物理资源 -->
    			<param name="inputPath">\image\meinv_01.rar</param>
    			<result name="success" type="stream">
    				<!-- 指定下载文件的文件类型 -->
    				<param name="contentType">application/rar</param>
    				<!-- 指定由getTargetFile()方法返回被下载文件的InputStream -->
    				<param name="inputName">targetFile</param>
    				<param name="contentDisposition">filename="meinv_01.rar"</param>
    				<!-- 指定下载文件的缓冲大小 -->
    				<param name="bufferSize">4096</param>
    			</result>
    			<result name="login">/login.jsp</result>
    		</action>

             通过上面的配置后,就可以实现用户的授权控制。如果用户不登录、或者用户名不正确,在下载该资源时,就会返回到登录界面。

             如下:


             对于处理登录请求的Action如下:

    public class LoginAction extends ActionSupport {
    
    	private String username;
    	private String password;
    
    	public String getUsername() {
    		return username;
    	}
    
    	public void setUsername(String username) {
    		this.username = username;
    	}
    
    	public String getPassword() {
    		return password;
    	}
    
    	public void setPassword(String password) {
    		this.password = password;
    	}
    
    	@Override
    	public String execute() throws Exception {
    		return SUCCESS;
    	}
    
    }

              对于该Action,它只是一个简单的处理类。它的execute方法没有进行任何处理,直接返回success,表示任何用户名都可以登录成功,进入到下载界面,但是从AuthorityDownAction 处理类中可以看到只有用户名为chengssy的用户可以下载成功。其他任何用户下载该资源都不会成功。

              如果登录成功了,需要返回到下载页面,所以该Action的配置如下:

    <action name="login" class="com.app.action.LoginAction">
    			<result name="success">/download.jsp</result>
    		</action>

              通过上面的一些配置后,用户再输入"chengssy",一旦完成了登录,用户的sessionusername的值就会是:chenssy,这时就可以完成文件的下载了。


    读李刚《轻量级Java EE企业应用实战》

  • 相关阅读:
    洛谷 P2827 蚯蚓(NOIp 提高组2016)
    洛谷 P2822 组合数问题(NOIp 提高组2016)
    洛谷 P2671 求和
    洛谷 P1119 灾后重建
    电子海图开发第二十二篇 web电子海图 历史航迹的展示(共一百篇)
    电子海图开发第二十一篇 web电子海图 监听图标点击事件(共一百篇)
    电子海图开发第二十篇 web电子海图 在电子海图上加载图标(共一百篇)
    物联网时代存储告急 边缘存储如何缓解存储压力?
    国家超算深圳中心计划2年内提升计算能力至少1000倍;图神经网络的生成式预训练论文解读
    轻量型 GPU 应用首选 京东智联云推出 NVIDIA vGPU 实例
  • 原文地址:https://www.cnblogs.com/oversea201405/p/3752345.html
Copyright © 2011-2022 走看看