因为项目需要,舍弃了struts2方便的文件下载方式,采用了applet,主要为了下载的时候手动点出一个文件下载的选择框,在进行文件的下载保存。
下面开始介绍实现的过程:
1.applet代码
import java.applet.Applet; import java.awt.Color; import java.io.File; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import javax.xml.ws.Response; public class getFile extends Applet { String info; /** * 请求的服务器action方法:比如我请求的就是http://localhost:8080/restools/tsh/CobolAction! * download.do */ String serverpath; /** * 指定的客户端文件的下载路径 */ String localpath; /** * 服务器端的文件所在路径 */ String filePath; /* * (non-Javadoc) 初始化applet * * @see java.applet.Applet#init() */ public void init() { URL url; URLConnection con; serverpath = getParameter("serverpath"); localpath = getParameter("localpath"); filePath = getParameter("filePath"); try { // 打开连接,注意filePath参数的使用 url = new URL(/blog_article/serverpath "/filePath/quot; filePath.html); con = url.openConnection(); // 开始连接url的时候,会去调用服务器的download方法,将服务端被下载的文件以流的方式写入到网络中,可以参考我自己的serverpath con.connect();
//客户端将按照本地的路径,将网络中的流内容写入到文件中 File file = new File(localpath); if (!file.exists()) { file.createNewFile(); } getInfo(con, file); } catch (MalformedURLException mfe) { System.out.println("URL form error!"); } catch (IOException ioe) { System.out.println("IO Exception!"); } } public void getInfo(URLConnection urlc, File file) { String txt = new String(); InputStream is; FileOutputStream fWriter = null; int size=0;
public void getInfo(URLConnection urlc, File file) {
String txt = new String(); InputStream is; FileOutputStream fWriter = null; int size=0; try { is = urlc.getInputStream(); byte[] b = new byte[1024]; fWriter = new FileOutputStream(file); while ((size=is.read(b)) != -1) { if(size==1024){ fWriter.write(b); } else{ byte[] last = new byte[size]; System.arraycopy(b, 0, last, 0, size); fWriter.write(last); } } is.close(); } catch (IOException ioe) { System.out.println("IO Exception!"); txt = new String("File read failed!"); try { fWriter.write(txt.getBytes()); } catch (IOException e) { } } finally { try { fWriter.flush(); fWriter.close(); } catch (IOException e) { } } } }
服务器端代码。download代码public String download() { try {//获得页面上传过来的服务器端文件路径,将文件写入到网络中,这时applet将从中取到流中的内容,从而将内容写入到本地文件中 filepath = request.getParameter("filePath"); File file = new File(filepath); InputStream fiStream = new FileInputStream(file); byte[] b = new byte[1024]; OutputStream ops = response.getOutputStream(); int size ; while ((size = fiStream.read(b)) != -1) { if(size == 1024){ ops.write(b); }else{ byte[] last = new byte[size]; System.arraycopy(b, 0, last, 0, size); ops.write(last); } } fiStream.close(); } catch (FileNotFoundException e) { log.error(e.toString(), e); } catch (IOException e) { log.error(e.toString(), e); } return NONE; }jsp页面:注意需要将getfile这个applet文件,打成jar包,并签名,放在工程的webapp目录下,和web-inf同级。这里的参数codeBasePath依旧是服务器的路径。serverPath是客户端请求的action中的方法,localPath是客户端下载文件的路径,filePath是服务器端需要下载的文件名
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> </head> <body> <applet code="getFile" codebase="${codeBasePath}" ARCHIVE = "getfile.jar" width="0" height="0"> <param name="serverpath" id="serverpath" value="${serverPath}"/> <param name="localpath" id="localpath" value="${localPath}"/> <param name="filePath" id="filePath" value="${filepath}"/> </applet> </body> </html>总结下:也就是当你去请求action中的download方法的时候,action会将以上的参数传递给getfile这个applet,applet执行的过程中,又去调用action中的一个方法,将文件以流的形式传递给网络,applet继续执行,将流中的数据写入到客户端的文件当中。至此,用applet下载文件就算完成了!希望对大家有所帮助!
提供参数的获得方法:
String codeBasePath = request.getScheme() + "://"
+ request.getServerName() + ":"
+ request.getServerPort()
+ request.getContextPath();
这个方法将会取得工程的路径,比如:http://localhost:8080/restools
作者:yehui18sui 发表于2013-4-24 9:34:32 原文链接阅读:5 评论:0 查看评论
1、可以获得请求参数后重新编码
//获得请求参数 String name=request.getParameter("name"); byte[] bytes=name.getBytes("ISO-8859-1");//将请求忏悔书用ISO-8859-1分解成字节数组 name=new String(bytes,"utf-8");//将字节数组重新解码成字符串
2、使用URLDecoder解码字符串
String name=request.getQueryString();//获取请求参数 name1=URLDecoder.decode(name,"utf-8");//重新解码
什么情况下,要禁止静态文件缓存:
1、经常可能要改动的 js, css.
比如 一个html 文件, test.html 在 1.0版本中。可能是这样
<script src=/blog_article/"common.js"></script>_br/index.html>
修改后 v1.1版本:
<script src=/blog_article/"common.js"></script>_br/index.html>
<script src=/blog_article/"foo.js"></script>_br/index.html>
新增加了一个foo.js 同时,也改动了common.js , 在common.js 中定义了新的类,并在foo.js 中使用了common.js.
在这种情况下如果以前用户浏览过 1.0版本的 html 文件,那么他的浏览器自动缓存了 common.js
当他浏览新版本的时候,因为使用的是 v1.1的 foo.js 和 v1.0的 common.js ,这样将导致脚本出错。
解决方法探讨:
因为css,js 是通过 <script src=/blog_article/....> 这种方式加载的,所以,很难使用 asp 的那种服务器端禁止缓存的办法。也很难使用ajax的通过设置 http请求头的办法禁止使用缓存。
看来随机数是个好办法。
document.write( " <script src='/blog_article/test.js'></s " + " cript> " )
// 方法二:
var js = document.createElement( " script " )
js.src = " test.js " + Math.random()
document.body.appendChild(js)
但是,如果采用随机数的话, js文件将永远得不到缓存,每次都必须重新从服务器加载,即使没有任何更改。
大家如果经常上国外网站的话,可以看到他们通常采用这样的方式来解决:
<script src=/blog_article/"test.js>
其中 ver=113 的 113就是版本号,一般都是采用 CVS 或其他工具生成的开发版本号。
这样真正做到了应该缓存的时候缓存静态文件,当版本有更新的时候从获取最新的版本,并更新缓存。
对于图像 <img src=/blog_article/"test/ver/在CVS的版本号/quot;/gt;.jps 来有效利用和更新缓存.
CSS更新的问题,如果网站CSS修改了,但客户浏览器设置不更新缓存,那看到的网页可能会乱掉。因为CSS缓存没有更新。(解决,可以在css文件后加一个参数,参数改变后,浏览器会重新下载新的文件。如:<link rel="stylesheet" type="text/css" href=/blog_article/"templates/css/stylesheet.css>