初學jsp心得 - 中國WEB開發者網絡 (http://www.webasp.net) -- 技術教程 (http://www.webasp.net/article/) --- 初學jsp心得 (http://www.webasp.net/article/18/17011.htm) |
| -- 作者:未知 -- 發佈日期: 2005-03-15 |
|
測試環境為 jdk1.2.2 jswdk-1.0 winnt4.0中文版。 1。java是大小寫敏感的,用過其他編程語言的人最容易犯這個錯誤,尤其是剛上手的時候。我剛開始調試jsp的時50%以上的編譯錯誤是都是因為這個。 2。java的調用過程都是要加括號的,一開始比較容易忽視,如title=request.getParameter(\"title\").trim(); 3。jsp中對應asp中的request.form()和request.querystring()的解決方法。 jsp中取得參數沒有form和queryString之分,都是通過request.getParameter(\"XXXX\")來取得。雖然jsp也有request.getQueryString()方法,但測試結果是 test.jsp?id=1&page=20 得到 id=1&page=20。 如果url和form有相同的參數名稱呢?下面是一段測試代碼: <form method=\"POST\" action=\"query.jsp?id=2\"> <input type=\"text\" name=\"id\" value=\"1\" size=\"60\"> </form> name都是id,結果是url的參數優先得到,jsp的這種處理方式和asp相比我覺的各有所長。 4。頭疼的漢字處理問題。 在其他的文章裡曾說到在中文NT環境下如下語句輸出會得到亂碼, <%=\"你好\"%> 及 out.print(\"你好\");等。解決方法是只要對字符串變量進行編碼就可以得到正確結果,如下代碼可以得到正確的輸出: <% String title=\"你好\"; byte[] tmpbyte=title.getBytes(\"ISO8859_1\"); title=new String(tmpbyte); out.print(title); %> 或者<%=title%> 關於sql語句漢字問題,例句為 select * from test where title='誰是傻瓜' 在jdbc-odbc驅動下連db2,不管是原句還是對sql語句進行編碼後都死活通不過。 換了ibm的jdbc直接驅動後,對sql語句編碼後程序可以通過。 這個問題的產生大概是中文NT的原因,在其他環境下可能就沒漢字處理問題了,據說ibm的web sphere對中文支持的很好,這也給jsp的開發帶來一定的通用性問題。據說對字符串編碼是一種通用的解決方法,不過沒有這麼多環境來測試。 5。在asp中經常使用到字符串判斷語句如 if state=\"真是傻瓜\" then..... 在java中String變量不是一個簡單的變量而是一個類實例,不同的方法會得到不同的結果 a. String str1=\"我是傻瓜\"; String str2=\"我是傻瓜\"; (or String str2=\"我是\"+\"傻瓜\"; ) if (str1==str2) out.print(\"yes\"); else out.print(\"no\"); 結果是\"yes\"。 大概是編譯優化,str1,str2指向同一個類實例; b. String str1,str2,str3; str1=\"我是傻瓜\"; str2=\"我是\"; str3=str2+\"傻瓜\"; if (str1==str3) out.print(\"yes\"); else out.print(\"no\"); 結果是\"no\"。 String str1=new String(\"我是傻瓜\"); String str2=new String(\"我是傻瓜\"); if (str1==str2) out.print(\"yes\"); else out.print(\"no\"); 結果是\"no\"。 String str1=new String(\"我是傻瓜\"); String str2=new String(\"我是傻瓜\"); if (str1.compareTo(str2)==0) out.print(\"yes\"); else out.print(\"no\"); 結果是\"yes\"。 所以在jsp中判斷字符串要使用compareTo方法,用慣傳統語言還真一下子適應不過來,熟悉java的朋友應該沒這個問題。 6。如何判斷數據庫為空? result = stmt.executeQuery(sql); if (result.next()) ...... result執行後游標出於一個未明的狀態,不能進行狀態判斷,也不能取值,一定要next()一下才可以用。 7。在jsp中實現分頁。 page是關鍵字,不能當變量。 conn.jsp <% String sDBDriver = \"COM.ibm.db2.jdbc.app.DB2Driver\"; String sConnStr = \"jdbc:db2:faq\"; Connection conn = null; Statement stmt = null; ResultSet rs=null; try { Class.forName(sDBDriver); } catch(java.lang.ClassNotFoundException e) { out.print(\"faq(): \" + e.getMessage()); } try{ conn = DriverManager.getConnection(sConnStr,\"wsdemo\",\"wsdemo1\"); stmt = conn.createStatement(); }catch(SQLException e){ out.print(e.toString()); } %> query.jsp <%@ page language=\"java\" import=\"java.sql.*\" %> <%@ page contentType=\"text/html; charset=gb2312\" %> <%@ include file=\"conn.jsp\" %> <% ....... int pages=0; int pagesize=10; ResultSet result = null; ResultSet rcount = null; pages = new Integer(request.getParameter(\"pages\")).intValue(); if (pages>0) { String sql=\" state='我不傻'\"; int count=0; try { rcount = stmt.executeQuery(\"SELECT count(id) as id from user where \"+sql); catch(SQLException ex) { out.print(\"aq.executeQuery: \" + ex.getMessage()); } if(rcount.next()) count = rcount.getInt(\"id\"); rcount.close(); if (count>0) { sql=\"select * from user where \"+sql; try { result = stmt.executeQuery(sql); } catch(SQLException ex) { out.print(\"aq.executeQuery: \" + ex.getMessage()); } int i; String name; // result.first(); // result.absolute((pages-1)*pagesize); // 此方法jdbc2.0支持。編譯通過,但執行不過,不知是不是跟驅動有關,只好用下面的笨辦法。 for(i=1;i<=(pages-1)*pagesize;i++) result.next(); for(i=1;i<=pagesize;i++) { if (result.next()) { name=result.getString(\"name\"); out.print(name); } result.close(); int n= (int)(count/pagesize); if (n*pagesize<count) n++; if (n>1) { for(i=1;i<=n;i++) out.print(\"<a href=query.jsp?pages=\"+i+\">\"+i+\" </a>\"); } } } %> 數據庫怎麼連接,怎麼老出錯啊?所以我集中的在這寫篇文章供大家參考,其實這種把數據庫邏輯全部放在jsp裡未必是好的做法,但是有利於初學者學習,所以我就這樣做了,當大家學到一定程度的時候,可以考慮用MVC的模式開發。在練習這些代碼的時候,你一定將jdbc的驅動程序放到服務器的類路徑裡,然後要在數據庫裡建一個表test,有兩個字段比如為test1,test2,可以用下面SQL建 create table test(test1 varchar(20),test2 varchar(20) 然後向這個表寫入一條測試紀錄 那麼現在開始我們的jsp和數據庫之旅吧。 一、jsp連接Oracle8/8i/9i數據庫(用thin模式) testoracle.jsp如下: <%@ page contentType="text/html;charset=gb2312"%> <%@ page import="java.sql.*"%> <html> <body> <%Class.forName("oracle.jdbc.driver.OracleDriver").newInstance(); String url="jdbc:oracle:thin:@localhost:1521:orcl"; //orcl為你的數據庫的SID String user="scott"; String password="tiger"; Connection conn= DriverManager.getConnection(url,user,password); Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE); String sql="select * from test"; ResultSet rs=stmt.executeQuery(sql); while(rs.next()) {%> 您的第一字段內容為:<%=rs.getString(1)%> 您的第二個字段內容為:<%=rs.getString(2)%> <%}%> <%out.print("數據庫操作成功,恭喜你");%> <%rs.close(); stmt.close(); conn.close(); %> </body> </html> 二、jsp連接Sql Server7.0/2000數據庫 testsqlserver.jsp如下: <%@ page contentType="text/html;charset=gb2312"%> <%@ page import="java.sql.*"%> <html> <body> <%Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance(); String url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=pubs"; //pubs為你的數據庫的 String user="sa"; String password=""; Connection conn= DriverManager.getConnection(url,user,password); Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE); String sql="select * from test"; ResultSet rs=stmt.executeQuery(sql); while(rs.next()) {%> 您的第一個字段內容為:<%=rs.getString(1)%> 您的第二個字段內容為:<%=rs.getString(2)%> <%}%> <%out.print("數據庫操作成功,恭喜你");%> <%rs.close(); stmt.close(); conn.close(); %> </body> </html> 三、jsp連接DB2數據庫 testdb2.jsp如下: <%@ page contentType="text/html;charset=gb2312"%> <%@ page import="java.sql.*"%> <html> <body> <%Class.forName("com.ibm.db2.jdbc.app.DB2Driver ").newInstance(); String url="jdbc:db2://localhost:5000/sample"; //sample為你的數據庫名 String user="admin"; String password=""; Connection conn= DriverManager.getConnection(url,user,password); Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE); String sql="select * from test"; ResultSet rs=stmt.executeQuery(sql); while(rs.next()) {%> 您的第一個字段內容為:<%=rs.getString(1)%> 您的第二個字段內容為:<%=rs.getString(2)%> <%}%> <%out.print("數據庫操作成功,恭喜你");%> <%rs.close(); stmt.close(); conn.close(); %> </body> </html> 四、jsp連接Informix數據庫 testinformix.jsp如下: <%@ page contentType="text/html;charset=gb2312"%> <%@ page import="java.sql.*"%> <html> <body> <%Class.forName("com.informix.jdbc.IfxDriver").newInstance(); String url = "jdbc:informix-sqli://123.45.67.89:1533/testDB:INFORMIXSERVER=myserver; user=testuser;password=testpassword"; //testDB為你的數據庫名 Connection conn= DriverManager.getConnection(url); Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE); String sql="select * from test"; ResultSet rs=stmt.executeQuery(sql); while(rs.next()) {%> 您的第一個字段內容為:<%=rs.getString(1)%> 您的第二個字段內容為:<%=rs.getString(2)%> <%}%> <%out.print("數據庫操作成功,恭喜你");%> <%rs.close(); stmt.close(); conn.close(); %> </body> </html> 五、jsp連接Sybase數據庫 testmysql.jsp如下: <%@ page contentType="text/html;charset=gb2312"%> <%@ page import="java.sql.*"%> <html> <body> <%Class.forName("com.sybase.jdbc.SybDriver").newInstance(); String url =" jdbc:sybase:Tds:localhost:5007/tsdata"; //tsdata為你的數據庫名 Properties sysProps = System.getProperties(); SysProps.put("user","userid"); SysProps.put("password","user_password"); Connection conn= DriverManager.getConnection(url, SysProps); Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE); String sql="select * from test"; ResultSet rs=stmt.executeQuery(sql); while(rs.next()) {%> 您的第一個字段內容為:<%=rs.getString(1)%> 您的第二個字段內容為:<%=rs.getString(2)%> <%}%> <%out.print("數據庫操作成功,恭喜你");%> <%rs.close(); stmt.close(); conn.close(); %> </body> </html> 六、jsp連接MySQL數據庫 testmysql.jsp如下: <%@ page contentType="text/html;charset=gb2312"%> <%@ page import="java.sql.*"%> <html> <body> <%Class.forName("org.gjt.mm.mysql.Driver").newInstance(); String url ="jdbc:mysql://localhost/softforum?user=soft&password=soft1234&useUnicode=true&characterEncoding=8859_1" //testDB為你的數據庫名 Connection conn= DriverManager.getConnection(url); Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE); String sql="select * from test"; ResultSet rs=stmt.executeQuery(sql); while(rs.next()) {%> 您的第一個字段內容為:<%=rs.getString(1)%> 您的第二個字段內容為:<%=rs.getString(2)%> <%}%> <%out.print("數據庫操作成功,恭喜你");%> <%rs.close(); stmt.close(); conn.close(); %> </body> </html> 七、jsp連接PostgreSQL數據庫 testmysql.jsp如下: <%@ page contentType="text/html;charset=gb2312"%> <%@ page import="java.sql.*"%> <html> <body> <%Class.forName("org.postgresql.Driver").newInstance(); String url ="jdbc:postgresql://localhost/soft" //soft為你的數據庫名 String user="myuser"; String password="mypassword"; Connection conn= DriverManager.getConnection(url,user,password); Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE); String sql="select * from test"; ResultSet rs=stmt.executeQuery(sql); while(rs.next()) {%> 您的第一個字段內容為:<%=rs.getString(1)%> 您的第二個字段內容為:<%=rs.getString(2)%> <%}%> <%out.print("數據庫操作成功,恭喜你");%> <%rs.close(); stmt.close(); conn.close(); %> </body> </html> 在jsp中使用smartupload組件上傳文件 jsp對上傳文件的支持不像php中支持的那麼好,直接做成了函數,也不像asp中要通過組件才能實現。jsp中可以通過javabean來實現。但是我們沒有必要自己去寫一個上載的bean,在網上已經有了很多成型的技術,smartupload就是其中的一個。但是smartupload是將文件先讀到服務器的內存中,所以上傳太大的文件(超過100兆)有可能會出問題,也算是一個美中不足吧:) 先說一下提交的頁面,smartupload組件要求用字節流的方式來提交<FORM action="upload.jsp" encType=multipart/form-data method=post>。下面就是個例子upload.htm: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <!-- saved from url=(0057)http://localhost:8080/jspsmartfile/jsp/uploadTemplate.jsp --> <HTML><HEAD> <META content="text/html; charset=gb2312" http-equiv=Content-Type> <META content="MSHTML 5.00.2920.0" name=GENERATOR></HEAD> <BODY bgColor=#e6e6e6><BR> <FORM action="upload.jsp" encType=multipart/form-data method=post> <TABLE> <TBODY> <TR> <TD><FONT color=#000000 face=helv,helvetica size=1> File : </FONT> <INPUT size=60 type=file name="file"></TD></TR> <TR> <TR> <TD><FONT color=#000000 face=helv,helvetica size=1> File : </FONT> <INPUT size=60 type=file name="file1"></TD></TR> <TR> <TD><FONT color=#000000 face=helv,helvetica size=1> File : </FONT> <INPUT size=60 type=text name="text"></TD></TR> <TR> <TD align=right><INPUT type=submit value=Send name="send"></TD></TR></TBODY></TABLE></FORM></BODY></HTML> 再來看一下接收的頁面 ,我們把文件上傳到服務器以後就直接把它再存入數據庫中:upload.jsp <%@ page contentType="text/hml;charset=gb2312"%> <%@ page import="java.sql.*"%> <%@ page import="com.jspsmart.upload.*" %> <%@ page import="DBstep.iDBManager2000.*"%> <% //實例化上載bean com.jspsmart.upload.SmartUpload mySmartUpload=new com.jspsmart.upload.SmartUpload(); //初始化 mySmartUpload.initialize(pageContext); //設置上載的最大值 mySmartUpload.setMaxFileSize(500 * 1024*1024); //上載文件 mySmartUpload.upload(); //循環取得所有上載的文件 for (int i=0;i<mySmartUpload.getFiles().getCount();i++){ //取得上載的文件 com.jspsmart.upload.File myFile = mySmartUpload.getFiles().getFile(i); if (!myFile.isMissing()) { //取得上載的文件的文件名 String myFileName=myFile.getFileName(); //取得不帶後綴的文件名 String suffix=myFileName.substring(0,myFileName.lastIndexOf('.')); //取得後綴名 String ext= mySmartUpload.getFiles().getFile(0).getFileExt(); //取得文件的大小 int fileSize=myFile.getSize(); //保存路徑 String aa=getServletContext().getRealPath("/")+"jsp\\"; String trace=aa+myFileName; //取得別的參數 String explain=(String)mySmartUpload.getRequest().getParameter("text"); String send=(String)mySmartUpload.getRequest().getParameter("send"); //將文件保存在服務器端 myFile.saveAs(trace,mySmartUpload.SAVE_PHYSICAL); //下面的是將上載的文件保存到數據庫中 //將文件讀到流中 java.io.File file = new java.io.File(trace); java.io.FileInputStream fis = new java.io.FileInputStream(file); out.println(file.length()); //打開數據庫 ResultSet result=null; String mSql=null; PreparedStatement prestmt=null; DBstep.iDBManager2000 DbaObj=new DBstep.iDBManager2000(); DbaObj.OpenConnection(); //將文件寫到數據庫中 mSql="insert into marklist (markname,password,marksize,markdate,MarkBody) values (?,?,?,?,?)"; prestmt =DbaObj.Conn.prepareStatement(mSql); prestmt.setString(1, "aaa1"); prestmt.setString(2, "0000"); prestmt.setInt(3, fileSize); prestmt.setString(4, DbaObj.GetDateTime()); prestmt.setBinaryStream(5,fis,(int)file.length()); DbaObj.Conn.setAutoCommit(true) ; prestmt.executeUpdate(); DbaObj.Conn.commit(); out.println(("上載成功!!!").toString()); } else { out.println(("上載失敗!!!").toString()); } }//與前面的if對應 %> 再說一下下載,下載分兩種情況1。從數據庫直接下載2。從服務器上下載 先說從數據庫直接下載的情形:就是把輸入流從數據庫裡讀出來,然後轉存為文件 <%@ page contentType="text/html; charset=gb2312" %> <%@ page import="java.sql.*"%> <%@ page import="java.io.*" %> <%@ page import="DBstep.iDBManager2000.*"%> <% int bytesum=0; int byteread=0; //打開數據庫 ResultSet result=null; String Sql=null; PreparedStatement prestmt=null; DBstep.iDBManager2000 DbaObj=new DBstep.iDBManager2000(); DbaObj.OpenConnection(); //取得數據庫中的數據 Sql="select * from t_local_zhongzhuan "; result=DbaObj.ExecuteQuery(Sql); result.next(); //將數據庫中的數據讀到流中 InputStream inStream=result.getBinaryStream("content"); FileOutputStream fs=new FileOutputStream( "c:/dffdsafd.doc"); byte[] buffer =new byte[1444]; int length; while ((byteread=inStream.read(buffer))!=-1) { out.println("<DT><B>"+byteread+"</B></DT>"); bytesum+=byteread; System.out.println(bytesum); fs.write(buffer,0,byteread); } %> 再說從服務器上下載的情形: <%@ page contentType="text/html; charset=gb2312" %> <%@ page import="java.io.*" %> <% String fileName = "zsc104.swf".toString(); f//讀到流中 InputStream inStream=new FileInputStream("c:/zsc104.swf"); //設置輸出的格式 response.reset(); response.setContentType("bin"); response.addHeader("Content-Disposition","attachment; filename=\"" + fileName + "\""); //循環取出流中的數據 byte[] b = new byte[100]; int len; while((len=inStream.read(b)) >0) response.getOutputStream().write(b,0,len); inStream.close(); %> 好了,到這裡只要不是太大的文件的上傳下載的操作都可以完成了。 縮略圖實現,將圖片(jpg,gif,bmp等等)真實的變成想要的大小 import java.io.*; import java.util.*; import com.sun.image.codec.jpeg.*; import java.awt.image.*; import java.awt.*; import java.net.*; import java.applet.*; import java.sql.*; //縮略圖類, //本java類能將jpg圖片文件,進行等比或非等比的大小轉換。 //具體使用方法 //s_pic(大圖片路徑,生成小圖片路徑,大圖片文件名,生成小圖片文名,生成小圖片寬度,生成小圖片高度,是否等比縮放(默認為true)) public class Small_pic{ String InputDir; //輸入圖路徑 String OutputDir; //輸出圖路徑 String InputFileName; //輸入圖文件名 String OutputFileName; //輸出圖文件名 int OutputWidth=80; //默認輸出圖片寬 int OutputHeight=80; //默認輸出圖片高 int rate=0; boolean proportion=true; //是否等比縮放標記(默認為等比縮放) public Small_pic(){ //初始化變量 InputDir=""; OutputDir=""; InputFileName=""; OutputFileName=""; OutputWidth=80; OutputHeight=80; rate=0; } public void setInputDir(String InputDir){ this.InputDir=InputDir; } public void setOutputDir(String OutputDir){ this.OutputDir=OutputDir; } public void setInputFileName(String InputFileName){ this.InputFileName=InputFileName; } public void setOutputFileName(String OutputFileName){ this.OutputFileName=OutputFileName; } public void setOutputWidth(int OutputWidth){ this.OutputWidth=OutputWidth; } public void setOutputHeight(int OutputHeight){ this.OutputHeight=OutputHeight; } public void setW_H(int width,int height){ this.OutputWidth=width; this.OutputHeight=height; } public String s_pic(){ BufferedImage image; String NewFileName; //建立輸出文件對像 File file = new File(OutputDir+OutputFileName); FileOutputStream tempout =null; try{ tempout= new FileOutputStream(file); }catch(Exception ex){ System.out.println(ex.toString()); } Image img=null; Toolkit tk=Toolkit.getDefaultToolkit(); Applet app=new Applet(); MediaTracker mt = new MediaTracker(app); try { img=tk.getImage(InputDir+InputFileName); mt.addImage(img, 0); mt.waitForID(0); }catch(Exception e) { e.printStackTrace(); } if(img.getWidth(null)==-1){ System.out.println(" can't read,retry!"+"<BR>"); return "no"; }else{ int new_w; int new_h; if (this.proportion==true) //判斷是否是等比縮放. { //為等比縮放計算輸出的圖片寬度及高度 double rate1=((double)img.getWidth(null))/(double)OutputWidth+0.1; double rate2=((double)img.getHeight(null))/(double)OutputHeight+0.1; double rate=rate1>rate2?rate1:rate2; new_w=(int)(((double)img.getWidth(null))/rate); new_h=(int)(((double)img.getHeight(null))/rate); } else{ new_w=OutputWidth; //輸出的圖片寬度 new_h=OutputHeight; //輸出的圖片高度 } BufferedImage buffImg = new BufferedImage(new_w,new_h,BufferedImage.TYPE_INT_RGB); Graphics g = buffImg.createGraphics(); g.setColor(Color.white); g.fillRect(0,0,new_w,new_h); g.drawImage(img,0,0,new_w,new_h,null); g.dispose(); JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(tempout); try{ encoder.encode(buffImg); tempout.close(); }catch(IOException ex){ System.out.println(ex.toString()); } } return "ok"; } public String s_pic(String InputDir,String OutputDir,String InputFileName,String OutputFileName){ //輸入圖路徑 this.InputDir=InputDir; //輸出圖路徑 this.OutputDir=OutputDir; //輸入圖文件名 this.InputFileName=InputFileName; //輸出圖文件名 this.OutputFileName=OutputFileName; return s_pic(); } public String s_pic(String InputDir,String OutputDir,String InputFileName,String OutputFileName,int width,int height,boolean gp){ //輸入圖路徑 this.InputDir=InputDir; //輸出圖路徑 this.OutputDir=OutputDir; //輸入圖文件名 this.InputFileName=InputFileName; //輸出圖文件名 this.OutputFileName=OutputFileName //設置圖片長寬 setW_H(width,height); //是否是等比縮放 標記 this.proportion=gp; return s_pic(); } public static void main(String [] a) { //s_pic(大圖片路徑,生成小圖片路徑,大圖片文件名,生成小圖片文名,生成小圖片寬度,生成小圖片高度) Small_pic mypic =new Small_pic(); System.out.println( mypic.s_pic("E:\\JAVA\\J2EEDatum\\王亮jsp資料\\縮圖例子\\personal\\", "E:\\JAVA\\J2EEDatum\\酒劍仙jsp資料\\縮圖例子\\personal\\", "1.jpg","new1.jpg",80,80,true) ); } 在JSP中使用JavaMail Java中文站 你希望在jsp中建立一個郵件發送收取工具嗎?下面將介紹的就是在jsp中建立一個郵件發送收取工具。在這篇文章中你可以瞭解到JavaMail API的一些要點以及如何在JSP中使用它。本文中還包括了在JSP中使用JavaMail的實例。JavaMail是JSP應用軟件中相當強大的API。 閱讀這篇文章需要對JSP、JavaBeans和JavaMail有一定的初步瞭解。當然,有關於JavaMail的知識你可以通過閱讀這篇文章來獲得。如果你對於以上三項一無所知,但你所使用的服務器支持JSP和JavaMail的話,你可以僅僅通過複製/粘貼來使用它們。 什麼是JavaMail JavaMail是Sun發佈的用來處理email的API。它可以方便地執行一些常用的郵件傳輸。 雖然JavaMail是Sun的API之一,但它目前還沒有被加在標準的java開發工具包中(Java Development Kit),這就意味著你在使用前必須另外下載JavaMail文件。除此以外,你還需要有Sun的JavaBeans Activation Framework (JAF)。JavaBeans Activation Framework的運行很複雜,在這裡簡單的說就是JavaMail的運行必須得依賴於它的支持。在Windows 2000下使用需要指定這些文件的路徑,在其它的操作系統上也類似。 接下來要講解的是這篇指南的最難理解的部分。 這篇指南包括三部分:HTML表格、關於JavaMail、JavaMail和JSP的結合。 第一部分:HTML表格 第一部分提供了一個最基本的基於HTML的email發送收取程序的例子。第二部分則講述JavaMail的工作原理。第三部分則介紹將JavaMail加入JSP,創建一個基本的email發送收取程序。 劃分組件 JSP最重要的特性是能將整個網頁劃分成一些細小的組件。這裡使用的組件包括: ●一個用來將email的信息發送給JSP的HTML表格; ●一個JSP頁面用來處理和發送信件。 第一步,就是創建一個HTML表格用來給JSP頁面發送信息。你可以將以下的HTML代碼複製到你的電腦上: 用來發送email的HTML源代碼 <HTML> <BODY> <FORM action="sendmail.jsp" method="post"> <TABLE align="center"> <TR> <TD width="50%"> To:<BR><INPUT name="to" size="25"> </TD> <TD width="50%"> From:<BR><INPUT name="from" size="25"> </TD> </TR> <TR> <TD colspan="2"> Subject:<BR><INPUT name="subject" size="50"> </TD> </TR> <TR> <TD colspan="2"> <P>Message:<BR><TEXTAREA name="text" rows=25 cols=85></TEXTAREA></P> </TD> </TR> </TABLE> <INPUT type="submit" name="cb_submit" value=" Send "> <INPUT type="reset" name="cb_reset" value=" Clear "> </FORM> </BODY> </HTML> 以上這段程序將創建一個包含email基本信息(例如:收件地址、發送地址、主題和內容)的文件。當然你可以根據你自己的需要來決定這個文件包含那些信息。 這個HTML文件的使用有兩點要求:第一點是生成的文件必須發送給接下來將介紹的程序使用。在這個例子中就是sendmail.jsp,但在你使用時,必須用這個文件在系統裡的URL來代替它;第二點是必須有空間來允許用戶發送email。 第二部分將對JavaMail的特徵進行一些分析,為在第三部分創建JSP程序作準備。所以接下來我們將學習JavaMail。 第二部分:關於JavaMail 文檔的使用 下載的JavaMail API中帶的文檔是很有用的。你可以在JavaMail下的/docs/javadocs/index.html找到它。第二部分主要將分析郵件程序的組件。你可以通過閱讀文檔來獲得更多這方面的信息。 組件發送郵件需要使用JavaMail,它使對郵件的操作變得簡單易用。 屬性對像 JavaMail需要創建一個格式為"mail.smtp.host"的文件用來發送信息。 Properties props = new Properties (); props.put("mail.smtp.host", "smtp.jspinsider.com"); 對話對像 所有的基於JavaMail的程序都至少需要一個或全部的對話目標。 Session sendMailSession; sendMailSession = Session.getInstance(props, null); 傳輸 郵件的傳輸只有送出或受到兩種狀態。JavaMail將這兩種不同狀態描述為傳輸和儲存。傳輸將送出郵件,而儲存將收取郵件。 Transport transport; transport = sendMailSession.getTransport("smtp"); 使用JavaMail能為我們節約大量的時間。JavaMail能代替所有的SMTP的工作。 注意:JavaMail並不能完全的支持所有的郵件發送收取工作。它目前僅支持IMAP、SMTP和POP3,除此以外你只有等待新的JavaMail版本或自己開發協議。 信息對像 信息對像將把你所發送的郵件真實的反映出來。 Message newMessage = new MimeMessage(sendMailSession); 這就是我們所需要的全部四個對象。下一步將是如何將對像加入到JSP中。 第三部分:JavaMail和JSP的結合 創建JSP 下面我們將開始將他們結合在一起。最重要的一點是要確認根據頁面指示分類。還要記得在郵件上標注java.util.date。 <%@ page import= " javax.mail.*, javax.mail.internet.*, javax.activation.*, java.util.*" %> 其次,創建郵件發送的確認信息。確認信息可以是任意的,一般常用"你的郵件已經發送出去了(Your mail has been sent)。" 信息是如何創建和發送的 我們在第二部分裡已經討論過信息對象的創建。我們下面將對信息進行操作。這就和設置信息對象的屬性一樣簡單。你可以通過下面的程序來實現這項操作。 newMessage.setFrom(new InternetAddress(request.getParameter("from"))); newMessage.setRecipient(Message.RecipientType.TO, new InternetAddress(request.getParameter("to"))); newMessage.setSubject(request.getParameter("subject")); newMessage.setSentDate(new Date()); newMessage.setText(request.getParameter("text")); 現在將開始發送信息。通過JavaMail來實現它非常簡單。 transport.send(newMessage); 將所有的組件結合在一起 現在所有的組件都已經齊全了。現在將它們都放在JSP裡面。要注意每一個錯誤信息,並將它反饋給用戶。代碼如下,你可以通過複製它們直接使用: Sample JSP email Utility Using JavaMail <%@ page import=" javax.mail.*, javax.mail.internet.*, javax.activation.*,java.util.*" %> <html> <head> <TITLE>JSP meets JavaMail, what a sweet combo.</TITLE> </HEAD> <BODY> <% try{ Properties props = new Properties(); Session sendMailSession; Store store; Transport transport; sendMailSession = Session.getInstance(props, null); props.put("mail.smtp.host", "smtp.jspinsider.com"); Message newMessage = new MimeMessage(sendMailSession); newMessage.setFrom(new InternetAddress(request.getParameter("from"))); newMessage.setRecipient(Message.RecipientType.TO, new InternetAddress(request.getParameter("to"))); newMessage.setSubject(request.getParameter("subject")); newMessage.setSentDate(new Date()); newMessage.setText(request.getParameter("text")); transport = sendMailSession.getTransport("smtp"); transport.send(newMessage); %> <P>Your mail has been sent.</P> <% } catch(MessagingException m) { out.println(m.toString()); } %> </BODY> </HTML> 你會很快體會到JavaMail的方便之處,JSP和JavaMail將是未來的希望。 文件/圖片上傳 package uploadfile; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import java.io.FileOutputStream; import java.io.*; import java.util.Hashtable; import java.util.*; public class FileUploadBean { private String savePath=null; //文件上傳保存的路徑 private String contentType=""; //內容類型 private String charEncode=null; //字符編碼 private String bounary=""; //分界線 private String fileName=null; //本地文件名字 private Hashtable dic=new Hashtable(); //用於保存"元素名--元素值"對 private int totalSize=0; //上傳文件總大小 private String path=""; //保存文件的路徑 private String newFileName=""; //存入隨機產生的文件名 /////////////////////////////////////////////////// //設置文件上傳保存的路徑 public void setSavePath(String s) { s=path+s; savePath=s; System.out.println("上傳路徑:"+savePath); } /////////////////////////////////////////////////// //取文件上傳保存的路徑 public String getSavePath() { return savePath; } //////////////////////////////////////////////////// //設置文件名字,也可以為它命名,暫時先用它原來的名字 public void setFileName(String s) { int pos=s.indexOf("\"; filename=\""); if (pos>0) { s=s.substring(pos+13,s.length()-3); //去 " 和 crlf pos=s.lastIndexOf("\\"); if (pos<0) pos=s.lastIndexOf("/"); if (pos<0) fileName=s; fileName=s.substring(pos+1); } } //////////////////////////////////////////////////// //取得文件名 public String getFileName() { System.out.println("得到文件名"+newFileName); return newFileName; } /////////////////////////// //以時間為種子數產生新文件名 public String getNewFileName() { int pos=0; //.的位置 long seed=0; //隨機種子數 String ext=""; //存入文件擴展名 System.out.println("upload file name:"+fileName); pos=fileName.lastIndexOf("."); ext=fileName.substring(pos); //得到擴展名 seed=new Date().getTime(); Random rand=new Random(seed);//以時間為種子產生隨機數作為文件名 newFileName=Long.toString(Math.abs(rand.nextInt()))+ext; //生成文件名 System.out.println("new file name:"+newFileName); return newFileName; } ////////////////////////////////////////////////////// //設置字符的編碼方式 public void setCharEncode(HttpServletRequest req) { charEncode=req.getCharacterEncoding(); } ///////////////////////////////////////////////// //設置得ContentType public void setBoundary(HttpServletRequest req) { //傳遞的參數值類似"multipart/form-data; boundary=---------------------------7d21441a30013c" //傳過來的分界線比實際顯示在上傳數據中的要多兩個"--" boundary=req.getContentType(); //System.out.println("boundary"+boundary); int pos=boundary.indexOf("boundary="); //加上這兩個"--" boundary="--"+boundary.substring(pos+9); } //////////////////////////////////////////////////// //取得ContentType public String getBoundary(){ //返回值類似"-----------------------------7d21441a30013c" return boundary; } ///////////////////////////////////////////// //設置ContentType public void setContentType(String s) { int pos =s.indexOf(": "); if (pos!=-1) contentType=s.substring(pos+2); } //////////////////////////////////////////// //取得ContentType public String getContentType() { return contentType; } ///////////////////////////////////////////// //初始化 public void init(HttpServletRequest req) { setCharEncode(req); setBoundary(req); } //////////////////////////////////////////////////// //取哈希表中的數據 public String getFieldValue(String s) { String temp=""; if(dic.containsKey(s)) //判斷表中是否存在s鍵,不判斷則返回nullpointerException { temp=(String)dic.get(s); temp=temp.trim(); }else temp=""; return temp; } //////////////////////////////////////////////// ////用指定的編碼方式生成字符串 public String newLine(byte oneLine[],int sp,int i,String charEncode) throws java.io.UnsupportedEncodingException { sp=0; // start position String lineStr=null; if (charEncode!=null) { return lineStr=new String(oneLine,sp,i,charEncode); //用指定的編碼方式生成字符串 } else { return lineStr=new String(oneLine,sp,i); } } /////////////////////////////////////////////// //得到上傳文件的大小 public int getTotalSize() { return totalSize/1000; } /////////////////////////////////////// //刪除指定路徑的文件 public boolean delFiles(String fn) //fn為要刪除的文件名,不包括路徑 { try { File file=new File(savePath+fn); System.out.println(savePath+fn); if(file.exists()) { file.delete(); System.out.println(file.getPath()+"delete file successfully!"); return true; }else { System.out.println("the file is not existed!"); return true; } }catch(Exception e) { System.out.println(e.toString()); return false; } } //////////////////////////////////////////////// //文件列表 public String[] listFiles(String fp) { String[] lf=null; try{ savePath=path+fp; File file=new File(savePath); lf=file.list(new DirFilter()); for(int i=0;i<lf.length;i++) System.out.println(lf[i]); }catch(Exception e){ e.printStackTrace();} return lf; } ///////////////////////////////////////////////// //開始上傳文件 public boolean doUpload(HttpServletRequest req) throws java.io.IOException { String fieldValue=""; //表單元素值 String fieldName=""; //表單元名稱 int pos=-1; //臨時變量,用於記錄位置 int pos2=-1; //臨時變量,用於記錄位置 String lineStr=null; //用oneLine[]生成的每行字符串 byte oneLine[] =new byte[4096]; //用於每次讀取的數據 FileOutputStream fos=null; //文件輸出流 init(req); //初始化 ServletInputStream sis=req.getInputStream(); int i=sis.readLine(oneLine,0,oneLine.length); //返回實際讀取的字符數,並把數據寫到oneLine中 while (i!=-1) { lineStr=newLine(oneLine,0,i,charEncode); //生成字符串 if (lineStr.indexOf(getBoundary()+"--")>=0) break; if (lineStr.startsWith("Content-Disposition: form-data; name=\"")) { //分離數據,因為表單元素也一併上傳,還有其它數據,對我們有用的只是 //文件的內容,表單元素及表單元素對應的值 if (lineStr.indexOf("\"; filename=\"")>=0) { //是文件輸入域 //設置文件名 setFileName(lineStr); if (!fileName.equals("")) { //如果文件名為空則跳過 //提取表單元素名稱及表單元素對應的值 pos=lineStr.indexOf("name=\""); pos2=lineStr.indexOf("\"; filename=\""); //表單元素名字 fieldName=lineStr.substring(pos+6,pos2); //表單元素值 fieldValue=lineStr.substring(pos2+13,lineStr.length()-3); //加入哈希表中 dic.put(fieldName,fieldValue); sis.readLine(oneLine,0,oneLine.length); //讀取的數據類似"Content-Type: text/plain" sis.readLine(oneLine,0,oneLine.length); //空行 //建立文件輸出 fos=new FileOutputStream(new File(getSavePath(),getNewFileName())); //開始讀上傳文件數據 i=sis.readLine(oneLine,0,oneLine.length); while(i!=-1) { totalSize=i+totalSize; lineStr=newLine(oneLine,0,i,charEncode); if (lineStr.indexOf(getBoundary())>=0) break; //表明這個文件區的數據讀取完畢 fos.write(oneLine,0,i); i=sis.readLine(oneLine,0,oneLine.length); }//end while fos.close(); }//end if (!getFileName().equals("")) } else { //非文件輸入域 pos=lineStr.indexOf("name=\""); //表單元素名字 fieldName=lineStr.substring(pos+6,lineStr.length()-3); //讀空行 sis.readLine(oneLine,0,oneLine.length); //這行含有元素值,如裡元素值為空,則這行也是空行,也要讀的 String temp=""; i=sis.readLine(oneLine,0,oneLine.length); while(i!=-1) { temp=newLine(oneLine,0,i,charEncode); if (temp.indexOf(getBoundary())>=0) break; fieldValue=fieldValue+temp; i=sis.readLine(oneLine,0,oneLine.length); } //加入哈希表中 dic.put(fieldName,fieldValue); fieldValue=""; } } i=sis.readLine(oneLine,0,oneLine.length); }//end while sis.close(); return true; } //end doUpload ////////////////////////// //清空Hashtable public void clearDic() { dic.clear(); if (dic.isEmpty()) { System.out.println("empty"); } else { Sstem.out.println("not empty"); } } ////////////////////////////////// //測試用的主函數 public static void main(String args[]) { String[] fileList=null; try{ FileUploadBean fub=new FileUploadBean(); fileList=fub.listFiles("/avatars/"); for(int i=0;i<fileList.length;i++) System.out.println(fileList[i]); }catch(Exception e){ e.printStackTrace();} } } /////////////////////////////////// ////文件目錄過濾內部類 class DirFilter implements FilenameFilter { public boolean accept(File dir, String name) { //dir為目錄名,name 為包含路徑的文件名 File f = new File(dir,name); //生成文件對像 if(f.isDirectory()) return false; return true; } } 相關類說明篇 一 File類 這個類包裝了一個上傳文件的所有信息。通過它,可以得到上傳文件的文件名、文件大小、擴展名、文件數據等信息。 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表明以操作系統的根目錄為文件根目錄另存文件,SAVEAS_VIRTUAL表明以Web應用程序的根目錄為文件根目錄另存文件,SAVEAS_AUTO則表示讓組件決定,當Web應用程序的根目錄存在另存文件的目錄時,它會選擇SAVEAS_VIRTUAL,否則會選擇SAVEAS_PHYSICAL。 例如,saveAs("/upload/sample.zip",SAVEAS_PHYSICAL)執行後若Web服務器安裝在C盤,則另存的文件名實際是c:\upload\sample.zip。而saveAs("/upload/sample.zip",SAVEAS_VIRTUAL)執行後若Web應用程序的根目錄是webapps/jspsmartupload,則另存的文件名實際是webapps/jspsmartupload/upload/sample.zip。saveAs("/upload/sample.zip",SAVEAS_AUTO)執行時若Web應用程序根目錄下存在upload目錄,則其效果同saveAs("/upload/sample.zip",SAVEAS_VIRTUAL),否則同saveAs("/upload/sample.zip",SAVEAS_PHYSICAL)。 建議:對於Web程序的開發來說,最好使用SAVEAS_VIRTUAL,以便移植。 2、isMissing 作用:這個方法用於判斷用戶是否選擇了文件,也即對應的表單項是否有值。選擇了文件時,它返回false。未選文件時,它返回true。 原型:public boolean isMissing() 3、getFieldName 作用:取HTML表單中對應於此上傳文件的表單項的名字。 原型:public String getFieldName() 4、getFileName 作用:取文件名(不含目錄信息) 原型:public String getFileName() 5、getFilePathName 作用:取文件全名(帶目錄) 原型:public String getFilePathName 6、getFileExt 作用:取文件擴展名(後綴) 原型:public String getFileExt() 7、getSize 作用:取文件長度(以字節計) 原型:public int getSize() 8、getBinaryData 作用:取文件數據中指定位移處的一個字節,用於檢測文件等處理。 原型:public byte getBinaryData(int index)。其中,index表示位移,其值在0到getSize()-1之間。 二 Files類 這個類表示所有上傳文件的集合,通過它可以得到上傳文件的數目、大小等信息。有以下方法: 1、getCount 作用:取得上傳文件的數目。 原型:public int getCount() 2、getFile 作用:取得指定位移處的文件對像File(這是com.jspsmart.upload.File,不是java.io.File,注意區分)。 原型:public File getFile(int index)。其中,index為指定位移,其值在0到getCount()-1之間。 3、getSize 作用:取得上傳文件的總長度,可用於限制一次性上傳的數據量大小。 原型:public long getSize() 4、getCollection 作用:將所有上傳文件對像以Collection的形式返回,以便其它應用程序引用,瀏覽上傳文件信息。 原型:public Collection getCollection() 5、getEnumeration 作用:將所有上傳文件對像以Enumeration(枚舉)的形式返回,以便其它應用程序瀏覽上傳文件信息。 原型:public Enumeration getEnumeration() 三 Request類 這個類的功能等同於JSP內置的對象request。只所以提供這個類,是因為對於文件上傳表單,通過request對像無法獲得表單項的值,必須通過jspSmartUpload組件提供的Request對像來獲取。該類提供如下方法: 1、getParameter 作用:獲取指定參數之值。當參數不存在時,返回值為null。 原型:public String getParameter(String name)。其中,name為參數的名字。 2、getParameterValues 作用:當一個參數可以有多個值時,用此方法來取其值。它返回的是一個字符串數組。當參數不存在時,返回值為null。 原型:public String[] getParameterValues(String name)。其中,name為參數的名字。 3、getParameterNames 作用:取得Request對像中所有參數的名字,用於遍歷所有參數。它返回的是一個枚舉型的對象。 原型:public Enumeration getParameterNames() 四 SmartUpload類這個類完成上傳下載工作。 A.上傳與下載共用的方法: 只有一個:initialize。 作用:執行上傳下載的初始化工作,必須第一個執行。 原型:有多個,主要使用下面這個: public final void initialize(javax.servlet.jsp.PageContext pageContext) 其中,pageContext為JSP頁面內置對像(頁面上下文)。 B.上傳文件使用的方法: 1、upload 作用:上傳文件數據。對於上傳操作,第一步執行initialize方法,第二步就要執行這個方法。 原型:public void upload() 2、save 作用:將全部上傳文件保存到指定目錄下,並返回保存的文件個數。 原型:public int save(String destPathName) 和public int save(String destPathName,int option) 其中,destPathName為文件保存目錄,option為保存選項,它有三個值,分別是SAVE_PHYSICAL,SAVE_VIRTUAL和SAVE_AUTO。(同File類的saveAs方法的選項之值類似)SAVE_PHYSICAL指示組件將文件保存到以操作系統根目錄為文件根目錄的目錄下,SAVE_VIRTUAL指示組件將文件保存到以Web應用程序根目錄為文件根目錄的目錄下,而SAVE_AUTO則表示由組件自動選擇。 註:save(destPathName)作用等同於save(destPathName,SAVE_AUTO)。 3、getSize 作用:取上傳文件數據的總長度 原型:public int getSize() 4、getFiles 作用:取全部上傳文件,以Files對像形式返回,可以利用Files類的操作方法來獲得上傳文件的數目等信息。 原型:public Files getFiles() 5、getRequest 作用:取得Request對象,以便由此對像獲得上傳表單參數之值。 原型:public Request getRequest() 6、setAllowedFilesList 作用:設定允許上傳帶有指定擴展名的文件,當上傳過程中有文件名不允許時,組件將拋出異常。 原型:public void setAllowedFilesList(String allowedFilesList) 其中,allowedFilesList為允許上傳的文件擴展名列表,各個擴展名之間以逗號分隔。如果想允許上傳那些沒有擴展名的文件,可以用兩個逗號表示。例如:setAllowedFilesList("doc,txt,,")將允許上傳帶doc和txt擴展名的文件以及沒有擴展名的文件。 7、setDeniedFilesList 作用:用於限制上傳那些帶有指定擴展名的文件。若有文件擴展名被限制,則上傳時組件將拋出異常。 原型:public void setDeniedFilesList(String deniedFilesList) 其中,deniedFilesList為禁止上傳的文件擴展名列表,各個擴展名之間以逗號分隔。如果想禁止上傳那些沒有擴展名的文件,可以用兩個逗號來表示。例如:setDeniedFilesList("exe,bat,,")將禁止上傳帶exe和bat擴展名的文件以及沒有擴展名的文件。 8、setMaxFileSize 作用:設定每個文件允許上傳的最大長度。 原型:public void setMaxFileSize(long maxFileSize) 其中,maxFileSize為為每個文件允許上傳的最大長度,當文件超出此長度時,將不被上傳。 9、setTotalMaxFileSize 作用:設定允許上傳的文件的總長度,用於限制一次性上傳的數據量大小。 原型:public void setTotalMaxFileSize(long totalMaxFileSize) 其中,totalMaxFileSize為允許上傳的文件的總長度。 jsp 上傳圖片並生成縮位圖或者加水印 有些網站 動網, 上傳圖片後加給加上自己的字(是在圖片上加的) 請問在JSP裡如何實現?? //添加水印,filePath 源圖片路徑, watermark 水印圖片路徑 public static boolean createMark(String filePath,String watermark) { ImageIcon imgIcon=new ImageIcon(filePath); Image theImg =imgIcon.getImage(); ImageIcon waterIcon=new ImageIcon(watermark); Image waterImg =waterIcon.getImage(); int width=theImg.getWidth(null); int height= theImg.getHeight(null); BufferedImage bimage = new BufferedImage(width,height, BufferedImage.TYPE_INT_RGB); Graphics2D g=bimage.creatGraphics( ); g.setColor(Color.red); g.setBackground(Color.white); g.drawImage(theImg, 0, 0, null ); g.drawImage(waterImg, 100, 100, null ); g.drawString("12233",10,10); //添加文字 g.dispose(); try{ FileOutputStream out=new FileOutputStream(filePath); JPEGImageEncoder encoder =JPEGCodec.createJPEGEncoder(out); JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bimage); param.setQuality(50f, true); encoder.encode(bimage, param); out.close(); }catch(Exception e){ return false; } return true; } /////////////////範例//////////////////// package package; import java.io.*; import javax.servlet.ServletException; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; public class upload { private static String newline = "\n"; private String uploadDirectory; private String ContentType; private String CharacterEncoding; public upload() { uploadDirectory = "."; ContentType = ""; CharacterEncoding = ""; } private String getFileName(String s) { int i = s.lastIndexOf("\\"); if(i < 0 || i >= s.length() - 1) { i = s.lastIndexOf("/"); if(i < 0 || i >= s.length() - 1) return s; } return s.substring(i + 1); } public void setUploadDirectory(String s) { uploadDirectory = s; } public void setContentType(String s) { ContentType = s; int i; if((i = ContentType.indexOf("boundary=")) != -1) { ContentType = ContentType.substring(i + 9); ContentType = "--" + ContentType; } } public void setCharacterEncoding(String s) { CharacterEncoding = s; } public String uploadFile(HttpServletRequest httpservletrequest) throws ServletException, IOException { String s = null; setCharacterEncoding(httpservletrequest.getCharacterEncoding()); setContentType(httpservletrequest.getContentType()); s = uploadFile(httpservletrequest.getInputStream()); return s; } public String uploadFile(ServletInputStream servletinputstream) throws ServletException, IOException { String s = null; String s1 = null; byte abyte0[] = new byte[4096]; byte abyte1[] = new byte[4096]; int ai[] = new int[1]; int ai1[] = new int[1]; String s2; while((s2 = readLine(abyte0, ai, servletinputstream, CharacterEncoding)) != null) { int i = s2.indexOf("filename="); if(i >= 0) { s2 = s2.substring(i + 10); if((i = s2.indexOf("\"")) > 0) s2 = s2.substring(0, i); break; } } s1 = s2; if(s1 != null && !s1.equals("\"")) { s1 = getFileName(s1); String s3 = readLine(abyte0, ai, servletinputstream, CharacterEncoding); if(s3.indexOf("Content-Type") >= 0) readLine(abyte0, ai, servletinputstream, CharacterEncoding); File file = new File(uploadDirectory, s1); FileOutputStream fileoutputstream = new FileOutputStream(file); while((s3 = readLine(abyte0, ai, servletinputstream, CharacterEncoding)) != null) { if(s3.indexOf(ContentType) == 0 && abyte0[0] == 45) break; if(s != null) { fileoutputstream.write(abyte1, 0, ai1[0]); fileoutputstream.flush(); } s = readLine(abyte1, ai1, servletinputstream, CharacterEncoding); if(s == null || s.indexOf(ContentType) == 0 && abyte1[0] == 45) break; fileoutputstream.write(abyte0, 0, ai[0]); fileoutputstream.flush(); } byte byte0; if(newline.length() == 1) byte0 = 2; else byte0 = 1; if(s != null && abyte1[0] != 45 && ai1[0] > newline.length() * byte0) fileoutputstream.write(abyte1, 0, ai1[0] - newline.length() * byte0); if(s3 != null && abyte0[0] != 45 && ai[0] > newline.length() * byte0) fileoutputstream.write(abyte0, 0, ai[0] - newline.length() * byte0); fileoutputstream.close(); } return s1; } private String readLine(byte abyte0[], int ai[], ServletInputStream servletinputstream, String s) { ai[0] = servletinputstream.readLine(abyte0, 0, abyte0.length); if(ai[0] == -1) return null; break MISSING_BLOCK_LABEL_27; Object obj; obj; return null; if(s == null) return new String(abyte0, 0, ai[0]); return new String(abyte0, 0, ai[0], s); obj; return null; } } JSP頁: <%@page contentType="text/html;charset=gb2312" import="package.upload"%> <% String Dir = "c:\dir\upload"; String fn=""; upload upload = new upload(); upload.setUploadDirectory(Dir); fn=upload.uploadFile(request); %> 隨機圖片名稱 <% mySmartUpload.initialize(pageContext); mySmartUpload.service(request,response); mySmartUpload.upload(); String fn=mySmartUpload.getFiles().getFile(0).getFileName(); mySmartUpload.save("upload/"); //文件保存的目錄為upload out.println("已經成功上傳了文件,請查看<a href=upload/"+fn+">這裡</a>"); %> 上面的程序可以上傳圖片,不過只能上傳gif或者JPG圖片。 而且保存圖片在upload文件夾下面,要想GIF或Jpg圖片的名稱變為年+月+日+隨機數.gif或年+月+日+隨機數.jpg 只允許上傳jpg或gif圖片,在客戶端用javaScript控制要好些。 變圖片名稱可用如下代碼:自己看看就明白了。: //得到實際路徑 String realPath = this.masRequest.getRequest().getRealPath("/"); String userPhotoPath = realPath + "images\\UserPhoto\\"; userPhotoPath = MasString.replace(userPhotoPath,"\\","\\\\"); if (!file.getFileName().trim().equals("")) { //根據系統時間生成文件名 Date nowTime = new Date(); emp_Photo = userPhotoPath + String.valueOf(nowTime.getTime()) +"."+ file.getFileExt(); file.saveAs(emp_Photo); System.out.println("file.saveAs() = " + "OK!!!"); } |
| webasp.net |