2007年4月30日
#
<html>
<head>
<title>ÎļþÉÏÔØ</title>
</head>
<body>
<form action="upjsp.jsp" enctype="MULTIPART/FORM-DATA" method=post>
<br />
¹«Ë¾: <input type="text" name="company" />
<br />
Ñ¡ÔñÒªÉÏÔØµÄÎļþ <input type="file" name="filename" />
<br />
<input type="submit" value="ÉÏÔØ" />
</form>
</body>
</html>
================================END=======================================
<jsp:useBean id="TheBean" scope="page" class="UpBean " />
<%
TheBean.doUpload(request);
%>
================================END=======================================
import java.io.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletInputStream;
public class UpBean {
public void doUpload(HttpServletRequest request) throws
IOException {
PrintWriter pw = new PrintWriter(
new BufferedWriter(new FileWriter("test.txt")));
ServletInputStream in = request.getInputStream();
int i = in.read();
while (i != -1) {
pw.print((char) i);
i = in.read();
}
pw.close();
}
}
================================END=======================================
import java.sql.*;
import java.io.*;
import java.util.logging.Logger;
class Mobile_area
{
public static void main(String[] args)
{
try
{
String address = "jdbc:odbc:mobile_area";
//驅(qū)動類型+目標(biāo)數(shù)據(jù)庫ip+數(shù)據(jù)庫端口
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
System.out.println("已經(jīng)成功連接手機歸屬地數(shù)據(jù)庫。");}
catch (ClassNotFoundException cnfe) {
System.out.println("連接手機歸屬地數(shù)據(jù)庫失敗!請參考‘readme.txt’文件的描述進(jìn)行配置!");}
String user="sa";//數(shù)據(jù)庫用戶密碼
String passwd="";//口令
String database = "mobilezip";//目標(biāo)數(shù)據(jù)庫
Logger log = Logger.getLogger("Mobile_area");
//if (log==null) log= Logger("Mobile_area","mobile_area.log");
Connection con = DriverManager.getConnection(address,user,passwd);//建立鏈接
con.setCatalog(database);//確定目標(biāo)數(shù)據(jù)庫
Statement smt =con.createStatement();
Statement insert_smt =con.createStatement();
Statement insert_smt_pre =con.createStatement();
String selCode = "";//查詢語句
String import_file="mobile.txt";
String mobile_pre="";
String mobile_area="";
String city="";
String privince="";
String mobile_num;
ResultSet res,rs;
System.out.println("提示:您需要處理的文件必須放在應(yīng)用程序所在的目錄中,否則無法處理");
System.out.println(" 進(jìn)度狀態(tài)的含義: '.'代表當(dāng)前的手機號碼已經(jīng)處理過;'0'代表成功查找并插入該手機號碼的歸屬地信息;'x'代表處理失敗");
System.out.println("請您輸入需要處理的文件名稱:");
DataInputStream inputFilename =
new DataInputStream(
new BufferedInputStream(System.in));
try {
String tmp="";
if((tmp = inputFilename.readLine()).length()>0) import_file =tmp ;
System.out.println("您需要處理的文件名為:"+import_file+",處理即將進(jìn)行......");
} catch(IOException e) {
System.out.println("您輸入的文件異常!請檢查您指定的文件是否當(dāng)前的目錄存在。");
}
System.out.println("如您沒有輸入需要處理的文件,默認(rèn)的處理文件名稱為:"+import_file);
DataInputStream in =
new DataInputStream(
new BufferedInputStream(
new FileInputStream(import_file)));
String s, s2 = new String();
System.out.println("|手機號碼\t|手機區(qū)段\t|手機區(qū)號\t|城市\(zhòng)t|省市|");//輸出此條記錄的查詢結(jié)果
int i=0;
String insert_sql="";
while((s = in.readLine())!= null)
{
mobile_num=s;
if(s==null) s="";
if(s.length()>10)
s=s.substring(0,7);
else
s="88888888888";
selCode="SELECT Mobile_area.mobile, Mobile_area.zip, Mobile_area.city, Mobile_area.state FROM Mobile_area WHERE ((Mobile_area.mobile)="+ s +")";
//System.out.println(selCode);
res = smt.executeQuery(selCode);//結(jié)果集
if(res.next())
{ //從第一條往后依次取結(jié)果集中的記錄
mobile_pre = res.getString(1);//等同rs.getString("userId"),即第一個字段數(shù)據(jù)
mobile_area = res.getString(2);//同上,第二個字段,全部取其為String類型
city = res.getString(3);//等同rs.getString("userId"),即第一個字段數(shù)據(jù)
privince = res.getString(4);//同上,第二個字段,全部取其為String類型
//若是中文字段,一般需要轉(zhuǎn)碼
//userName = new String(userName.getBytes("ISO-8859-1"),"gb2312");
if(i<=100)
System.out.println("|"+mobile_num+"\t|"+mobile_pre+"\t|"+mobile_area+"\t|"+city+"\t|"+privince+"|");//輸出此條記錄的查詢結(jié)果
//log.info("|"+mobile_num+"\t|"+mobile_pre+"\t|"+mobile_area+"\t|"+city+"\t|"+privince+"|") ;
String insert_sql_pre="select count(mobile_num) from mobile_area_insert where mobile_num='"+mobile_num+"'";
rs=insert_smt_pre.executeQuery(insert_sql_pre);
int rcount=0;
if(rs.next()){
rcount=rs.getInt(1);}
rs.close();//釋放資源
if(rcount==0)
{
insert_sql="insert into mobile_area_insert(mobile_num,mobile,zip,city,state) values('"+mobile_num+"','"+mobile_pre+"','"+mobile_area+"','"+city+"','"+privince+"')";
int j=insert_smt_pre.executeUpdate(insert_sql);
if(i>100)
{
if(j>0) System.out.print("0");
else System.out.print("x");
if(i%50==0) System.out.println(i);
}
}
else
{ if(i>100){
System.out.print(".");
if(i%50==0) System.out.println(i); }
}
i++;
}
res.close();//釋放資源
}
System.out.println("\t" + i +"行已經(jīng)處理!"); System.out.println("=========================end=========================");//輸出此條記錄的查詢結(jié)果
in.close();
smt.close();
insert_smt.close();
insert_smt_pre.close();
con.close();
}
catch (Exception e)
{e.printStackTrace();}
}
}
摘要:本文介紹了JavaBean實現(xiàn)多個文件上傳的兩種方法,分別是使用http協(xié)議和ftp協(xié)議實現(xiàn)。首先講述了http協(xié)議傳送多個文件的基本格式和實現(xiàn)上傳的詳細(xì)過程,之后簡單介紹了使用ftpclient 類實現(xiàn)了ftp方式的上傳,最后對這兩種方法進(jìn)行了比較。
關(guān)鍵字:JavaBean 、http 、ftp 、ftpclient
JavaBean是一種基于Java的軟件組件。JSP對于在Web 應(yīng)用中集成JavaBean組件提供了完善的支持。這種支持不僅能縮短開發(fā)時間(可以直接利用經(jīng)測試和可信任的已有組件,避免了重復(fù)開發(fā)),也為JSP應(yīng)用帶來了更多的可伸縮性。
文件的上傳功能在基于B/S的開發(fā)模式中非常普遍。同其他開發(fā)工具相比較,JSP對文件的上傳支持并不是很完美,它既不象ASP那樣一定需要使用組件來完成,也不像PHP那樣直接提供了文件上載的支持。JSP實現(xiàn)文件上傳的實現(xiàn)方式是這樣的:使用ServletRequest類的getInputStream()方法獲得一個客戶端向服務(wù)器發(fā)出的數(shù)據(jù)流,然后處理這個數(shù)據(jù)流,從中分析、得到文件上傳中傳遞到服務(wù)器的各個參數(shù)和數(shù)據(jù),然后將其中的文件數(shù)據(jù)存儲為一個文件或插入到數(shù)據(jù)庫中。通常JSP頁面中不處理文件的上傳功能,而是把這些功能放到Servlet 或JavaBean中去實現(xiàn)。使用Servlet完成文件上傳的例子在一些JSP的相關(guān)書籍中都有所介紹,我這里介紹使用JeanBean是如何完成文件上傳的。JSP中實現(xiàn)文件的上傳可以采用兩種方式即采用HTTP協(xié)議和FTP協(xié)議實現(xiàn),二者在傳輸?shù)脑砩洗嬖诤艽蟮牟町悺R韵聦⒔Y(jié)合源代碼對它們的實現(xiàn)做簡單介紹,相信讀者會從中有所收獲。以下程序已經(jīng)調(diào)試通過。調(diào)試的環(huán)境:window 2000 server+Apache +tomcat4.0,JavaBean調(diào)試環(huán)境:JDK1.4+Editplus。
在JSP中使用JavaBean實現(xiàn)基于Web的文件上傳功能一般需要三種文件結(jié)合完成。這三種文件分別是提供界面的HTML頁面文件、完成調(diào)用實現(xiàn)上傳功能的JavaBean的JSP文件和實現(xiàn)JavaBean的Java的類文件。以下我將重點講述采用HTTP協(xié)議和FTP協(xié)議實現(xiàn)文件上傳功能的JavaBean部分。
1 采用HTTP協(xié)議實現(xiàn)多個文件的上傳
在過去的Html中,表單不能實現(xiàn)文件的上傳,這多少限制了一些網(wǎng)頁的功能。RFC1867規(guī)范(即Html中實現(xiàn)基于表單的文件上傳)對表單作出了擴(kuò)展,增加了一個表單元素〈input type=file>。通過使用這個元素,瀏覽器會自動生成一個輸入框和一個按鈕,輸入框可供用戶填寫本地的文件名和路徑名,按鈕可以讓瀏覽器打開一個文件選擇框供用戶選擇文件。具體的表單實現(xiàn)如下:
當(dāng)選擇了粘貼文件后就直接輸入本地文件的絕對路徑,表單的action屬性值是*.jsp,這意味著請求(包括上載的文件)將發(fā)送給*..jsp文件。在這個過程中實際上就實現(xiàn)了HTTP方式的文件上載。文件從客戶端到服務(wù)器的上載是由HTTP協(xié)議的通用網(wǎng)關(guān)界面(CGI)支持的。這種上載方式要求瀏覽器和WEBServer兩方面都能夠支持Rfc1867。JavaBean 通過ServletRequest類的getInputStream()方法獲得一個客戶端向服務(wù)器發(fā)出的數(shù)據(jù)流、分析上傳的文件格式,根據(jù)分析結(jié)果將多個文件依次輸出服務(wù)器端的目標(biāo)文件中。本例中的JavaBeande的功能是由testUpload類具體實現(xiàn)。TestUpload類的框架如下:
public class testUpload
{
public testUpload(){……}
public final void initialize(ServletConfig config) throws ServletException
{ m_application = config.getServletContext(); }
public void upload() throws testUploadException, IOException, ServletException
{………}
private void getDataSection(){………}
private void getDataHeader(){………}
public int save (String destPathName)
throws SmartUploadException, IOException, ServletException
{………}
……
}
通過initialize()方法初始化Servlet的運行環(huán)境。使用upload()方法獲得輸入流,并分析上傳文件的格式,并將各個上傳文件的屬性賦給多個File類實例處理,這些File類實例由Files類管理。File類根據(jù)各文件的屬性調(diào)用它的save ()方法將多個文件依次輸出服務(wù)器端的目標(biāo)文件中。其中upload()方法是關(guān)鍵,用于分析http1.1協(xié)議傳送文件的格式。經(jīng)過測試,我們得出傳輸流文件的格式,這對理解upload()方法很有用。例如,上傳我的文檔 t.txt文件。格式如下:
//文件分隔符
-----------------------------7d226137250336
//文件信息頭
Content-Disposition: form-data; name="FILE1"; filename="C:Documents and SettingsAdministrator.TIMBER-4O6B0ZZ0My Documents t.sql"
Content-Type: text/plain
//源文件內(nèi)容
create table info(
content image null);
//下一個文件的分隔符
-----------------------------7d226137250336
Content-Disposition: form-data; name="FILE2"; filename=""
Content-Type: application/octet-stream
-----------------------------7d226137250336
從以上文件我們可以看出,HTTP協(xié)議在上傳多個文件時,是將文件全部放到輸入流并以一定的分隔符來區(qū)分的。實際上upload()方法就是要分析上面的文件,確定分隔符的內(nèi)容、各個文件的內(nèi)容格式、文件的完整路徑名稱、及其文件的實際數(shù)據(jù)的始末位置。這里需要說明的一點是分隔符是隨機的,它是傳輸流文件的第一個回車符之前的所有字符。
Upload()方法的實現(xiàn)流程是:首先將輸入流文件輸出到字節(jié)數(shù)組m_binArray中,通過下面的代碼實現(xiàn)。
m_totalBytes=1024;totalRead=0;
for(; totalRead < m_totalBytes; totalRead += readBytes)
try
{ m_request.getInputStream();
readBytes = m_request.getInputStream().read(m_binArray, totalRead, m_totalBytes - totalRead);
}catch(Exception e){ throw new SmartUploadException("Unable to upload.");}
這里采用了循環(huán)中多字節(jié)讀取方法,以上循環(huán)不斷地讀取數(shù)據(jù)直到數(shù)組填滿為止。如果一個文件可以完全得到,則文件的所有字節(jié)也就可以全部得到。但是因為網(wǎng)絡(luò)速度通常比CPU慢得多,所以程序很容易在所有的數(shù)據(jù)到來之前就清空網(wǎng)絡(luò)緩沖區(qū)。實際上,多字節(jié)讀取方法在試圖從暫時為空但是開放的網(wǎng)絡(luò)緩存區(qū)讀取數(shù)據(jù)時,該方法會返回0,這表示沒有數(shù)據(jù)存在但網(wǎng)絡(luò)流沒有關(guān)閉。這種情況下,單字節(jié)方法將阻止運行程序的執(zhí)行,所以多字節(jié)的行為優(yōu)于單字節(jié)read()方法的行為。接下來將分析字節(jié)數(shù)組m_binArray。首先找到分隔符;使用getDataHeader()方法返回文件信息頭的值,從中確定源文件的完整路徑名、源文件的擴(kuò)展名和源文件文件內(nèi)容格式;使用getDataSection()方法返回文件的內(nèi)容數(shù)據(jù),并記錄文件數(shù)據(jù)在字節(jié)數(shù)組中的起止位置。然后生成一個File類實例,并將文件的完整路徑名、源文件的擴(kuò)展名、源文件文件內(nèi)容格式和文件的內(nèi)容數(shù)據(jù)的起止位置放到File類實例的屬性中。找到下一個分隔符,繼續(xù)重復(fù)上述過程,直至分析完畢。
2 采用FTP協(xié)議實現(xiàn)多個文件的上傳
FTP協(xié)議是Internet上用來傳送文件的協(xié)議,規(guī)定了Internet上文件互相傳送的標(biāo)準(zhǔn)。在java中實現(xiàn)這一功能是借助FtpClient類完成的。具體實現(xiàn)過程:首先與FTP服務(wù)器建立連接;初始化文件的傳輸方式,包括ASCII和BINARY兩種方式;將文件輸出到文件輸入流FileInputStream中;FileInputStream中的數(shù)據(jù)讀入字節(jié)數(shù)組中;字節(jié)數(shù)組中的數(shù)據(jù)寫入輸出流TelnetOutputStream(利用write方法將數(shù)據(jù)寫入到一個網(wǎng)絡(luò)鏈接上)。這樣和源文件同名的一個文件就復(fù)制到了服務(wù)器端。本例的JavaBean中通過connectServer()、upload()和closeConnect()三個方法完成文件上傳過程。主要實現(xiàn)如下:
public class ftpUpload
{ String filename;String filename1;FtpClient ftpClient;
public void connectServer(string server,string user,string password,string path)
{
//server:FTP服務(wù)器的IP地址;user:登錄FTP服務(wù)器的用戶名
//password:登錄FTP服務(wù)器的用戶名的口令;path:FTP服務(wù)器上的路徑
try{ ftpClient=new FtpClient();
ftpClient.openServer(server);
ftpClient.login(user, password);
System.out.println("login success!");
if (path.length()!=0) ftpClient.cd(path);
ftpClient.binary(); }catch (IOException ex) {System.out.println(ex);}
}
public void closeConnect()
{try{ ftpClient.closeServer();
}catch (IOException ex) {System.out.println(ex);}
}
public void upload()
{ filename1=findFileName(filename);
//從filename中分析出文件的名稱,作為目標(biāo)文件的名稱,具體方法實現(xiàn)未給出
try {
TelnetOutputStream os=ftpClient.put(filename1);
java.io.File file_in=new java.io.File(filename);
FileInputStream is=new FileInputStream(file_in);
byte[] bytes=new byte[1024];
int c;
while ((c=is.read(bytes))!=-1){ os.write(bytes,0,c); }
is.close(); os.close();
} catch (IOException ex) {System.out.println(ex);}
}
}
connectServer()完成與FTP服務(wù)器建立連接的功能,使用FtpClient的openServer(string server)方法打開遠(yuǎn)程FTP服務(wù)器,然后使用FtpClient的login(user, password)方法登錄服務(wù)器。登錄遠(yuǎn)程FTP服務(wù)器有兩種方式,一種是注冊用戶登錄,另一種是以匿名方式登錄。前者要求用戶首先注冊為服務(wù)器的客戶,服務(wù)器會給客戶一個登錄賬號和密碼,依據(jù)賬號和密碼連結(jié)到服務(wù)器上。后者要求用戶不用注冊而使用特殊的用戶名"annoymous"和"guest"有限制的訪問遠(yuǎn)程主機的公開文件,現(xiàn)在許多系統(tǒng)要求用戶將Email地址作為口令。出于安全的目的,大部分匿名FTP主機一般只允許遠(yuǎn)程用戶下載文件,而不允許上傳,這將依賴于FTP服務(wù)器的設(shè)置。用戶可根據(jù)實際情況選擇使用兩種方式。登錄完成后使用FtpClient的binary()方法初始化傳輸方式為字節(jié)方式。upload()完成文件的上傳功能。創(chuàng)建源文件的文件輸入流FileInputStream,將輸入流寫入到字節(jié)數(shù)組中,利用TelnetOutputStream的write方法將字節(jié)數(shù)組中的數(shù)據(jù)寫入到一個網(wǎng)絡(luò)鏈接上。由于TelnetOutputStream打開的是FTP服務(wù)器上的一個文件,所以數(shù)據(jù)寫入到了目標(biāo)文件中,這樣就完成了文件上傳。closeConnect()要求與服務(wù)器斷開連接。
以上只是單個文件上傳的過程,如果是多個文件可以多次調(diào)用此上傳過程。由以上兩種方式我們可以看出采用FTP協(xié)議實現(xiàn)多個文件的上傳比較簡單,容易實現(xiàn)。利用FTP協(xié)議上傳文件一般是編寫的客戶端的程序,服務(wù)器端的安全設(shè)置會比較復(fù)雜;而利用HTTP協(xié)議上傳文件則是服務(wù)器端的應(yīng)用程序,相對來說安全設(shè)置會比較簡單。并且通過測試發(fā)現(xiàn)FTP上傳方式在傳輸大文件時速度是HTTP上傳方式的幾十倍甚至幾百倍,但在傳輸小于1M的文件時卻比HTTP上傳方式稍慢一些。所以說兩種傳輸方式各有優(yōu)勢,請讀者根據(jù)自身情況量力而行。如果有什么問題或者是需要其他部分的源碼,請與我聯(lián)系!
================================UPLOAD.HTML=======================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>文件上傳</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body>
<p> </p>
<p align="center">上傳文件選擇</p>
<FORM METHOD="POST" ACTION="upload.jsp"
ENCTYPE="multipart/form-data">
<input type="hidden" name="TEST" value="good">
<table width="75%" border="1" align="center">
<tr>
<td><div align="center">1、
<input type="FILE" name="FILE1" size="30">
</div></td>
</tr>
<tr>
<td><div align="center">2、
<input type="FILE" name="FILE2" size="30">
</div></td>
</tr>
<tr>
<td><div align="center">3、
<input type="FILE" name="FILE3" size="30">
</div></td>
</tr>
<tr>
<td><div align="center">4、
<input type="FILE" name="FILE4" size="30">
</div></td>
</tr>
<tr>
<td><div align="center">
<input type="submit" name="Submit" value="上傳它!">
</div></td>
</tr>
</table>
</FORM>
</body>
</html>
================================END=======================================
================================upload.jsp================================
<%@ page contentType="text/html;charset=gb2312"%>
<%@ page import="com.jspsmart.upload.*"%>
<%@ page import="java.util.*"%>
<html>
<head>
<title>文件上傳處理頁面</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body>
<%
// 新建一個SmartUpload對象
SmartUpload su = new SmartUpload();
// 上傳初始化
su.initialize(pageContext);
// 設(shè)定上傳限制
// 1.限制每個上傳文件的最大長度。
// su.setMaxFileSize(10000);
// 2.限制總上傳數(shù)據(jù)的長度。
// su.setTotalMaxFileSize(20000);
// 3.設(shè)定允許上傳的文件(通過擴(kuò)展名限制),僅允許doc,txt文件。
// su.setAllowedFilesList("doc,txt");
// 4.設(shè)定禁止上傳的文件(通過擴(kuò)展名限制),禁止上傳帶有exe,bat,jsp,htm,html擴(kuò)展名的文件和沒有擴(kuò)展名的文件。
// su.setDeniedFilesList("exe,bat,jsp,htm,html,,");
// 上傳文件
su.upload();
// 將上傳文件全部保存到指定目錄
int count = su.save("/upload");
out.println(count+"個文件上傳成功!<br>");
// 利用Request對象獲取參數(shù)之值
out.println("TEST="+su.getRequest().getParameter("TEST")+"<BR><BR>");
// 逐一提取上傳文件信息,同時可保存文件。
for (int i=0;i<su.getFiles().getCount();i++)
{
com.jspsmart.upload.File file = su.getFiles().getFile(i);
// 若文件不存在則繼續(xù)
if (file.isMissing()) continue;
// 顯示當(dāng)前文件信息
out.println("<TABLE BORDER=1>");
out.println("<TR><TD>表單項名(FieldName)</TD><TD>"+ file.getFieldName() + "</TD></TR>");
out.println("<TR><TD>文件長度(Size)</TD><TD>" + file.getSize() + "</TD></TR>");
out.println("<TR><TD>文件名(FileName)</TD><TD>" + file.getFileName() + "</TD></TR>");
out.println("<TR><TD>文件擴(kuò)展名(FileExt)</TD><TD>" + file.getFileExt() + "</TD></TR>");
out.println("<TR><TD>文件全名(FilePathName)</TD><TD>"+ file.getFilePathName() + "</TD></TR>");
out.println("</TABLE><BR>");
// 將文件另存
// file.saveAs("/upload/" + myFile.getFileName());
// 另存到以WEB應(yīng)用程序的根目錄為文件根目錄的目錄下
// file.saveAs("/upload/" + myFile.getFileName(), su.SAVE_VIRTUAL);
// 另存到操作系統(tǒng)的根目錄為文件根目錄的目錄下
// file.saveAs("c:\\temp\\" + myFile.getFileName(), su.SAVE_PHYSICAL);
}
%>
</body>
</html>
================================END=======================================
================================download.html=============================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>下載</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body>
<a href="download.jsp">點擊下載</a>
</body>
</html>
================================END=======================================
================================download.jsp==============================
<%@ page contentType="text/html;charset=gb2312"%>
<%@ page import="com.jspsmart.upload.*"%>
<%
//新建一個SmartUpload對象
SmartUpload su=new SmartUpload();
// 初始化
su.initialize(pageContext);
// 設(shè)定contentDisposition為null以禁止瀏覽器自動打開文件,
//保證點擊鏈接后是下載文件。若不設(shè)定,則下載的文件擴(kuò)展名為
//doc時,瀏覽器將自動用word打開它。擴(kuò)展名為pdf時,
//瀏覽器將用acrobat打開。
su.setContentDisposition(null);
// 下載文件
su.downloadFile("/upload/mobile.txt");
%>
================================END=======================================
import java.sql.*;
public class access{
public static void main(String args[]){
Connection con;
Statement sql; //聲明Statement對象
ResultSet rs;
try{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
}
catch(ClassNotFoundException e){
System.out.println(""+e);
}
try{
con=DriverManager.getConnection("jdbc:odbc:redsun","","");
sql=con.createStatement();
rs=sql.executeQuery("Select * FROM member");
while(rs.next()){
String name=rs.getString(1); //獲得數(shù)據(jù)庫第一列
String sex=rs.getString(2);
System.out.println("姓名:"+name); //輸出信息
System.out.println("性別:"+sex);
}
con.close();
}
catch(SQLException el){}
}
}
一、安裝篇
jspSmartUpload是由www.jspsmart.com網(wǎng)站開發(fā)的一個可免費使用的全功能的文件上傳下載組件,適于嵌入執(zhí)行上傳下載操作的JSP文件中。該組件有以下幾個特點:
1、使用簡單。在JSP文件中僅僅書寫三五行JAVA代碼就可以搞定文件的上傳或下載,方便。
2、能全程控制上傳。利用jspSmartUpload組件提供的對象及其操作方法,可以獲得全部上傳文件的信息(包括文件名,大小,類型,擴(kuò)展名,文件數(shù)據(jù)等),方便存取。
3、能對上傳的文件在大小、類型等方面做出限制。如此可以濾掉不符合要求的文件。
4、下載靈活。僅寫兩行代碼,就能把Web服務(wù)器變成文件服務(wù)器。不管文件在Web服務(wù)器的目錄下或在其它任何目錄下,都可以利用jspSmartUpload進(jìn)行下載。
5、能將文件上傳到數(shù)據(jù)庫中,也能將數(shù)據(jù)庫中的數(shù)據(jù)下載下來。這種功能針對的是MYSQL數(shù)據(jù)庫,因為不具有通用性,所以本文不準(zhǔn)備舉例介紹這種用法。
jspSmartUpload組件可以從www.jspsmart.com網(wǎng)站上自由下載,壓縮包的名字是jspSmartUpload.zip。下載后,用WinZip或WinRAR將其解壓到Tomcat的webapps目錄下(本文以Tomcat服務(wù)器為例進(jìn)行介紹)。解壓后,將webapps/jspsmartupload目錄下的子目錄Web-inf名字改為全大寫的WEB-INF,這樣一改jspSmartUpload類才能使用。因為Tomcat對文件名大小寫敏感,它要求Web應(yīng)用程序相關(guān)的類所在目錄為WEB-INF,且必須是大寫。接著重新啟動Tomcat,這樣就可以在JSP文件中使用jspSmartUpload組件了。
注意,按上述方法安裝后,只有webapps/jspsmartupload目錄下的程序可以使用jspSmartUpload組件,如果想讓Tomcat服務(wù)器的所有Web應(yīng)用程序都能用它,必須做如下工作:
1.進(jìn)入命令行狀態(tài),將目錄切換到Tomcat的webapps/jspsmartupload/WEB-INF目錄下。
2.運行JAR打包命令:jar cvf jspSmartUpload.jar com
(也可以打開資源管理器,切換到當(dāng)前目錄,用WinZip將com目錄下的所有文件壓縮成jspSmartUpload.zip,然后將jspSmartUpload.zip換名為jspSmartUpload.jar文件即可。)
3.將jspSmartUpload.jar拷貝到Tomcat的shared/lib目錄下。
二、相關(guān)類說明篇
㈠ File類
這個類包裝了一個上傳文件的所有信息。通過它,可以得到上傳文件的文件名、文件大小、擴(kuò)展名、文件數(shù)據(jù)等信息。
File類主要提供以下方法:
1、saveAs作用:將文件換名另存。
原型:
public void saveAs(java.lang.String destFilePathName)
或
public void saveAs(java.lang.String destFilePathName, int optionSaveAs)
其中,destFilePathName是另存的文件名,optionSaveAs是另存的選項,該選項有三個值,分別是SAVEAS_PHYSICAL,SAVEAS_VIRTUAL,SAVEAS_AUTO。SAVEAS_PHYSICAL表明以操作系統(tǒng)的根目錄為文件根目錄另存文件,SAVEAS_VIRTUAL表明以Web應(yīng)用程序的根目錄為文件根目錄另存文件,SAVEAS_AUTO則表示讓組件決定,當(dāng)Web應(yīng)用程序的根目錄存在另存文件的目錄時,它會選擇SAVEAS_VIRTUAL,否則會選擇SAVEAS_PHYSICAL。
例如,saveAs("/upload/sample.zip",SAVEAS_PHYSICAL)執(zhí)行后若Web服務(wù)器安裝在C盤,則另存的文件名實際是c:\upload\sample.zip。而saveAs("/upload/sample.zip",SAVEAS_VIRTUAL)執(zhí)行后若Web應(yīng)用程序的根目錄是webapps/jspsmartupload,則另存的文件名實際是webapps/jspsmartupload/upload/sample.zip。saveAs("/upload/sample.zip",SAVEAS_AUTO)執(zhí)行時若Web應(yīng)用程序根目錄下存在upload目錄,則其效果同saveAs("/upload/sample.zip",SAVEAS_VIRTUAL),否則同saveAs("/upload/sample.zip",SAVEAS_PHYSICAL)。
建議:對于Web程序的開發(fā)來說,最好使用SAVEAS_VIRTUAL,以便移植。
2、isMissing
作用:這個方法用于判斷用戶是否選擇了文件,也即對應(yīng)的表單項是否有值。選擇了文件時,它返回false。未選文件時,它返回true。
原型:public boolean isMissing()
3、getFieldName
作用:取HTML表單中對應(yīng)于此上傳文件的表單項的名字。
原型:public String getFieldName()
4、getFileName
作用:取文件名(不含目錄信息)
原型:public String getFileName()
5、getFilePathName
作用:取文件全名(帶目錄)
原型:public String getFilePathName
6、getFileExt
作用:取文件擴(kuò)展名(后綴)
原型:public String getFileExt()
7、getSize
作用:取文件長度(以字節(jié)計)
原型:public int getSize()
8、getBinaryData
作用:取文件數(shù)據(jù)中指定位移處的一個字節(jié),用于檢測文件等處理。
原型:public byte getBinaryData(int index)。其中,index表示位移,其值在0到getSize()-1之間。
㈡ Files類
這個類表示所有上傳文件的集合,通過它可以得到上傳文件的數(shù)目、大小等信息。有以下方法:
1、getCount
作用:取得上傳文件的數(shù)目。
原型:public int getCount()
2、getFile
作用:取得指定位移處的文件對象File(這是com.jspsmart.upload.File,不是java.io.File,注意區(qū)分)。
原型:public File getFile(int index)。其中,index為指定位移,其值在0到getCount()-1之間。
3、getSize
作用:取得上傳文件的總長度,可用于限制一次性上傳的數(shù)據(jù)量大小。
原型:public long getSize()
4、getCollection
作用:將所有上傳文件對象以Collection的形式返回,以便其它應(yīng)用程序引用,瀏覽上傳文件信息。
原型:public Collection getCollection()
5、getEnumeration
作用:將所有上傳文件對象以Enumeration(枚舉)的形式返回,以便其它應(yīng)用程序瀏覽上傳文件信息。
原型:public Enumeration getEnumeration()
㈢ Request類
這個類的功能等同于JSP內(nèi)置的對象request。只所以提供這個類,是因為對于文件上傳表單,通過request對象無法獲得表單項的值,必須通過jspSmartUpload組件提供的Request對象來獲取。該類提供如下方法:
1、getParameter
作用:獲取指定參數(shù)之值。當(dāng)參數(shù)不存在時,返回值為null。
原型:public String getParameter(String name)。其中,name為參數(shù)的名字。
2、getParameterValues
作用:當(dāng)一個參數(shù)可以有多個值時,用此方法來取其值。它返回的是一個字符串?dāng)?shù)組。當(dāng)參數(shù)不存在時,返回值為null。
原型:public String[] getParameterValues(String name)。其中,name為參數(shù)的名字。
3、getParameterNames
作用:取得Request對象中所有參數(shù)的名字,用于遍歷所有參數(shù)。它返回的是一個枚舉型的對象。
原型:public Enumeration getParameterNames()
㈣ SmartUpload類這個類完成上傳下載工作。
A.上傳與下載共用的方法:
只有一個:initialize。
作用:執(zhí)行上傳下載的初始化工作,必須第一個執(zhí)行。
原型:有多個,主要使用下面這個:
public final void initialize(javax.servlet.jsp.PageContext pageContext)
其中,pageContext為JSP頁面內(nèi)置對象(頁面上下文)。
B.上傳文件使用的方法:
1、upload
作用:上傳文件數(shù)據(jù)。對于上傳操作,第一步執(zhí)行initialize方法,第二步就要執(zhí)行這個方法。
原型:public void upload()
2、save
作用:將全部上傳文件保存到指定目錄下,并返回保存的文件個數(shù)。
原型:public int save(String destPathName)
和public int save(String destPathName,int option)
其中,destPathName為文件保存目錄,option為保存選項,它有三個值,分別是SAVE_PHYSICAL,SAVE_VIRTUAL和SAVE_AUTO。(同F(xiàn)ile類的saveAs方法的選項之值類似)SAVE_PHYSICAL指示組件將文件保存到以操作系統(tǒng)根目錄為文件根目錄的目錄下,SAVE_VIRTUAL指示組件將文件保存到以Web應(yīng)用程序根目錄為文件根目錄的目錄下,而SAVE_AUTO則表示由組件自動選擇。
注:save(destPathName)作用等同于save(destPathName,SAVE_AUTO)。
3、getSize
作用:取上傳文件數(shù)據(jù)的總長度
原型:public int getSize()
4、getFiles
作用:取全部上傳文件,以Files對象形式返回,可以利用Files類的操作方法來獲得上傳文件的數(shù)目等信息。
原型:public Files getFiles()
5、getRequest
作用:取得Request對象,以便由此對象獲得上傳表單參數(shù)之值。
原型:public Request getRequest()
6、setAllowedFilesList
作用:設(shè)定允許上傳帶有指定擴(kuò)展名的文件,當(dāng)上傳過程中有文件名不允許時,組件將拋出異常。
原型:public void setAllowedFilesList(String allowedFilesList)
其中,allowedFilesList為允許上傳的文件擴(kuò)展名列表,各個擴(kuò)展名之間以逗號分隔。如果想允許上傳那些沒有擴(kuò)展名的文件,可以用兩個逗號表示。例如:setAllowedFilesList("doc,txt,,")將允許上傳帶doc和txt擴(kuò)展名的文件以及沒有擴(kuò)展名的文件。
7、setDeniedFilesList
作用:用于限制上傳那些帶有指定擴(kuò)展名的文件。若有文件擴(kuò)展名被限制,則上傳時組件將拋出異常。
原型:public void setDeniedFilesList(String deniedFilesList)
其中,deniedFilesList為禁止上傳的文件擴(kuò)展名列表,各個擴(kuò)展名之間以逗號分隔。如果想禁止上傳那些沒有擴(kuò)展名的文件,可以用兩個逗號來表示。例如:setDeniedFilesList("exe,bat,,")將禁止上傳帶exe和bat擴(kuò)展名的文件以及沒有擴(kuò)展名的文件。
8、setMaxFileSize
作用:設(shè)定每個文件允許上傳的最大長度。
原型:public void setMaxFileSize(long maxFileSize)
其中,maxFileSize為為每個文件允許上傳的最大長度,當(dāng)文件超出此長度時,將不被上傳。
9、setTotalMaxFileSize
作用:設(shè)定允許上傳的文件的總長度,用于限制一次性上傳的數(shù)據(jù)量大小。
原型:public void setTotalMaxFileSize(long totalMaxFileSize)
其中,totalMaxFileSize為允許上傳的文件的總長度。
1、setContentDisposition
作用:將數(shù)據(jù)追加到MIME文件頭的CONTENT-DISPOSITION域。jspSmartUpload組件會在返回下載的信息時自動填寫MIME文件頭的CONTENT-DISPOSITION域,如果用戶需要添加額外信息,請用此方法。
原型:public void setContentDisposition(String contentDisposition)
其中,contentDisposition為要添加的數(shù)據(jù)。如果contentDisposition為null,則組件將自動添加"attachment;",以表明將下載的文件作為附件,結(jié)果是IE瀏覽器將會提示另存文件,而不是自動打開這個文件(IE瀏覽器一般根據(jù)下載的文件擴(kuò)展名決定執(zhí)行什么操作,擴(kuò)展名為doc的將用word程序打開,擴(kuò)展名為pdf的將用acrobat程序打開,等等)。
2、downloadFile
作用:下載文件。
原型:共有以下三個原型可用,第一個最常用,后兩個用于特殊情況下的文件下載(如更改內(nèi)容類型,更改另存的文件名)。
① public void downloadFile(String sourceFilePathName)
其中,sourceFilePathName為要下載的文件名(帶目錄的文件全名)
② public void downloadFile(String sourceFilePathName,String contentType)
其中,sourceFilePathName為要下載的文件名(帶目錄的文件全名),contentType為內(nèi)容類型(MIME格式的文件類型信息,可被瀏覽器識別)。
③ public void downloadFile(String sourceFilePathName,String contentType,String destFileName)
其中,sourceFilePathName為要下載的文件名(帶目錄的文件全名),contentType為內(nèi)容類型(MIME格式的文件類型信息,可被瀏覽器識別),destFileName為下載后默認(rèn)的另存文件名。
三、文件上傳篇
㈠ 表單要求
對于上傳文件的FORM表單,有兩個要求:
1、METHOD應(yīng)用POST,即METHOD="POST"。
2、增加屬性:ENCTYPE="multipart/form-data"
下面是一個用于上傳文件的FORM表單的例子:
<FORM METHOD="POST" ENCTYPE="multipart/form-data"
ACTION="/jspSmartUpload/upload.jsp">
<INPUT TYPE="FILE" NAME="MYFILE">
<INPUT TYPE="SUBMIT">
</FORM>
㈡ 上傳的例子
1、上傳頁面upload.html
本頁面提供表單,讓用戶選擇要上傳的文件,點擊"上傳"按鈕執(zhí)行上傳操作。
頁面源碼如下:
<!--
文件名:upload.html
作 者:縱橫軟件制作中心雨亦奇(zhsoft88@sohu.com)
-->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>文件上傳</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body>
<p> </p>
<p align="center">上傳文件選擇</p>
<FORM METHOD="POST" ACTION="jsp/do_upload.jsp"
ENCTYPE="multipart/form-data">
<input type="hidden" name="TEST" value="good">
<table width="75%" border="1" align="center">
<tr>
<td><div align="center">1、
<input type="FILE" name="FILE1" size="30">
</div></td>
</tr>
<tr>
<td><div align="center">2、
<input type="FILE" name="FILE2" size="30">
</div></td>
</tr>
<tr>
<td><div align="center">3、
<input type="FILE" name="FILE3" size="30">
</div></td>
</tr>
<tr>
<td><div align="center">4、
<input type="FILE" name="FILE4" size="30">
</div></td>
</tr>
<tr>
<td><div align="center">
<input type="submit" name="Submit" value="上傳它!">
</div></td>
</tr>
</table>
</FORM>
</body>
</html>
2、上傳處理頁面do_upload.jsp
本頁面執(zhí)行文件上傳操作。頁面源碼中詳細(xì)介紹了上傳方法的用法,在此不贅述了。
頁面源碼如下:
<%--
文件名:do_upload.jsp
作 者:縱橫軟件制作中心雨亦奇(zhsoft88@sohu.com)
--%>
<%@ page contentType="text/html; charset=gb2312" language="java"
import="java.util.*,com.jspsmart.upload.*" errorPage="" %>
<html>
<head>
<title>文件上傳處理頁面</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body>
<%
// 新建一個SmartUpload對象
SmartUpload su = new SmartUpload();
// 上傳初始化
su.initialize(pageContext);
// 設(shè)定上傳限制
// 1.限制每個上傳文件的最大長度。
// su.setMaxFileSize(10000);
// 2.限制總上傳數(shù)據(jù)的長度。
// su.setTotalMaxFileSize(20000);
// 3.設(shè)定允許上傳的文件(通過擴(kuò)展名限制),僅允許doc,txt文件。
// su.setAllowedFilesList("doc,txt");
// 4.設(shè)定禁止上傳的文件(通過擴(kuò)展名限制),禁止上傳帶有exe,bat,
jsp,htm,html擴(kuò)展名的文件和沒有擴(kuò)展名的文件。
// su.setDeniedFilesList("exe,bat,jsp,htm,html,,");
// 上傳文件
su.upload();
// 將上傳文件全部保存到指定目錄
int count = su.save("/upload");
out.println(count+"個文件上傳成功!<br>");
// 利用Request對象獲取參數(shù)之值
out.println("TEST="+su.getRequest().getParameter("TEST")
+"<BR><BR>");
// 逐一提取上傳文件信息,同時可保存文件。
for (int i=0;i<su.getFiles().getCount();i++)
{
com.jspsmart.upload.File file = su.getFiles().getFile(i);
// 若文件不存在則繼續(xù)
if (file.isMissing()) continue;
// 顯示當(dāng)前文件信息
out.println("<TABLE BORDER=1>");
out.println("<TR><TD>表單項名(FieldName)</TD><TD>"
+ file.getFieldName() + "</TD></TR>");
out.println("<TR><TD>文件長度(Size)</TD><TD>" +
file.getSize() + "</TD></TR>");
out.println("<TR><TD>文件名(FileName)</TD><TD>"
+ file.getFileName() + "</TD></TR>");
out.println("<TR><TD>文件擴(kuò)展名(FileExt)</TD><TD>"
+ file.getFileExt() + "</TD></TR>");
out.println("<TR><TD>文件全名(FilePathName)</TD><TD>"
+ file.getFilePathName() + "</TD></TR>");
out.println("</TABLE><BR>");
// 將文件另存
// file.saveAs("/upload/" + myFile.getFileName());
// 另存到以WEB應(yīng)用程序的根目錄為文件根目錄的目錄下
// file.saveAs("/upload/" + myFile.getFileName(),
su.SAVE_VIRTUAL);
// 另存到操作系統(tǒng)的根目錄為文件根目錄的目錄下
// file.saveAs("c:\\temp\\" + myFile.getFileName(),
su.SAVE_PHYSICAL);
}
%>
</body>
</html>
四、文件下載篇
1、下載鏈接頁面download.html
頁面源碼如下:
<!--
文件名:download.html
作 者:縱橫軟件制作中心雨亦奇(zhsoft88@sohu.com)
-->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>下載</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body>
<a href="jsp/do_download.jsp">點擊下載</a>
</body>
</html>
2、下載處理頁面do_download.jsp do_download.jsp展示了如何利用jspSmartUpload組件來下載文件,從下面的源碼中就可以看到,下載何其簡單。
源碼如下:
<%@ page contentType="text/html;charset=gb2312"
import="com.jspsmart.upload.*" %><%
// 新建一個SmartUpload對象
SmartUpload su = new SmartUpload();
// 初始化
su.initialize(pageContext);
// 設(shè)定contentDisposition為null以禁止瀏覽器自動打開文件,
//保證點擊鏈接后是下載文件。若不設(shè)定,則下載的文件擴(kuò)展名為
//doc時,瀏覽器將自動用word打開它。擴(kuò)展名為pdf時,
//瀏覽器將用acrobat打開。
su.setContentDisposition(null);
// 下載文件
su.downloadFile("/upload/如何賺取我的第一桶金.doc");
%>
注意,執(zhí)行下載的頁面,在Java腳本范圍外(即<% ... %>之外),不要包含HTML代碼、空格、回車或換行等字符,有的話將不能正確下載。不信的話,可以在上述源碼中%><%之間加入一個換行符,再下載一下,保證出錯。因為它影響了返回給瀏覽器的數(shù)據(jù)流,導(dǎo)致解析出錯。
3、如何下載中文文件
jspSmartUpload雖然能下載文件,但對中文支持不足。若下載的文件名中有漢字,則瀏覽器在提示另存的文件名時,顯示的是一堆亂碼,很掃人興。上面的例子就是這樣。(這個問題也是眾多下載組件所存在的問題,很少有人解決,搜索不到相關(guān)資料,可嘆!)
為了給jspSmartUpload組件增加下載中文文件的支持,我對該組件進(jìn)行了研究,發(fā)現(xiàn)對返回給瀏覽器的另存文件名進(jìn)行UTF-8編碼后,瀏覽器便能正確顯示中文名字了。這是一個令人高興的發(fā)現(xiàn)。于是我對jspSmartUpload組件的SmartUpload類做了升級處理,增加了toUtf8String這個方法,改動部分源碼如下:
public void downloadFile(String s, String s1, String s2, int i)
throws ServletException, IOException, SmartUploadException
{
if(s == null)
throw new IllegalArgumentException("File ''" + s +
"'' not found (1040).");
if(s.equals(""))
throw new IllegalArgumentException("File ''" + s +
"'' not found (1040).");
if(!isVirtual(s) && m_denyPhysicalPath)
throw new SecurityException("Physical path is
denied (1035).");
if(isVirtual(s))
s = m_application.getRealPath(s);
java.io.File file = new java.io.File(s);
FileInputStream fileinputstream = new FileInputStream(file);
long l = file.length();
boolean flag = false;
int k = 0;
byte abyte0[] = new byte[i];
if(s1 == null)
m_response.setContentType("application/x-msdownload");
else
if(s1.length() == 0)
m_response.setContentType("application/x-msdownload");
else
m_response.setContentType(s1);
m_response.setContentLength((int)l);
m_contentDisposition = m_contentDisposition != null ?
m_contentDisposition : "attachment;";
if(s2 == null)
m_response.setHeader("Content-Disposition",
m_contentDisposition + " filename=" +
toUtf8String(getFileName(s)));
else
if(s2.length() == 0)
m_response.setHeader("Content-Disposition",
m_contentDisposition);
else
m_response.setHeader("Content-Disposition",
m_contentDisposition + " filename=" + toUtf8String(s2));
while((long)k < l)
{
int j = fileinputstream.read(abyte0, 0, i);
k += j;
m_response.getOutputStream().write(abyte0, 0, j);
}
fileinputstream.close();
}
/**
* 將文件名中的漢字轉(zhuǎn)為UTF8編碼的串,以便下載時能正確顯示另存的文件名.
* 縱橫軟件制作中心雨亦奇2003.08.01
* @param s 原文件名
* @return 重新編碼后的文件名
*/
public static String toUtf8String(String s) {
StringBuffer sb = new StringBuffer();
for (int i=0;i<s.length();i++) {
char c = s.charAt(i);
if (c >= 0 && c <= 255) {
sb.append(c);
} else {
byte[] b;
try {
b = Character.toString(c).getBytes("utf-8");
} catch (Exception ex) {
System.out.println(ex);
b = new byte[0];
}
for (int j = 0; j < b.length; j++) {
int k = b[j];
if (k < 0) k += 256;
sb.append("%" + Integer.toHexString(k).
toUpperCase());
}
}
}
return sb.toString();
}
注意源碼中粗體部分,原jspSmartUpload組件對返回的文件未作任何處理,現(xiàn)在做了編碼的轉(zhuǎn)換工作,將文件名轉(zhuǎn)換為UTF-8形式的編碼形式。UTF-8編碼對英文未作任何處理,對中文則需要轉(zhuǎn)換為%XX的形式。toUtf8String方法中,直接利用Java語言提供的編碼轉(zhuǎn)換方法獲得漢字字符的UTF-8編碼,之后將其轉(zhuǎn)換為%XX的形式。
將源碼編譯后打包成jspSmartUpload.jar,拷貝到Tomcat的shared/lib目錄下(可為所有WEB應(yīng)用程序所共享),然后重啟Tomcat服務(wù)器就可以正常下載含有中文名字的文件了。另,toUtf8String方法也可用于轉(zhuǎn)換含有中文的超級鏈接,以保證鏈接的有效,因為有的WEB服務(wù)器不支持中文鏈接。
小結(jié):jspSmartUpload組件是應(yīng)用JSP進(jìn)行B/S程序開發(fā)過程中經(jīng)常使用的上傳下載組件,它使用簡單,方便。現(xiàn)在我又為其加上了下載中文名字的文件的支持,真?zhèn)€是如虎添翼,必將贏得更多開發(fā)者的青睞。
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.PageContext;
public class UploadFile
{
private ServletRequest request;
private ServletResponse response;
private ServletConfig config;
ServletInputStream DATA;
int FormSize;
File f1;
FileOutputStream os;
DataInputStream is;
String filename;
byte[] b;
byte t;
boolean flag=false;
public UploadFile()
{ }
public void initialize(ServletConfig config,HttpServletRequest request,HttpServletResponse response) throws IOException
{
this.request=request;
this.response=response;
this.config=config;
DATA = request.getInputStream();
FormSize=request.getContentLength();
}
public void initialize(PageContext pageContext) throws IOException
{
request=pageContext.getRequest();
response=pageContext.getResponse();
config=pageContext.getServletConfig();
DATA = request.getInputStream();
FormSize=request.getContentLength();
}
public boolean setFilename(String s)
{
try
{
File f1=new File(s);
os=new FileOutputStream(f1);
}
catch(IOException e)
{return(false);}
return(true);
}
public void getByte()
{
int i=0;
try
{
is=new DataInputStream(DATA);
b=new byte[FormSize];
while (true)
{
try
{
t=is.readByte();
b[i]=t;
i++;
}
catch(EOFException e)
{ break;}
}
is.close();}
catch(IOException e)
{}
}
public boolean save()
{
int i=0,start1=0,start2=0;
String temp="";
if (!flag)
{
getByte();
flag=true;
}
try
{
temp=new String(b,"ISO8859_1");
}
catch(UnsupportedEncodingException e)
{return(false);}
start1=temp.indexOf("image/");
temp=temp.substring(start1);
start1=temp.indexOf("\r\n\r\n");
temp=temp.substring(start1+4);
start2=temp.indexOf(";\r\n");
if (start2!=-1)
{
temp=temp.substring(0,start2);
}
try
{
byte[] img=temp.getBytes("ISO8859_1");
for (i=0;i<img.length;i++)
{ os.write(img[i]); }
os.close();
}
catch(IOException e)
{return(false);}
return(true);
}
}
How to Read the Value of an HTTP Header
In the above sections, we have gone through several HTTP headers that are useful for user agent detection and device capabilities detection. Now one essential question remains: how to read the value of an HTTP header?
Reading the value of an HTTP header is not difficult. Just use a server-side scripting technology to write a few lines of code. We will demonstrate how to read the value of an HTTP header using ASP, Java Servlet / JSP, Perl and PHP below.
Retrieving HTTP Headers with ASP
In ASP, you can use the ServerVariables collection of the Request object to retrieve the value of HTTP headers. You can choose either VBScript or JScript (JavaScript implemented by Microsoft) as the scripting language. If you use VBScript, the code for reading HTTP headers should be like this:
' Declaring variables
Dim accept
Dim user_agent
Dim accept_charset
Dim accept_language
Dim x_wap_profile
Dim profile
accept = Request.ServerVariables("HTTP_ACCEPT")
user_agent = Request.ServerVariables("HTTP_USER_AGENT")
accept_charset = Request.ServerVariables("HTTP_ACCEPT_CHARSET")
accept_language = Request.ServerVariables("HTTP_ACCEPT_LANGUAGE")
x_wap_profile = Request.ServerVariables("HTTP_X_WAP_PROFILE")
profile = Request.ServerVariables("HTTP_PROFILE")
As you can see above, to retrieve the value of an HTTP header in ASP, we use Request.ServerVariables("HTTP_x"), where x is the HTTP header name with all the "-" characters replaced with the "_" character. ASP has other pre-defined server environment variables that can be placed inside the parentheses of ServerVariables() but we are not going to discuss about them since they are not useful to us here.
If you use JScript, the code for reading HTTP headers should look like this:
var accept = Request.ServerVariables("HTTP_ACCEPT");
var user_agent = Request.ServerVariables("HTTP_USER_AGENT");
var accept_charset = Request.ServerVariables("HTTP_ACCEPT_CHARSET");
var accept_language = Request.ServerVariables("HTTP_ACCEPT_LANGUAGE");
var x_wap_profile = Request.ServerVariables("HTTP_X_WAP_PROFILE");
var profile = Request.ServerVariables("HTTP_PROFILE");
Retrieving HTTP Headers with Java Servlet / JSP
In Java Servlet or JSP, you can use the getHeader() method of the javax.servlet.http.HttpServletRequest object to retrieve the value of HTTP headers. Here is the code for reading HTTP headers:
String accept = request.getHeader("accept");
String user_agent = request.getHeader("user-agent");
String accept_charset = request.getHeader("accept-charset");
String accept_language = request.getHeader("accept-language");
String x_wap_profile = request.getHeader("x-wap-profile");
String profile = request.getHeader("profile");
As you can see, to retrieve the value of an HTTP header whose name is x in Java Servlet or JSP, we use request.getHeader("x"), where request is an instance of the javax.servlet.http.HttpServletRequest class.
Retrieving HTTP Headers with Perl
In Perl, the values of HTTP headers are stored in the %ENV hash. Here is the code for retrieving HTTP headers:
$accept = $ENV{"HTTP_ACCEPT"};
$user_agent = $ENV{"HTTP_USER_AGENT"};
$accept_charset = $ENV{"HTTP_ACCEPT_CHARSET"};
$accept_language = $ENV{"HTTP_ACCEPT_LANGUAGE"};
$x_wap_profile = $ENV{"HTTP_X_WAP_PROFILE"};
$profile = $ENV{"HTTP_PROFILE"};
As you can see above, to retrieve the value of an HTTP header in Perl, we use $ENV{"HTTP_x"}, where x is the HTTP header name with all the "-" characters replaced with the "_" character. Perl has other pre-defined values that can be placed inside the braces of $ENV{} but we are not going to discuss about them since they are not useful to us here.
Retrieving HTTP Headers with PHP
In PHP, the value of HTTP headers are stored in the $_SERVER array. Here is the code for retrieving HTTP headers:
$accept = $_SERVER["HTTP_ACCEPT"];
$user_agent = $_SERVER["HTTP_USER_AGENT"];
$accept_charset = $_SERVER["HTTP_ACCEPT_CHARSET"];
$accept_language = $_SERVER["HTTP_ACCEPT_LANGUAGE"];
$x_wap_profile = $_SERVER["HTTP_X_WAP_PROFILE"];
$profile = $_SERVER["HTTP_PROFILE"];
As you can see above, to retrieve the value of an HTTP header in PHP, we use $_SERVER["HTTP_x"], where x is the HTTP header name with all the "-" characters replaced with the "_" character. PHP has other pre-defined values that can be placed inside the square brackets of $_SERVER[] but we are not going to discuss about them since they are not useful to us here