欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java Web實(shí)現(xiàn)文件下載和亂碼處理方法

 更新時(shí)間:2016年10月19日 15:22:08   投稿:mrr  
文件上傳和下載是web開發(fā)中常遇到的問題。今天小編給大家分享下Java Web實(shí)現(xiàn)文件下載和亂碼處理方法的相關(guān)資料,需要的朋友可以參考下

文件上傳和下載是web開發(fā)中常遇到的問題,這幾天在做一個(gè)項(xiàng)目又用到了文件下載,之前也零零散散記了些筆記,今天來做一下整理。文件上傳還有待進(jìn)一步測(cè)試,這里先說一下文件下載。

一、文件下載處理流程

文件下載處理流程其實(shí)很清晰,即:

1、根據(jù)文件名或者文件路徑定位文件,具體的策略主要根據(jù)自己的需求,總之需要系統(tǒng)能找到的文件全路徑。

2、獲取輸入流,從目標(biāo)文件獲取輸入流。

3、獲取輸出流,從response中獲取輸出流。

4、從輸入流讀入文件,通過輸出流輸出文件。這是真正的下載執(zhí)行過程。

5、關(guān)閉IO流。

主要流程就是這個(gè),另外就是一些必要的屬性設(shè)置,比如比較重要的有設(shè)置文件的contentType類型等。

二、不啰嗦了了,上代碼

我是用Springmvc做的,但其實(shí)用其他的也一樣,主要需要HttpServletResponse對(duì)象和有效的目標(biāo)文件。

1、前臺(tái)代碼

/*
* 下載上傳的文件
*/
function downloadFromUpload(fileName){
window.location.href = path + "/download?dir=upload&fileName="+encodeURI(encodeURI(fileName));
}
/*
* 普通下載
*/
function download(fileName){
window.location.href = path + "/download?dir=download&fileName="+encodeURI(encodeURI(fileName));
}

2、controller代碼

/**
* 文件下載(從上傳路徑下載)
* 
* @param request
* @param response
* @throws IOException
*/
@ResponseBody
@RequestMapping(value = "/download")
public void downloadFile(HttpServletRequest request,
HttpServletResponse response, FileModel model) throws Exception {
String fileName = URLDecoder.decode(model.getFileName(), "UTF-8");
/*
* 限制只有upload和download文件夾里的文件可以下載
*/
String folderName = "download";
if (!StringUtils.isEmpty(model.getDir())
&& model.getDir().equals("upload")) {
folderName = "upload";
} else {
folderName = "download";
}
String fileAbsolutePath = request.getSession().getServletContext()
.getRealPath("/")
+ "/WEB-INF/" + folderName + "/" + fileName;
FileTools.downloadFile(request, response, fileAbsolutePath);
log.warn("用戶Id:"
+ (Integer) (request.getSession().getAttribute("userId"))
+ ",用戶名:"
+ (String) (request.getSession().getAttribute("username"))
+ ",下載了文件:" + fileAbsolutePath);
}

這里的下載邏輯是,前臺(tái)只需要請(qǐng)求/download,并給出文件名參數(shù)即可。為了避免中文亂碼,前臺(tái)的文件名在作為參數(shù)時(shí),使用了js的encodeURI()將其變?yōu)閁nicode碼,然后后臺(tái)解碼轉(zhuǎn)換為中文。另外由于項(xiàng)目的特殊性,我這里要下載的文件可能會(huì)在upload和download兩個(gè)文件夾中,所以這里多了一部分判斷邏輯。另外,我這里將文件名和請(qǐng)求的文件夾名稱都封裝在了FileModel中。

3、下載邏輯實(shí)現(xiàn)。

這里沒有用service了,直接用的靜態(tài)方法實(shí)現(xiàn)。

/**
* 下載文件時(shí)指定下載名
* 
* @param request
* HttpServletRequest
* @param response
* HttpServletResponse
* @param filePath
* 文件全路徑
* @param fileName
* 指定客戶端下載時(shí)顯示的文件名
* @throws IOException
*/
public static void downloadFile(HttpServletRequest request,
HttpServletResponse response, String filePath, String fileName)
throws IOException {
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
bis = new BufferedInputStream(new FileInputStream(filePath));
bos = new BufferedOutputStream(response.getOutputStream());
long fileLength = new File(filePath).length();
response.setCharacterEncoding("UTF-8");
response.setContentType("multipart/form-data");
/*
* 解決各瀏覽器的中文亂碼問題
*/
String userAgent = request.getHeader("User-Agent");
byte[] bytes = userAgent.contains("MSIE") ? fileName.getBytes()
: fileName.getBytes("UTF-8"); // fileName.getBytes("UTF-8")處理safari的亂碼問題
fileName = new String(bytes, "ISO-8859-1"); // 各瀏覽器基本都支持ISO編碼
response.setHeader("Content-disposition",
String.format("attachment; filename=\"%s\"", fileName));
response.setHeader("Content-Length", String.valueOf(fileLength));
byte[] buff = new byte[2048];
int bytesRead;
while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
bos.write(buff, 0, bytesRead);
}
bis.close();
bos.close();
}
/**
* 下載文件時(shí)不指定下載文件名稱
* 
* @param request
* HttpServletRequest
* @param response
* HttpServletResponse
* @param filePath
* 文件全路徑
* @throws IOException
*/
public static void downloadFile(HttpServletRequest request,
HttpServletResponse response, String filePath) throws IOException {
File file = new File(filePath);
downloadFile(request, response, filePath, file.getName());
}

這里提供了重載的下載方法,解決有時(shí)需要指定客戶端下載的文件名的需求。

三、注意事項(xiàng)

1、關(guān)于MIME類型的選擇

之前對(duì)MIME類型不是很了解,發(fā)現(xiàn)網(wǎng)上有很多下載的源碼的MIME類型設(shè)置的不一樣。即這句

response.setContentType("multipart/form-data");

查了下這里設(shè)置MIME類型的一個(gè)作用是告訴客戶端瀏覽器以什么格式處理要下載的文件。具體的對(duì)應(yīng)網(wǎng)上有很多講解,這I類設(shè)置成這種格式,一般會(huì)自動(dòng)匹配格式。

2、指定客戶端下載文件名

有時(shí)我們可能需要指定客戶端下載文件時(shí)的文件名,即這句代碼

response.setHeader("Content-disposition", String.format("attachment; filename=\"%s\"", fileName));
中的fileName,可以自定義。前面的部分一般不要?jiǎng)印?/p>

3、中文亂碼問題的解決

中文文件亂碼太常見了,在項(xiàng)目系統(tǒng)架構(gòu)剛搭建時(shí),就應(yīng)該統(tǒng)一所有的中文編碼,包括編輯器中、頁面中以及數(shù)據(jù)庫中,推薦UTF-8編碼。如果用的Spring,還可以配置Spring的字符集過濾器,進(jìn)一步避免中文亂碼。

(1)客戶端下載請(qǐng)求過程文件名亂碼

有時(shí)我們會(huì)遇到,前臺(tái)頁面顯示中文文件名下載列表時(shí)正常的,但我們到后臺(tái)發(fā)現(xiàn)請(qǐng)求中的文件名亂碼了,這時(shí)采用前面所說的encodeURI可以解決。

(2)客戶端下載執(zhí)行時(shí)文件名亂碼

在實(shí)際測(cè)試中發(fā)現(xiàn),在其他瀏覽器都可以執(zhí)行的情況下,ie下中文文件名可能會(huì)出現(xiàn)亂碼。在網(wǎng)上看到了這樣一段代碼,經(jīng)測(cè)試,完美解決了不同瀏覽器的中文亂碼問題

/*
* 解決各瀏覽器的中文亂碼問題
*/
String userAgent = request.getHeader("User-Agent");
byte[] bytes = userAgent.contains("MSIE") ? fileName.getBytes()
: fileName.getBytes("UTF-8"); // fileName.getBytes("UTF-8")處理safari的亂碼問題
fileName = new String(bytes, "ISO-8859-1"); // 各瀏覽器基本都支持ISO編碼
response.setHeader("Content-disposition",
String.format("attachment; filename=\"%s\"", fileName));

(3)服務(wù)器上文件亂碼

不同的服務(wù)器可能因平臺(tái)的不同編碼方式也不同,這里也需要注意。具體的解決方案請(qǐng)參見之前寫過的一篇文章:文件下載過程中中文亂碼處理

以上所述是小編給大家介紹的Java Web實(shí)現(xiàn)文件下載和亂碼處理方法,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

  • Java實(shí)現(xiàn)郵件找回密碼功能

    Java實(shí)現(xiàn)郵件找回密碼功能

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)郵件找回密碼功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-02-02
  • mybatis-plus 攔截器敏感字段加解密的實(shí)現(xiàn)

    mybatis-plus 攔截器敏感字段加解密的實(shí)現(xiàn)

    數(shù)據(jù)庫在保存數(shù)據(jù)時(shí),對(duì)于某些敏感數(shù)據(jù)需要脫敏或者加密處理,本文主要介紹了mybatis-plus 攔截器敏感字段加解密的實(shí)現(xiàn),感興趣的可以了解一下
    2021-11-11
  • 實(shí)例講解Java中的synchronized

    實(shí)例講解Java中的synchronized

    這篇文章主要介紹了Java中synchronized的使用方法,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • 基于Java中字符串內(nèi)存位置詳解

    基于Java中字符串內(nèi)存位置詳解

    下面小編就為大家?guī)硪黄贘ava中字符串內(nèi)存位置詳解。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-08-08
  • 匯總Java中List 去重的 6 種方法

    匯總Java中List 去重的 6 種方法

    這篇文章主要介紹了匯總Java中List 去重的 6 種方法,文章圍繞主題展開List去重的方法,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-05-05
  • Mybatis的介紹、基本使用、高級(jí)使用

    Mybatis的介紹、基本使用、高級(jí)使用

    這篇文章主要介紹了Mybatis的介紹、基本使用、高級(jí)使用,Mybatis是一款半自動(dòng)的ORM持久層框架,具有較高的SQL靈活性,如何使用看這篇就夠了,需要的朋友可以參考下
    2023-03-03
  • Java中反射機(jī)制的使用詳解

    Java中反射機(jī)制的使用詳解

    這篇文章主要介紹了Java中反射機(jī)制的使用詳解,Java的發(fā)射機(jī)制允許程序在運(yùn)行時(shí)檢查和操作任意一個(gè)類、方法、屬性等的信息,包括了類名、方法名、屬性名、參數(shù)列表以及訪問修飾符等,需要的朋友可以參考下
    2023-09-09
  • Java中的Set集合簡(jiǎn)單匯總解析

    Java中的Set集合簡(jiǎn)單匯總解析

    這篇文章主要介紹了Java中的Set集合簡(jiǎn)單匯總解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • Spring依賴注入(DI)兩種方式的示例詳解

    Spring依賴注入(DI)兩種方式的示例詳解

    這篇文章主要介紹了Spring依賴注入(DI)的兩種方式:setter注入和構(gòu)造器注入。文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2022-06-06
  • Java 基礎(chǔ)詳解(泛型、集合、IO、反射)

    Java 基礎(chǔ)詳解(泛型、集合、IO、反射)

    下面小編就為大家?guī)硪黄狫ava 基礎(chǔ)詳解(泛型、集合、IO、反射)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-10-10

最新評(píng)論