1. jfinal 如何导出zip压缩文件
官网介绍:JFinal 是基于 java 语言的极速 WEB + ORM 框架,其核心设计目标是开发迅速、代码量少、学习简单、功能强大、轻量级、易扩展、Restful。在拥有Java语言所有优势的同时再拥有ruby、python、php等动态语言的开发效率!为您节约更多时间,去陪恋人、家人和朋友 :)
Jfinal做为后台,进行下载文件服务时,源码中可看到:
Controller中已经提供了,方法:
/**
*Renderwithfile
*/
publicvoidrenderFile(StringfileName){
render=renderManager.getRenderFactory().getFileRender(fileName);
}
/**
*Renderwithfile,
*/
publicvoidrenderFile(StringfileName,StringdownloadFileName){
render=renderManager.getRenderFactory().getFileRender(fileName,downloadFileName);
}
/**
*Renderwithfile
*/
publicvoidrenderFile(Filefile){
render=renderManager.getRenderFactory().getFileRender(file);
}
/**
*Renderwithfile,
file=文件,downloadFileName=下载时客户端显示的文件名称,很贴心
*/
publicvoidrenderFile(Filefile,StringdownloadFileName){
render=renderManager.getRenderFactory().getFileRender(file,downloadFileName);
}
大家可以看到源码中 FileRender 是有处理各个浏览器的兼容问题,所以可以方便的使用
/**
*Copyright(c)2011-2017,JamesZhan詹波([email protected]).
*
*LicensendertheApacheLicense,Version2.0(the"License");
*.
*YoumayobtainaoftheLicenseat
*
*http://www.apache.org/licenses/LICENSE-2.0
*
*,software
*"ASIS"BASIS,
*,eitherexpressorimplied.
*
*limitationsundertheLicense.
*/
packagecom.jfinal.render;
importjava.io.BufferedInputStream;
importjava.io.File;
importjava.io.FileInputStream;
importjava.io.IOException;
importjava.io.InputStream;
importjava.io.OutputStream;
importjava.io.UnsupportedEncodingException;
importjava.net.URLEncoder;
importjavax.servlet.ServletContext;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importcom.jfinal.kit.LogKit;
importcom.jfinal.kit.StrKit;
/**
*FileRender.
*/
{
_CONTENT_TYPE="application/octet-stream";
;
;
protectedFilefile;
=null;
publicFileRender(Filefile){
if(file==null){
("filecannotbenull.");
}
this.file=file;
}
publicFileRender(Filefile,StringdownloadFileName){
this(file);
if(StrKit.isBlank(downloadFileName)){
("downloadFileNamecannotbeblank.");
}
this.downloadFileName=downloadFileName;
}
publicFileRender(StringfileName){
if(StrKit.isBlank(fileName)){
("fileNamecannotbeblank.");
}
StringfullFileName;
fileName=fileName.trim();
if(fileName.startsWith("/")||fileName.startsWith("\")){
if(baseDownloadPath.equals("/")){
fullFileName=fileName;
}else{
fullFileName=baseDownloadPath+fileName;
}
}else{
fullFileName=baseDownloadPath+File.separator+fileName;
}
this.file=newFile(fullFileName);
}
publicFileRender(StringfileName,StringdownloadFileName){
this(fileName);
if(StrKit.isBlank(downloadFileName)){
("downloadFileNamecannotbeblank.");
}
this.downloadFileName=downloadFileName;
}
staticvoidinit(StringbaseDownloadPath,ServletContextservletContext){
FileRender.baseDownloadPath=baseDownloadPath;
FileRender.servletContext=servletContext;
}
publicvoidrender(){
if(file==null||!file.isFile()){
RenderManager.me().getRenderFactory().getErrorRender(404).setContext(request,response).render();
return;
}
//---------
response.setHeader("Accept-Ranges","bytes");
Stringfn=downloadFileName==null?file.getName():downloadFileName;
response.setHeader("Content-disposition","attachment;"+encodeFileName(request,fn));
StringcontentType=servletContext.getMimeType(file.getName());
response.setContentType(contentType!=null?contentType:DEFAULT_CONTENT_TYPE);
//---------
if(StrKit.isBlank(request.getHeader("Range"))){
normalRender();
}else{
rangeRender();
}
}
protectedStringencodeFileName(StringfileName){
try{
//returnnewString(fileName.getBytes("GBK"),"ISO8859-1");
returnnewString(fileName.getBytes(getEncoding()),"ISO8859-1");
}catch(UnsupportedEncodingExceptione){
returnfileName;
}
}
/**
*依据浏览器判断编码规则
*/
publicStringencodeFileName(HttpServletRequestrequest,StringfileName){
StringuserAgent=request.getHeader("User-Agent");
try{
StringencodedFileName=URLEncoder.encode(fileName,"UTF8");
//如果没有UA,则默认使用IE的方式进行编码
if(userAgent==null){
return"filename=""+encodedFileName+""";
}
userAgent=userAgent.toLowerCase();
//IE浏览器,只能采用URLEncoder编码
if(userAgent.indexOf("msie")!=-1){
return"filename=""+encodedFileName+""";
}
//Opera浏览器只能采用filename*
if(userAgent.indexOf("opera")!=-1){
return"filename*=UTF-8''"+encodedFileName;
}
//Safari浏览器,只能采用ISO编码的中文输出,Chrome浏览器,只能采用MimeUtility编码或ISO编码的中文输出
if(userAgent.indexOf("safari")!=-1||userAgent.indexOf("applewebkit")!=-1||userAgent.indexOf("chrome")!=-1){
return"filename=""+newString(fileName.getBytes("UTF-8"),"ISO8859-1")+""";
}
//FireFox浏览器,可以使用MimeUtility或filename*或ISO编码的中文输出
if(userAgent.indexOf("mozilla")!=-1){
return"filename*=UTF-8''"+encodedFileName;
}
return"filename=""+encodedFileName+""";
}catch(UnsupportedEncodingExceptione){
thrownewRuntimeException(e);
}
}
protectedvoidnormalRender(){
response.setHeader("Content-Length",String.valueOf(file.length()));
InputStreaminputStream=null;
OutputStreamoutputStream=null;
try{
inputStream=newBufferedInputStream(newFileInputStream(file));
outputStream=response.getOutputStream();
byte[]buffer=newbyte[1024];
for(intlen=-1;(len=inputStream.read(buffer))!=-1;){
outputStream.write(buffer,0,len);
}
outputStream.flush();
outputStream.close();
}catch(IOExceptione){
Stringn=e.getClass().getSimpleName();
if(n.equals("ClientAbortException")||n.equals("EofException")){
}else{
thrownewRenderException(e);
}
}catch(Exceptione){
thrownewRenderException(e);
}finally{
if(inputStream!=null)
try{inputStream.close();}catch(IOExceptione){LogKit.error(e.getMessage(),e);}
}
}
protectedvoidrangeRender(){
Long[]range={null,null};
processRange(range);
StringcontentLength=String.valueOf(range[1].longValue()-range[0].longValue()+1);
response.setHeader("Content-Length",contentLength);
response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);//status=206
//Content-Range:bytes0-499/10000
StringBuildercontentRange=newStringBuilder("bytes").append(String.valueOf(range[0])).append("-").append(String.valueOf(range[1])).append("/").append(String.valueOf(file.length()));
response.setHeader("Content-Range",contentRange.toString());
InputStreaminputStream=null;
OutputStreamoutputStream=null;
try{
longstart=range[0];
longend=range[1];
inputStream=newBufferedInputStream(newFileInputStream(file));
if(inputStream.skip(start)!=start)
thrownewRuntimeException("Fileskiperror");
outputStream=response.getOutputStream();
byte[]buffer=newbyte[1024];
longposition=start;
for(intlen;position<=end&&(len=inputStream.read(buffer))!=-1;){
if(position+len<=end){
outputStream.write(buffer,0,len);
position+=len;
}
else{
for(inti=0;i<len&&position<=end;i++){
outputStream.write(buffer[i]);
position++;
}
}
}
outputStream.flush();
outputStream.close();
}
catch(IOExceptione){
Stringn=e.getClass().getSimpleName();
if(n.equals("ClientAbortException")||n.equals("EofException")){
}else{
thrownewRenderException(e);
}
}
catch(Exceptione){
thrownewRenderException(e);
}
finally{
if(inputStream!=null)
try{inputStream.close();}catch(IOExceptione){LogKit.error(e.getMessage(),e);}
}
}
/**
*Examplesofbyte-ranges-specifiervalues(assuminganentity-bodyoflength10000):
*Thefirst500bytes(byteoffsets0-499,inclusive):bytes=0-499
*Thesecond500bytes(byteoffsets500-999,inclusive):bytes=500-999
*Thefinal500bytes(byteoffsets9500-9999,inclusive):bytes=-500
*Orbytes=9500-
*/
protectedvoidprocessRange(Long[]range){
StringrangeStr=request.getHeader("Range");
intindex=rangeStr.indexOf(',');
if(index!=-1)
rangeStr=rangeStr.substring(0,index);
rangeStr=rangeStr.replace("bytes=","");
String[]arr=rangeStr.split("-",2);
if(arr.length<2)
thrownewRuntimeException("Rangeerror");
longfileLength=file.length();
for(inti=0;i<range.length;i++){
if(StrKit.notBlank(arr[i])){
range[i]=Long.parseLong(arr[i].trim());
if(range[i]>=fileLength)
range[i]=fileLength-1;
}
}
//Rangeformatlike:9500-
if(range[0]!=null&&range[1]==null){
range[1]=fileLength-1;
}
//Rangeformatlike:-500
elseif(range[0]==null&&range[1]!=null){
range[0]=fileLength-range[1];
range[1]=fileLength-1;
}
//checkfinalrange
if(range[0]==null||range[1]==null||range[0].longValue()>range[1].longValue())
thrownewRuntimeException("Rangeerror");
}
}
2. 如何使用python爬虫jfinal
一、gzip/deflate支持
现在的网页普遍支持gzip压缩,这往往可以解决大量传输时间,以VeryCD的主页为例,未压缩版本247K,压缩了以后45K,为原来的1/5。这就意味着抓取速度会快5倍。
然而python的urllib/urllib2默认都不支持压缩,要返回压缩格式,必须在request的header里面写明’accept-encoding’,然后读取response后更要检查header查看是否有’content-encoding’一项来判断是否需要解码,很繁琐琐碎。如何让urllib2自动支持gzip, defalte呢?
其实可以继承BaseHanlder类,然后build_opener的方式来处理:
import urllib2from gzip import GzipFilefrom StringIO import StringIOclass ContentEncodingProcessor(urllib2.BaseHandler): """A handler to add gzip capabilities to urllib2 requests """ # add headers to requests def http_request(self, req): req.add_header("Accept-Encoding", "gzip, deflate") return req # decode def http_response(self, req, resp): old_resp = resp # gzip if resp.headers.get("content-encoding") == "gzip": gz = GzipFile( fileobj=StringIO(resp.read()), mode="r" ) resp = urllib2.addinfourl(gz, old_resp.headers, old_resp.url, old_resp.code) resp.msg = old_resp.msg # deflate if resp.headers.get("content-encoding") == "deflate": gz = StringIO( deflate(resp.read()) ) resp = urllib2.addinfourl(gz, old_resp.headers, old_resp.url, old_resp.code) # 'class to add info() and resp.msg = old_resp.msg return resp # deflate supportimport zlibdef deflate(data): # zlib only provides the zlib compress format, not the deflate format; try: # so on top of all there's this workaround: return zlib.decompress(data, -zlib.MAX_WBITS) except zlib.error: return zlib.decompress(data)
然后就简单了,
encoding_support = = urllib2.build_opener( encoding_support, urllib2.HTTPHandler ) #直接用opener打开网页,如果服务器支持gzip/defalte则自动解压缩content = opener.open(url).read()
二、更方便地多线程
总结一文的确提及了一个简单的多线程模板,但是那个东东真正应用到程序里面去只会让程序变得支离破碎,不堪入目。在怎么更方便地进行多线程方面我也动了一番脑筋。先想想怎么进行多线程调用最方便呢?
1、用twisted进行异步I/O抓取
事实上更高效的抓取并非一定要用多线程,也可以使用异步I/O法:直接用twisted的getPage方法,然后分别加上异步I/O结束时的callback和errback方法即可。例如可以这么干:
from twisted.web.client import getPagefrom twisted.internet import reactor links = [ ''%i for i in range(5420,5430) ] def parse_page(data,url): print len(data),url def fetch_error(error,url): print error.getErrorMessage(),url # 批量抓取链接for url in links: getPage(url,timeout=5) \ .addCallback(parse_page,url) \ #成功则调用parse_page方法 .addErrback(fetch_error,url) #失败则调用fetch_error方法 reactor.callLater(5, reactor.stop) #5秒钟后通知reactor结束程序reactor.run()
twisted人如其名,写的代码实在是太扭曲了,非正常人所能接受,虽然这个简单的例子看上去还好;每次写twisted的程序整个人都扭曲了,累得不得了,文档等于没有,必须得看源码才知道怎么整,唉不提了。
如果要支持gzip/deflate,甚至做一些登陆的扩展,就得为twisted写个新的HTTPClientFactory类诸如此类,我这眉头真是大皱,遂放弃。有毅力者请自行尝试。
这篇讲怎么用twisted来进行批量网址处理的文章不错,由浅入深,深入浅出,可以一看。
2、设计一个简单的多线程抓取类
还是觉得在urllib之类python“本土”的东东里面折腾起来更舒服。试想一下,如果有个Fetcher类,你可以这么调用
f = Fetcher(threads=10) #设定下载线程数为10for url in urls: f.push(url) #把所有url推入下载队列while f.taskleft(): #若还有未完成下载的线程 content = f.pop() #从下载完成队列中取出结果 do_with(content) # 处理content内容
这么个多线程调用简单明了,那么就这么设计吧,首先要有两个队列,用Queue搞定,多线程的基本架构也和“技巧总结”一文类似,push方法和pop方法都比较好处理,都是直接用Queue的方法,taskleft则是如果有“正在运行的任务”或者”队列中的任务”则为是,也好办,于是代码如下:
import urllib2from threading import Thread,Lockfrom Queue import Queueimport time class Fetcher: def __init__(self,threads): self.opener = urllib2.build_opener(urllib2.HTTPHandler) self.lock = Lock() #线程锁 self.q_req = Queue() #任务队列 self.q_ans = Queue() #完成队列 self.threads = threads for i in range(threads): t = Thread(target=self.threadget) t.setDaemon(True) t.start() self.running = 0 def __del__(self): #解构时需等待两个队列完成 time.sleep(0.5) self.q_req.join() self.q_ans.join() def taskleft(self): return self.q_req.qsize()+self.q_ans.qsize()+self.running def push(self,req): self.q_req.put(req) def pop(self): return self.q_ans.get() def threadget(self): while True: req = self.q_req.get() with self.lock: #要保证该操作的原子性,进入critical area self.running += 1 try: ans = self.opener.open(req).read() except Exception, what: ans = '' print what self.q_ans.put((req,ans)) with self.lock: self.running -= 1 self.q_req.task_done() time.sleep(0.1) # don't spam if __name__ == "__main__": links = [ ''%i for i in range(5420,5430) ] f = Fetcher(threads=10) for url in links: f.push(url) while f.taskleft(): url,content = f.pop() print url,len(content)
3. 求shop++的源代码
主要库
spring-aop-4.0.9.RELEASE
spring-beans-4.0.9.RELEASE
spring-context-4.0.9.RELEASE
spring-context-support-4.0.9.RELEASE
spring-core-4.0.9.RELEASE
spring-expression-4.0.9.RELEASE
spring-jdbc-4.0.9.RELEASE
spring-orm-4.0.9.RELEASE
spring-test-4.0.9.RELEASE
spring-tx-4.0.9.RELEASE
spring-web-4.0.9.RELEASE
spring-webmvc-4.0.9.RELEASE
hibernate-core-4.3.9.Final
hibernate-jpa-2.1-api-1.0.0.Final
hibernate-entitymanager-4.3.9.Final
hibernate-validator-5.1.3.Final
hibernate-search-orm-4.5.3.Final
lucene-core-3.6.2
freemarker-2.3.22
ehcache-core-2.6.10
ehcache-web-2.0.4
shiro-core-1.2.3
shiro-web-1.2.3
c3p0-0.9.2.1
commons-lang-2.6
commons-beanutils-1.9.2
commons-collections-3.2.1
commons-io-2.4
commons-net-3.3
commons-fileupload-1.3.1
commons-codec-1.10
commons-email-1.3.3
commons-compress-1.9
junit-4.10
httpclient-4.3.5
httpcore-4.3.2
slf4j-api-1.7.7
jcl-over-slf4j-1.7.7
logback-core-1.1.2
logback-classic-1.1.2
dom4j-1.6.1
jackson-core-2.4.3
jackson-databind-2.4.3
jackson-annotations-2.4.3
IKAnalyzer2012_u6
4. jfinal2.3的定时任务如何实现
Cron4jPlugin是JFinal集成的任务调度插件,通过使用Cron4jPlugin可以使用通用的cron表达式极为便利的实现任务调度功能。
jfinal2.3我不记得有Cron4jPlugin没有.
如果没有 你可以把新版的jfinal更新上来,或者把Cron4jPlugin的源码拷贝出来放到你的项目中去,可以单独适用的.
或者直接使用Cron4j就可以,参考:网页链接
5. jfinalshop2.0支持手机浏览吗
使用RedisPlugin 除了需要依赖commons-pool2、jedis这两个包之外还需要依赖fst 在此附上对应的maven
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.7.2</version>
</dependency>
<dependency>
<groupId>de.ruedigermoeller</groupId>
<artifactId>fst</artifactId>
<version>2.31</version>
</dependency>
6. jfinal什么时候出web版的后台管理
可以加入Jfinal俱乐部,
引用官网的:
俱乐部当前发放的福利是本社区 jfinal.com 的源代码,并取名为
jfinal-club。jfinal-club 在核心功能上相当于一个迷你的 OSChina 社区,newsfeed
信息流模块整合了整站动态数据,交互性极好。重要功能:动态消息、@提到我、remind提醒、关注、好友、粉丝、私信、发贴、回贴、点赞、收藏、定时任务等功能。常见的功能也很全面:文件下载、图片上传、用户头像裁剪、登录、注册、邮件激活、找回密码、XSS过滤、缓存、后台管理、以及一些常用工具类等等。
jfinal-club 是官方出品的唯一 JFinal 最佳实践,绝无仅有的极简设计,获得 jfinal-club 也就获得了作者本人对
JFinal 的使用精髓。基于 jfinal 3.3 开发,获得 jfinal-club 将以令人难以想象的速度掌握新版本功能。
jfinal-club 是一个长期进化的,不断添加实用功能的项目,加入俱乐部以后,将随之长期享受该福利。
---------------
web版的后台管理社区做的比较好的有:
JfinalUIB , EOVA ,JPress, ... 等很多都非常的好
http://www.jfinal.com/project 相关项目http://www.jfinal.com/club 俱乐部
7. JFinal 集成kisso怎么使用里面的shiro
这个你需要看kisso的代码了。
推荐一套完整的Shiro Demo,免费的。
推荐一套完整的ShiroDemo,免费的。
ShiroDemo:http://www.sojson.com/shiro
Demo已经部署到线上,地址是http://shiro.itboy.net
管理员帐号:admin,密码:sojson.com如果密码错误,请用sojson。PS:你可以注册自己的帐号,然后用管理员赋权限给你自己的帐号,但是,每20分钟会把数据初始化一次。建议自己下载源码,让Demo跑起来,然后跑的更快。
管理员帐号:admin,密码:sojson.com 如果密码错误,请用sojson。PS:你可以注册自己的帐号,然后用管理员赋权限给你自己的帐号,但是,每20分钟会把数据初始化一次。建议自己下载源码,让Demo跑起来,然后跑的更快。
8. jfinal上传大文件 如何断点续传
点量Http、FTP多线程断点续传下载组件(下载DLL)内核源码使用高效的c++代码编写,提供标准的动态链接库(DLL),可供C/C++、Delphi、C#、Java、VB、PowerBuilder、易语言等语言和各常用开发环境调用。
9. jfinal不兼容的浏览器有哪些
官网介绍:
JFinal 是基于 Java 语言的极速 WEB + ORM
框架,其核心设计目标是开发迅速、代码量少、学习简单、功能强大、轻量级、易扩展、Restful。在拥有Java语言所有优势的同时再拥有ruby、python、php等动态语言的开发效率!为您节约更多时间,去陪恋人、家人和朋友
:)
Jfinal是JAVA框架, 不在浏览器上执行的, 是两个方向。
如果你说的是Jfinal做为后台,进行下载文件服务时,是否有浏览器兼容问题,在Jfinal3.0之后的版已经全面兼容了
3.3版的源码中可看到已经有处理:
/**
*Copyright(c)2011-2017,JamesZhan詹波([email protected]).
*
*LicensendertheApacheLicense,Version2.0(the"License");
*.
*YoumayobtainaoftheLicenseat
*
*http://www.apache.org/licenses/LICENSE-2.0
*
*,software
*"ASIS"BASIS,
*,eitherexpressorimplied.
*
*limitationsundertheLicense.
*/
packagecom.jfinal.render;
importjava.io.BufferedInputStream;
importjava.io.File;
importjava.io.FileInputStream;
importjava.io.IOException;
importjava.io.InputStream;
importjava.io.OutputStream;
importjava.io.UnsupportedEncodingException;
importjava.net.URLEncoder;
importjavax.servlet.ServletContext;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importcom.jfinal.kit.LogKit;
importcom.jfinal.kit.StrKit;
/**
*FileRender.
*/
{
_CONTENT_TYPE="application/octet-stream";
;
;
protectedFilefile;
=null;
publicFileRender(Filefile){
if(file==null){
("filecannotbenull.");
}
this.file=file;
}
publicFileRender(Filefile,StringdownloadFileName){
this(file);
if(StrKit.isBlank(downloadFileName)){
("downloadFileNamecannotbeblank.");
}
this.downloadFileName=downloadFileName;
}
publicFileRender(StringfileName){
if(StrKit.isBlank(fileName)){
("fileNamecannotbeblank.");
}
StringfullFileName;
fileName=fileName.trim();
if(fileName.startsWith("/")||fileName.startsWith("\")){
if(baseDownloadPath.equals("/")){
fullFileName=fileName;
}else{
fullFileName=baseDownloadPath+fileName;
}
}else{
fullFileName=baseDownloadPath+File.separator+fileName;
}
this.file=newFile(fullFileName);
}
publicFileRender(StringfileName,StringdownloadFileName){
this(fileName);
if(StrKit.isBlank(downloadFileName)){
("downloadFileNamecannotbeblank.");
}
this.downloadFileName=downloadFileName;
}
staticvoidinit(StringbaseDownloadPath,ServletContextservletContext){
FileRender.baseDownloadPath=baseDownloadPath;
FileRender.servletContext=servletContext;
}
publicvoidrender(){
if(file==null||!file.isFile()){
RenderManager.me().getRenderFactory().getErrorRender(404).setContext(request,response).render();
return;
}
//---------
response.setHeader("Accept-Ranges","bytes");
Stringfn=downloadFileName==null?file.getName():downloadFileName;
response.setHeader("Content-disposition","attachment;"+encodeFileName(request,fn));
StringcontentType=servletContext.getMimeType(file.getName());
response.setContentType(contentType!=null?contentType:DEFAULT_CONTENT_TYPE);
//---------
if(StrKit.isBlank(request.getHeader("Range"))){
normalRender();
}else{
rangeRender();
}
}
protectedStringencodeFileName(StringfileName){
try{
//returnnewString(fileName.getBytes("GBK"),"ISO8859-1");
returnnewString(fileName.getBytes(getEncoding()),"ISO8859-1");
}catch(UnsupportedEncodingExceptione){
returnfileName;
}
}
/**
*依据浏览器判断编码规则
*/
publicStringencodeFileName(HttpServletRequestrequest,StringfileName){
StringuserAgent=request.getHeader("User-Agent");
try{
StringencodedFileName=URLEncoder.encode(fileName,"UTF8");
//如果没有UA,则默认使用IE的方式进行编码
if(userAgent==null){
return"filename=""+encodedFileName+""";
}
userAgent=userAgent.toLowerCase();
//IE浏览器,只能采用URLEncoder编码
if(userAgent.indexOf("msie")!=-1){
return"filename=""+encodedFileName+""";
}
//Opera浏览器只能采用filename*
if(userAgent.indexOf("opera")!=-1){
return"filename*=UTF-8''"+encodedFileName;
}
//Safari浏览器,只能采用ISO编码的中文输出,Chrome浏览器,只能采用MimeUtility编码或ISO编码的中文输出
if(userAgent.indexOf("safari")!=-1||userAgent.indexOf("applewebkit")!=-1||userAgent.indexOf("chrome")!=-1){
return"filename=""+newString(fileName.getBytes("UTF-8"),"ISO8859-1")+""";
}
//FireFox浏览器,可以使用MimeUtility或filename*或ISO编码的中文输出
if(userAgent.indexOf("mozilla")!=-1){
return"filename*=UTF-8''"+encodedFileName;
}
return"filename=""+encodedFileName+""";
}catch(UnsupportedEncodingExceptione){
thrownewRuntimeException(e);
}
}
protectedvoidnormalRender(){
response.setHeader("Content-Length",String.valueOf(file.length()));
InputStreaminputStream=null;
OutputStreamoutputStream=null;
try{
inputStream=newBufferedInputStream(newFileInputStream(file));
outputStream=response.getOutputStream();
byte[]buffer=newbyte[1024];
for(intlen=-1;(len=inputStream.read(buffer))!=-1;){
outputStream.write(buffer,0,len);
}
outputStream.flush();
outputStream.close();
}catch(IOExceptione){
Stringn=e.getClass().getSimpleName();
if(n.equals("ClientAbortException")||n.equals("EofException")){
}else{
thrownewRenderException(e);
}
}catch(Exceptione){
thrownewRenderException(e);
}finally{
if(inputStream!=null)
try{inputStream.close();}catch(IOExceptione){LogKit.error(e.getMessage(),e);}
}
}
protectedvoidrangeRender(){
Long[]range={null,null};
processRange(range);
StringcontentLength=String.valueOf(range[1].longValue()-range[0].longValue()+1);
response.setHeader("Content-Length",contentLength);
response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);//status=206
//Content-Range:bytes0-499/10000
StringBuildercontentRange=newStringBuilder("bytes").append(String.valueOf(range[0])).append("-").append(String.valueOf(range[1])).append("/").append(String.valueOf(file.length()));
response.setHeader("Content-Range",contentRange.toString());
InputStreaminputStream=null;
OutputStreamoutputStream=null;
try{
longstart=range[0];
longend=range[1];
inputStream=newBufferedInputStream(newFileInputStream(file));
if(inputStream.skip(start)!=start)
thrownewRuntimeException("Fileskiperror");
outputStream=response.getOutputStream();
byte[]buffer=newbyte[1024];
longposition=start;
for(intlen;position<=end&&(len=inputStream.read(buffer))!=-1;){
if(position+len<=end){
outputStream.write(buffer,0,len);
position+=len;
}
else{
for(inti=0;i<len&&position<=end;i++){
outputStream.write(buffer[i]);
position++;
}
}
}
outputStream.flush();
outputStream.close();
}
catch(IOExceptione){
Stringn=e.getClass().getSimpleName();
if(n.equals("ClientAbortException")||n.equals("EofException")){
}else{
thrownewRenderException(e);
}
}
catch(Exceptione){
thrownewRenderException(e);
}
finally{
if(inputStream!=null)
try{inputStream.close();}catch(IOExceptione){LogKit.error(e.getMessage(),e);}
}
}
/**
*Examplesofbyte-ranges-specifiervalues(assuminganentity-bodyoflength10000):
*Thefirst500bytes(byteoffsets0-499,inclusive):bytes=0-499
*Thesecond500bytes(byteoffsets500-999,inclusive):bytes=500-999
*Thefinal500bytes(byteoffsets9500-9999,inclusive):bytes=-500
*Orbytes=9500-
*/
protectedvoidprocessRange(Long[]range){
StringrangeStr=request.getHeader("Range");
intindex=rangeStr.indexOf(',');
if(index!=-1)
rangeStr=rangeStr.substring(0,index);
rangeStr=rangeStr.replace("bytes=","");
String[]arr=rangeStr.split("-",2);
if(arr.length<2)
thrownewRuntimeException("Rangeerror");
longfileLength=file.length();
for(inti=0;i<range.length;i++){
if(StrKit.notBlank(arr[i])){
range[i]=Long.parseLong(arr[i].trim());
if(range[i]>=fileLength)
range[i]=fileLength-1;
}
}
//Rangeformatlike:9500-
if(range[0]!=null&&range[1]==null){
range[1]=fileLength-1;
}
//Rangeformatlike:-500
elseif(range[0]==null&&range[1]!=null){
range[0]=fileLength-range[1];
range[1]=fileLength-1;
}
//checkfinalrange
if(range[0]==null||range[1]==null||range[0].longValue()>range[1].longValue())
thrownewRuntimeException("Rangeerror");
}
}
10. jfinal+easyui项目源码
JFinal是一个基于Java的极速Web开发框架,其核心设计目标是开发迅速、代码量少、学习简单、功能强大、轻量级、易扩展、Restful。
地址:http://www.csdn.net/tag/jfinal