中文文件的下载的下载还是小事,毕竟在服务器上面放置的文件一般都以用户ID与时间戳命名为好。不然一些浏览器无法解释中文,就无法提供一个正常的中文链接给用户下载。但是利用Struts2实现下载权限的控制真的是一个很实用的功能。
一、基本目标
设置一个很简单的问题,用户输入错误答案则不能下载,必须输入正确答案才能下载,如下图,而且被下载的文件在服务器的File文件下面,名称叫做“中文没有问题”的一张图片。浏览器遇到纯图片地址是不会调用下载工具的,而是直接显示。
二、基本准备
1、在Eclipse for Javaee新建一个Web工程名叫StrutsDownload,在WEB-INF的lib中放入Struts2的核心包,写好web.xml,具体在《【Struts2】Struts2纯手工安装、配置以及Helloworld,以最新版struts 2.3.20 GA做例子》(点击打开链接)说过,不赘述。之后再WebContent网站工程文件夹中,新建一个文件夹叫File,里面放一张图片“中文没有问题.jpg”。搞好之后网站目录结构如下。
2、首先写错误提示页error.jsp,这一页没有什么内容。就是一个错误提示与返回超级链接,具体如下:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>回答错误,禁止下载</title>
</head>
<body>
回答错误,禁止下载<br />
<a href="download.jsp">返回</a>
</body>
</html>
3、输入答案下载页download.jsp,这一页有一个只有一个输入框与提交按钮的表单,处理的Action是Download,也没有什么好讲的。
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>文件下载权限管理</title>
</head>
<body>
请问1+1=?
<form action="download" method="post">
<input type="text" name="password" /><br />
<input type="submit" value="提交" />
</form>
</body>
</html>
4、struts.xml
对于这个文件,必须注意的是,这次的如果download.java处理的结果是返回success的话,其返回给用户,也就是View层的链接是一个二进制流result,正如上次在《【Struts2】利用JQuery实现Struts2的Ajax功能》(点击打开链接)讲Ajax返回处理字符串一样的,设置返回结果的类型是流的话,在下面必须指明一个inputName的参数,说明这流到底是download.java中提供的哪一个流,虽然基本上download.java只会提供一个文件流、字符流等二进制流而已。流的概念就是Java中流的概念,具体在《【Java】输入与输出与JDK1.5之后的新型字符串StringBuilder》(点击打开链接)说过了。而返回error的话,才是返回一个超级链接。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="test" extends="struts-default">
<action name="download" class="test.download" method="run">
<result name="success" type="stream">
<param name="inputName">result</param>
</result>
<result name="error">error.jsp</result>
</action>
</package>
</struts>
5、下载权限管理文件download.java
这文件的任务主要有一个两个,一个是对前台传递过来的password字符串进行判断,看答案是否正确,你完全可以改成怒取Session,看用户是否有登录之类,一个是利用封装好的方法组织一个输入流给struts.xml。
package test;
import java.io.*;//这是搞文件必须有的
import org.apache.struts2.ServletActionContext;//这个包中包含组织文件流的方法
import com.opensymphony.xwork2.*;//这是搞struts必须有的
@SuppressWarnings("serial")
public class download extends ActionSupport {
private String password;
// 这个输入流是用来存放下载文件的。
private InputStream result;
public String run() throws Exception {
//这样能够组织一个文件流
String filePath="\\Files\\中文没有问题.jpg";
result= ServletActionContext.getServletContext().getResourceAsStream(filePath);
//trim是用来清楚空格、回车那些视觉上是空白的鬼东西。
//看用户回答是否符合要求,也就是判断用户回答1+1=是否是2
if(password.trim().equals("2")){
//备注,利用(String)ActionContext.getContext().getSession().get("username");
//能取到当前用户存在Session的用户名哦!
return SUCCESS;
}
else{
//不符合要求,返回一个跳转到error.jsp的地址给用户,不返回文件流
return "error";
}
}
// eclipse自动生成
// 虽然password只进不出,其getter可以不要,但是还是排着吧,前台不调用就没问题
// 输入流Result只出不进,其setter也是可以不要的,但是系统一次性生成getter与setter
// 为何要手贱删除呢
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public InputStream getResult() {
return result;
}
public void setResult(InputStream result) {
this.result = result;
}
}