JavaWeb-20
JAVAWEB-20:JDBC之文件上下傳與JavaMail
補充過濾器
<filter-mapping>可以加入<dispatcher>的配置
1、默認不寫:REQUEST
2、其他取值
a.ERROR:過濾web.xml中的錯誤頁
b.INCLUDE:動態包含的資源
c.FORWARD:轉發的資源
在過濾類型<filter-mapping>內加上標籤<dispatcher>
加上配置值。注意每一個配置值的作用
在index里加上跳轉標籤,跳轉到01.jsp
注意過濾器對01.jsp沒有進行攔截!!這是默認的狀態
如果想起作用,在<dispatcher>里加上FORWARD的屬性值。
在<dispatcher>里加上了INCLUDE的屬性後
使用include標籤演示,使用靜態包含的話,不會攔截
但是如果是動態包含的話就會攔截
在聲明頭加上errorPage加上屬性值01.jsp
如果在<dispatcher>上加上ERROR的話,那麼errorPage就不會走
如果想走,就配置FORWARD。
如果把errorPage刪去
而在xml里加上<error-page>,並在裏面加屬性<exception-type><location>等屬性,那麼可以配置FORWARD屬性來啓動這些標籤。
這些屬性都可以同時用。
一、文件上傳的原理及框架的引入
1、上傳的必要性:博客等例子
2、上傳的前提
1、enctype = "multipart/form-data"
2、method="post"
3、<input type = "file"/>
<form enctype="multipart/form-data" action="${pageContext.request.contextPath}/servlet/FileUploadServlet1" method="post">
靚照0:<input type="file" name="f1"><br>
靚照1:<input type="file" name="f2"><br><!--名稱可以相同-->
<input type="submit" value="上傳"><br>
</form>
以上是準備工作
嘗試上傳關鍵組件
1、環境編碼
2、獲取f1的值,嘗試打印發現什麼都沒有,null
爲什麼?注意getParameter只針對enctype裏的值:application/x-www-form-urlencoded
文件上傳的原理:利用Record來記錄上傳的內容 觀察:
Content-Type: multipart/form-data; boundary=---------------------------7de2192e140922
Accept-Encoding: gzip, deflate
Host: localhost:8080
Content-Length: 971
DNT: 1
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: JSESSIONID=D8C093F784D359A1395BF097CD6E8B9A
-----------------------------7de2192e140922
Content-Disposition: form-data; name="f1"; filename="oracleinfo.txt"
Content-Type: text/plain
Enterprise Manager Database Control URL - (orcl2) :http://wangli-PC:1158/em數據庫配置文件已經安裝到 D:\oracle\product\10.2.0,同時其他選定的安裝組件也已經安裝到 D:\oracle\product\10.2.0\db_3。iSQL*Plus URL 爲:http://wangli-PC:5560/isqlplusiSQL*Plus DBA URL 爲:http://wangli-PC:5560/isqlplus/dba
^list\[\d+\]\.name
-----------------------------7de2192e140922
Content-Disposition: form-data; name="f2"; filename="oracleinfo.txt"
Content-Type: text/plain
Enterprise Manager Database Control URL - (orcl2) :http://wangli-PC:1158/em數據庫配置文件已經安裝到 D:\oracle\product\10.2.0,同時其他選定的安裝組件也已經安裝到 D:\oracle\product\10.2.0\db_3。iSQL*Plus URL 爲:http://wangli-PC:5560/isqlplusiSQL*Plus DBA URL 爲:http://wangli-PC:5560/isqlplus/dba
^list\[\d+\]\.name
-----------------------------7de2192e140922--
通過邊界-----------------------------7de2192e140922--來把上傳的文件給隔開。
文件上傳原理
InputStream is = request.getInputStream();
byte []buffer = new byte[1024];
int len=-1;
while((len=is.read(buffer))!=-1){
System.out.println(new String(buffer,0,len));
}
實驗:項目:day2001fileupload1
項目架構:
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="http://blog.163.com/faith_yee/blog/<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="http://blog.163.com/faith_yee/blog/styles.css">
-->
</head>
<!-- 文件上傳的三個前提條件:
1.enctype="multipart/form-data"
2.method="post"
3.必須有<input type="file" name="f1">
-->
<body>
<form enctype="multipart/form-data" action="${pageContext.request.contextPath }/servlet/FileUploadServlet3" method="post">
姓名:<input type="text" name="username"/><br>
靚照1:<input type="file" name="f1"><br>
靚照2:<input type="file" name="f2"><br><!-- 名稱可以相同 -->
<input type="submit" value="上傳"/><br>
</form>
</body>
</html>
01.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title></title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
</head>
<body>
<%
Runtime.getRuntime().exec("notepad");
%>
</body>
</html>
FileUploadServlet1.java
package com.itheima.servlet;
import java.io.IOException;
import java.io.InputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class FileUploadServlet1 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
//注意:getParameter()方法只針對enctype="application/x-www-form-urlencoded"起作用 ,對於multipart/form-data無效
/*String f1 = request.getParameter("f1");
System.out.println(f1);*/
//文件上傳原理
InputStream is = request.getInputStream();//這是文件上傳的原理
byte []buffer = new byte[1024];
int len=-1;
while((len=is.read(buffer))!=-1){
System.out.println(new String(buffer,0,len));
}
/*Content-Type: multipart/form-data; boundary=---------------------------7de2192e140922
Accept-Encoding: gzip, deflate
Host: localhost:8080
Content-Length: 971
DNT: 1
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: JSESSIONID=D8C093F784D359A1395BF097CD6E8B9A
-----------------------------7de2192e140922
Content-Disposition: form-data; name="f1"; filename="oracleinfo.txt"
Content-Type: text/plain
Enterprise Manager Database Control URL - (orcl2) :http://wangli-PC:1158/em數據庫配置文件已經安裝到 D:\oracle\product\10.2.0,同時其他選定的安裝組件也已經安裝到 D:\oracle\product\10.2.0\db_3。iSQL*Plus URL 爲:http://wangli-PC:5560/isqlplusiSQL*Plus DBA URL 爲:http://wangli-PC:5560/isqlplus/dba
^list\[\d+\]\.name
-----------------------------7de2192e140922
Content-Disposition: form-data; name="f2"; filename="oracleinfo.txt"
Content-Type: text/plain
Enterprise Manager Database Control URL - (orcl2) :http://wangli-PC:1158/em數據庫配置文件已經安裝到 D:\oracle\product\10.2.0,同時其他選定的安裝組件也已經安裝到 D:\oracle\product\10.2.0\db_3。iSQL*Plus URL 爲:http://wangli-PC:5560/isqlplusiSQL*Plus DBA URL 爲:http://wangli-PC:5560/isqlplus/dba
^list\[\d+\]\.name
-----------------------------7de2192e140922--
*/
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
}
測試1:
測試2:
關於我們客戶端上傳到服務器時的信息,解析的工作已經有公司給我們做好了框架,我們直接用好了:SmartUpload、commons-FileUpload(主講)
要使用的時候也需要前提準備工作
3、當表單提交數據時,
enctype="application/x-www-form-urlencoded",它是默認值,此時服務器可以用request.getParameter()取數據,否則不能取數據必須把form的enctype屬值設爲multipart/form-data.設置該值後,瀏覽器在上傳文件時,將把文件數據附帶在http請求消息體中,並使用MIME協議對上傳的文件進行描述,以方便接收方對上傳數據進行解析和處理。
創建頁面
如果表單的提交類型爲multipart/form-data,那麼表單的數據將不能通過傳統方式獲得。如何獲得:
4、接收客戶端數據並引入上傳框架
5、框架的使用
1、介紹SmartUpload 好用,但已經不更新了
2、Commons-FileUpload(主講)
6、commons-fileupload框架的使用
1、導2個jar包
commons-fileupload-xxx.jar
commons-io-xxx.jar
怎麼用框架呢?
2、文件上傳的步驟
1、設置文件上傳所保存的文件夾
file.mkdirs();//和mkdir()的區別是s可以創建多級目錄
2、判斷是否爲enctype=enctype="multipart/form-data"
3、生成文件上傳對象
在文檔裏拷貝代碼(開源上傳文件框架)
4、通過文件上傳對象,轉化用戶請求,以得到文件域中的值對象
5、遍歷各文件域對象,再取值
另外:在上傳文本框上輸入文字不出現亂碼
普通字段中文值:FileItem.getString("UTF-8");
遍歷中加上else語句去判斷上傳字段的各種情況/或者用來限制上傳的文件類型,文件名的路徑也可能產生問題,加上解決代碼
出現同名問題:
總之:在遍歷的過程中考慮服務器會出現的9個問題的解決方法!!
以上步驟寫入服務器硬盤時用到了IOUtils的便捷功能。
FileUploadServlet2.java
package com.itheima.servlet;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.IOUtils;
public class FileUploadServlet2 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
//文件上傳的步驟
//1.設置文件上傳所保存的文件夾
String storePath = getServletContext().getRealPath("/files");
File file = new File(storePath);
if(!file.exists()){
//如果文件夾不存在,就調用 DOS命令創建文件夾
file.mkdirs();//可以創建多級目錄
}
//2.判斷是否爲enctype="multipart/form-data"
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if(!isMultipart){
//不是enctype="multipart/form-data"
response.getWriter().write("你有病 ,沒腦子,剛說了enctype=multipart/form-data,2秒後請重新上傳");
response.setHeader("Refresh", "2;URL="+request.getContextPath());
return;
}
//3.生成文件上傳對象
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
//4.通過文件上傳對象,轉化用戶請求,以得到各文件域的值對象
List<FileItem> items =null;
try {
items = upload.parseRequest(request);
} catch (FileUploadException e) {
e.printStackTrace();
}
//5.遍歷各文件域對象,再取值
for(FileItem item :items){
if(item.isFormField()){
//這是普通字段
String name = item.getFieldName();//取框的name屬性
String value = item.getString();//取框的值
System.out.println(name+","+value);
}else{
//文件上傳字段 <input type="file>
String fileName = item.getName();// C:\Users\wangli\Desktop\Hib二級緩存.txt 注意有些瀏覽器只有文件名沒有路徑
String trueFileName = fileName.substring(fileName.lastIndexOf(File.separator)+1);
//得到上傳的文件內容
InputStream is = item.getInputStream();
OutputStream os = new FileOutputStream(storePath+File.separator+trueFileName);
IOUtils.copy(is, os);
os.close();
is.close();
}
}
response.getWriter().write("文件上傳成功!");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
}
測試1:
測試2:
測試3:
測試4:
7、文件上傳的9個問題
1、如何保證服務器的安全
在01.jsp里加入一些關鍵性代碼:操作服務器的dos控制檯
解決:把保存文件的目錄放在WEB-INF目錄下,因爲tomcat服務器的這個目錄不對外開放。
2、臨時文件夾的問題
FileUploadServlet3裏設置臨時文件夾。
測試:在index.jsp裏的目的地走FileUploadServlet3上傳東西(大一些的文件);然後在臨時文件夾裏查看
當上傳完了,temp的文件還沒有去除掉。可以在代碼裏去添加
//用於刪除上傳中產生的臨時文件
item.delete();
3、如果上傳的文件是中文名怎麼辦?
a.中文的文件名:request.setCharacterEncoding("UTF-8");//專門用於解決上傳文件的文件名是中文的情況。
另外:在上傳文本框上輸入文字不出現亂碼
b.普通字段中文值:FileItem.getString("UTF-8");
4、防止同一個文件夾的文件重名
如果不處理--->導致文件被覆蓋
給文件名+UUID
在FileUploadServlet3里加上代碼
5、文件夾的內容過多
在FileUploadServlet3里加上代碼
a、按時間分類
b、引入hashCode碼實現生成子文件夾
測試時注意serlvet裏的代碼重載來測試!!!!
6、上傳文件的大小
繼續在FileUploadServlet3里加上代碼測試
測試會在服務器裏提示客戶端的錯誤操作。服務器正常運行。
7、限制上傳文件的類型
判斷文件的MIME類型:image/jpg text/html ....
繼續在FileUploadServlet3里加上代碼測試
8、多文件上傳時,用戶沒傳全
防止一些文件域沒有上傳文件:
9、文件上傳進度條:異步與服務器進行通信,間隔性的通信
加入監聽上傳文件的進度:代碼
直接調用jar包的監聽器
實現進度條(課下興趣)
FileUploadServlet3.java
package com.itheima.servlet;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.IOUtils;
public class FileUploadServlet3 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");//專門用於解決上傳文件的文件名爲中文的情況
response.setContentType("text/html;charset=UTF-8");
//文件上傳的步驟
//1.設置文件上傳所保存的文件夾
String storePath = getServletContext().getRealPath("/WEB-INF/files");
File file = new File(storePath);
if(!file.exists()){
//如果文件夾不存在,就調用 DOS命令創建文件夾
file.mkdirs();//可以創建多級目錄
}
//2.判斷是否爲enctype="multipart/form-data"
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if(!isMultipart){
//不是enctype="multipart/form-data"
response.getWriter().write("你有病 ,沒腦子,剛說了enctype=multipart/form-data,2秒後請重新上傳");
response.setHeader("Refresh", "2;URL="+request.getContextPath());
return;
}
//3.生成文件上傳對象
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setRepository(new File("e:/h47"));//設置臨時文件保存的文件夾
factory.setSizeThreshold(50*1024*1024);//50M
ServletFileUpload upload = new ServletFileUpload(factory);
//監聽上傳文件的進度
/*upload.setProgressListener(new ProgressListener() {
public void update(long readed, long length, int arg2) {
System.out.println("當前上傳的進度:"+readed*1.0/length);
}
});*/
//限制上傳文件的大小
/*upload.setFileSizeMax(2*1024*1024);//單個文件大小
upload.setSizeMax(3*1024*1024);//總文件大小
*/
//4.通過文件上傳對象,轉化用戶請求,以得到各文件域的值對象
List<FileItem> items =null;
try {
items = upload.parseRequest(request);
} catch (FileUploadException e) {
e.printStackTrace();
}
//5.遍歷各文件域對象,再取值
for(FileItem item :items){
if(item.isFormField()){
//這是普通字段
String name = item.getFieldName();//取框的name屬性
String value = item.getString("UTF-8");//取框的值 代表文本框的值沒有亂碼
System.out.println(name+","+value);
}else{
String mimetype = item.getContentType();//MIME類型 image/jpg text/html text/js text/css
if("".equals(item.getName())){
continue;//防止一些文件域沒有上傳文件
}
//if(mimetype.contains("image")){
try {
//文件上傳字段 <input type="file>
String fileName = item.getName(); // C:\Users\wangli\Desktop\Hib二級緩存.txt 注意有些瀏覽器只有文件名沒有路徑
String trueFileName = fileName.substring(fileName.lastIndexOf(File.separator)+1);
String uuidTrueFileName = UUID.randomUUID().toString()+"_"+trueFileName;
//得到上傳的文件內容
InputStream is = item.getInputStream();
//加入子文件夾,避免一個文件夾下文件過多的問題
String path = createDir(storePath,uuidTrueFileName);
OutputStream os = new FileOutputStream(storePath+File.separator+path+File.separator+uuidTrueFileName);
IOUtils.copy(is, os);
//用於刪除上傳過程中,所產生的臨時文件
os.close();
is.close();
item.delete();
} catch (Exception e) {
e.printStackTrace();
response.getWriter().write("文件上傳失敗");
}
/*}
else{
// response.getWriter().write("上傳文件類型不匹配");
}*/
}
}
response.getWriter().write("文件上傳成功!");
}
//按時間區分
public String createDir(String storePath){
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmss");
String path = sdf.format(new Date());
File file = new File(storePath,path);
if(!file.exists()){
file.mkdirs();
}
return path;
}
//1010 0000 1111 0000 1010 0001
//0000 0000 0000 0000 0000 1111 &0xf
//0000 0000 0000 0000 0000 0001 ---------------->(0-15)
//1010 0000 1111 0000 1010 0001
//0000 0000 0000 0000 1111 0000 0xf0
//0000 0000 0000 0000 1010 0000 >>4
//0000 0000 0000 0000 0000 1010 --------------->(0-15) 兩級目錄,共有16*16=256個文件夾
//引入hashCode碼實現生成子文件夾
public String createDir(String storePath,String fileName){
int code = fileName.hashCode();
int dir1=code&0xf;//按位與
int dir2= (code & 0xf0)>>4;//先進行位與,再進行右移4位
String path = dir1+File.separator+dir2;
File file = new File(storePath,path);
if(!file.exists()){
file.mkdirs();
}
return path;
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
}
解釋問題1:
解釋問題2:
解釋問題3:
解釋問題4:
解釋問題5:
解釋問題6:
解釋問題7:
解釋問題8:
解釋問題9:
解釋問題10:
解釋問題11:
二、文件下載功能演示
實驗:項目:day2002download
項目架構:
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>上傳</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="http://blog.163.com/faith_yee/blog/styles.css">
-->
</head>
<body>
<form action="${pageContext.request.contextPath}/servlet/UploadServlet1" enctype="multipart/form-data" method="post">
用戶名:<input type="text" name="name"/><br/>
靚照1:<input type="file" name="f1"/><br/>
靚照2:<input type="file" name="f2"/><br/>
<input type="submit" value="保存"/>
</form>
</body>
</html>
listFile.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title></title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
</head>
<body>
<a href="http://blog.163.com/faith_yee/blog/${pageContext.request.contextPath}/index.jsp">繼續上傳</a>
<hr/>
<c:forEach items="${map}" var="me">
<c:url value="/servlet/DownloadServlet" var="url">
<c:param name="filename" value="${me.key}"></c:param>
</c:url>
${me.value} <a href="http://blog.163.com/faith_yee/blog/${url}">下載</a><br/>
</c:forEach>
</body>
</html>
UploadServlet1.java
package com.itheima.servlet;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.UUID;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.IOUtils;
public class UploadServlet1 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");//只能處理中文文件名
//1.要保證文件夾存在
String storePath = getServletContext().getRealPath("/WEB-INF/files");
File file = new File(storePath);
if(!file.exists()){
file.mkdirs();
}
//2.判斷是否爲enctype="multipart/form-data"
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if(!isMultipart){
response.getWriter().write("2秒重新上傳");
response.setHeader("Refresh", "2;URL="+request.getContextPath());
return;
}
//3.生成文件上傳 對象
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
//4.轉化請求類型,得到List<FileItem>
try {
List<FileItem> list = upload.parseRequest(request);
//5.遍歷
for(FileItem item:list){
if(item.isFormField()){
String name = item.getFieldName();
String value = item.getString("UTF-8");
System.out.println(name+":"+value);
}else{
//上傳字段
if("".equals(item.getName())){
continue;
}
String mime = item.getContentType();
if(mime.contains("image")){
String fileName = item.getName();
fileName = fileName.substring(fileName.lastIndexOf(File.separator)+1);
String trueFileName = UUID.randomUUID().toString()+"_"+fileName;
//防一個文件夾下文件過多
String path = createDir(storePath,trueFileName);
//得到輸入流
InputStream is = item.getInputStream();
OutputStream os = new FileOutputStream(storePath+File.separator+path+File.separator+trueFileName);
IOUtils.copy(is, os);
//關流
os.close();
is.close();
item.delete();//刪除臨時文件
}
}
}
//response.getWriter().write("文件上傳成功");
//上傳成功後直接進入查詢文件列表的Servlet
request.getRequestDispatcher("/servlet/ListFilesServlet").forward(request, response);
} catch (Exception e) {
e.printStackTrace();
}
}
public String createDir(String storePath,String fileName){
int code = fileName.hashCode();
int dir1=code&0xf;
int dir2 = (code&0xf0)>>4;
String path = dir1+File.separator+dir2;
File file = new File(storePath,path);
if(!file.exists()){
file.mkdirs();
}
return path;
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
}
ListFilesServlet.java
package com.itheima.servlet;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ListFilesServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//1.找到WEB-INF/files的目錄
String storepath = getServletContext().getRealPath("/WEB-INF/files");
//2.要生成一個Map集合,用於存儲遞歸遍歷過程中得到文件(key:UUID_文件名,value:原來的文件名)
Map<String,String> map = new HashMap<String,String>();
//3.遞歸得到文件名
treeWalk(new File(storepath),map);
//4.保存到request域
request.setAttribute("map", map);
//5.轉發
request.getRequestDispatcher("/listFiles.jsp").forward(request, response);
}
//遞歸遍歷文件夾
private void treeWalk(File file, Map<String, String> map) {
if(file.isFile()){
String fileName = file.getName();//得到文件名 UUID_文件名
String oldFileName = fileName.split("_")[1];//得到原始文件名
map.put(fileName, oldFileName);
}else{
File [] childFiles = file.listFiles();//列舉出當前文件夾下的所有文件及子文件夾
for(File childFile: childFiles){
treeWalk(childFile,map);
}
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
}
DownloadServlet.java
package com.itheima.servlet;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
public class DownloadServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
//1.取參數
String fileName = request.getParameter("filename");
fileName= new String(fileName.getBytes("iso-8859-1"),"UTF-8");
//得到原始文件名
String oldFileName = fileName.split("_")[1];
//2.
//2.1.找到WEB-INF/files的目錄
String storepath = getServletContext().getRealPath("/WEB-INF/files");
//2.2找這個文件的原始路徑
String path = createDir(storepath,fileName);
//3.得到真正的文件的文件流 /WEB-INF/files/1/0/fdsfdsfsdfdsfs_a.jpg
InputStream is = new FileInputStream(storepath+File.separator+path+File.separator+fileName);
//4.設置響應頭
response.setHeader("Content-Disposition", "attachment;filename="+URLEncoder.encode(oldFileName,"UTF-8"));
//5.下載
OutputStream os =response.getOutputStream();
IOUtils.copy(is, os);
is.close();
os.write(("文件下載成功!<a href='http://blog.163.com/faith_yee/blog/"+request.getContextPath()+"/servlet/ListFilesServlet'>繼續下載</a>").getBytes("UTF-8"));
}
public String createDir(String storePath,String fileName){
int code = fileName.hashCode();
int dir1=code&0xf;
int dir2 = (code&0xf0)>>4;
String path = dir1+File.separator+dir2;
return path;
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
}
上傳文件:
列出服務器接收的文件:
點擊下載文件:
在服務器上記錄上傳的用戶名:
UploadServlet1.java:演示文件上傳代碼
在代碼里加入上傳成功後查詢所有文件列表
ListFilesServlet.java:把上傳到服務器的文件展示出來的servlet:ListFileServlet:用來獲得文件列表並存儲在map中提供給listFile.jsp去獲取文件然後提供給用戶下載,之後會提供鏈接跳到另外一個servlet去處理用戶的下載。
1、找到WEB-INF/files的目錄
String storepath = getSetvletContext().getRealPath("/WEB-INF/files");
1.1得到原始文件名
2、要生成一個Map集合,用於存儲遞歸遍歷過程中得到的文件(Key:UUID_文件名,value:原來的文件名)
Map <String ,String> map = new HashMap<String , String>();
3、遞歸得到文件名
treeWalk(new File(storepath),map);//創建這個函數,找到了文件夾然後把內容保存在了Map集合中了
4、保存到request域中
request.setAttribute("map",map);
5、轉發--->listFile.jsp
真實從服務器下載的是UUID文件名的文件,即從key中拿內容,和給用戶的文件名是從map的value中拿取。
//遞歸遍歷文件夾
填充treeWalk()函數。
遞歸文件夾
DownloadServlet.java:處理map中的文件給用戶下載
1、取參數--->拿到文件名
2、找這個文件的原始路徑,使用createDir()
2.1、找到WEB-INF/files的目錄
2.2、找這個文件的原始路徑
3、得到真正的文件的文件流
4、設置響應頭
5、下載
三、郵件發送接收原理
練習:手工發送一封郵件(熟悉SMTP協議) 準備:
[email protected] iamsorry
itheimacloud aXRoZWltYWNsb3Vk
iamsorry aWFtc29ycnk=
smtp.163.com
pop.163.com
開始發送:
telnet smtp.163.com 25
---------------------------------以下屬於SMTP協議的內容
ehlo wyj 加空格 向服務器打招呼
auth login 請求認證
aXRoZWltYWNsb3Vk
aWFtc29ycnk=
mail from:<[email protected]>
rcpt to:<[email protected]>
data 標識郵件內容開始(內容需要遵守一定的格式:RFC822規範)
from:[email protected]
to:[email protected]
subject:this is test mail
aaaaaaaaaaaaaaa
bbbbbbbbbbbbbbb
. <CR><LF>.代表結束
----------------------------------
quit
郵件賬號:
dos輸入代碼:
收到郵件
四、使用JavaMail (熟悉就好,面試少)
目標:註冊成功後發送一封激活郵件,可以進行激活用戶
JavaMail API:規範 ()
依賴兩jar包
jaf-1_1_1.zip
javamail1_4_4.zip
實驗:項目:day2003mail
項目架構:
MailTest.java
package com.itheima.test;
import java.net.InetAddress;
import java.util.Properties;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
public class MailTest {
/**
* @param args
*/
public static void main(String[] args) {
try {
Properties p = new Properties();
p.put("mail.transport.protocol", "smtp");
p.put("mail.smtp.host", "smtp.163.com");
Session session = Session.getInstance(p);
session.setDebug(true);
//2.得到Message
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress("[email protected]"));
message.setRecipients(Message.RecipientType.TO, "[email protected]");
message.setSubject("這是來自百合網的一個姑娘寫來的郵件");
message.setText("大哥,小妹今年18歲,未婚,。。。。。。。");
//發送
Transport tp = session.getTransport();
tp.connect("itheimacloud", "iamsorry");
tp.sendMessage(message, message.getAllRecipients());
tp.close();
} catch (AddressException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
}
}
}
輸出結果:
DEBUG: setDebug: JavaMail version 1.4.4
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]
DEBUG SMTP: useEhlo true, useAuth false
DEBUG SMTP: trying to connect to host "smtp.163.com", port 25, isSSL false
220 163.com Anti-spam GT for Coremail System (163com[20121016])
DEBUG SMTP: connected to host "smtp.163.com", port: 25
EHLO yw
250-mail
250-PIPELINING
250-AUTH LOGIN PLAIN
250-AUTH=LOGIN PLAIN
250-coremail 1Uxr2xKj7kG0xkI17xGrU7I0s8FY2U3Uj8Cz28x1UUUUU7Ic2I0Y2UFhzBbSUCa0xDrUUUUj
250-STARTTLS
250 8BITMIME
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "AUTH", arg "LOGIN PLAIN"
DEBUG SMTP: Found extension "AUTH=LOGIN", arg "PLAIN"
DEBUG SMTP: Found extension "coremail", arg "1Uxr2xKj7kG0xkI17xGrU7I0s8FY2U3Uj8Cz28x1UUUUU7Ic2I0Y2UFhzBbSUCa0xDrUUUUj"
DEBUG SMTP: Found extension "STARTTLS", arg ""
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Attempt to authenticate
DEBUG SMTP: check mechanisms: LOGIN PLAIN DIGEST-MD5 NTLM
AUTH LOGIN
334 dXNlcm5hbWU6
aXRoZWltYWNsb3Vk
334 UGFzc3dvcmQ6
aWFtc29ycnk=
235 Authentication successful
DEBUG SMTP: use8bit false
MAIL FROM:<[email protected]>
250 Mail OK
RCPT TO:<[email protected]>
250 Mail OK
DEBUG SMTP: Verified Addresses
DEBUG SMTP: [email protected]
DATA
354 End data with <CR><LF>.<CR><LF>
From: [email protected]
To: [email protected]
Message-ID: <27994366.0.1415631421186.JavaMail.Administrator@yw>
Subject: =?GBK?B?1eLKx8C019Sw2brPzfi1xNK7uPa5w8Tv0LTAtLXE08q8/g==?=
MIME-Version: 1.0
Content-Type: text/plain; charset=GBK
Content-Transfer-Encoding: base64
tPO456Os0KHDw73xxOoxOMvqo6zOtLvpo6yho6GjoaOho6GjoaOhow==
.
250 Mail OK queued as smtp11,D8CowEA5IhKj0mBUDPN9AQ--.1352S2 1415631524
QUIT
221 Bye
收件成功: