問題描述
1、完成商品圖片上傳功能
使用表單錄入商品基本信息(表單中包含file元素實現商品圖片選擇),實現把商品圖片保存到服務器端指定目錄下,輸出商品基本信息並在頁面上顯示商品圖片。本程序使用的product信息如下:
要求實現:
- 錄入每件商品的所有信息
- 可以查看上傳好的文件倉庫
- 可以下載倉庫中的文件
提示:
圖片保存在上下文的image目錄中
使用getServletContext().getRealPath("")獲得當前上下文的真實路徑
使用request.getContextPath()獲取上下文路徑
//創建File對象,指向當前上下文中的image目錄
File path=new File(this.getServletContext().getRealPath("/image"));
//輸出信息在頁面上顯示商品圖片
out.println(“<image src=”+request.getContextPath()+“/image/”+圖片文件名);
實現方法
我的思路是利用session會話來實現文件間的數據共享,將文件保存在服務器,不使用數據庫
(1)創建Product類用於存儲每件商品的信息
package Product;
public class Product {
public int pid;//編號
public String name;//名字
public String note;//備註
public int price;//價格
public int amount;//數量
public String filePath;//路徑
public String filename;//文件名
public Product(int pid,String name,String note,int price,int amount,String filename,String filePath){
this.pid=pid;
this.name=name;
this.note=note;
this.price=price;
this.amount=amount;
this.filename=filename;
this.filePath=filePath;
}
}
(2)HTML表單錄入商品信息(沒有調整樣式)
- form表單的action屬性要對應servlet程序
productUploadServlet
- 由於是上傳文件,form表單的enctype屬性,要規定編碼方式
multipart/form-data
屬性 | 值 | 描述 |
---|---|---|
enctype | application/x-www-form-urlencoded multipart/form-data text/plain | 規定在向服務器發送表單數據之前如何對其進行編碼。(適用於 method="post" 的情況) |
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<style type="text/css">
input{
display:block;
margin: 10px;
}
</style>
<body>
<form name="upLoadPic" method="post" action="productUploadServlet" enctype="multipart/form-data">
產品名稱:<input type="text" name="name" value="" required/>
產品簡介:<input type="text" name="note" value="" required/>
產品單價:<input type="number" name="price" required/>
產品數量:<input type="number" name="amount" required/>
上傳圖片:<input type="file" name="file" required/>
<input type="submit" value="提交"/>
</form>
</body>
</html>
(3)productupLoadServletc上傳文件
- 上傳文件的流程如下:
- 用request的getpart方法從前端獲取文件:
Part part = request.getPart("file")
- 用Part對象的getSubmittedFileName方法獲取文件名
String filename = part.getSubmittedFileName()
- 路徑獲取:
getServletContext().getRealPath("\\images")
,指向當前上下文中的image目錄 - 用Part對象的write(filePath)保存文件
- 文件用session保存起來,用於不同servlet間的數據共享
- 保存文件之後打印一條超鏈接,指向checkServlet程序,用於查看倉庫
productupLoadServletc實現
@MultipartConfig//確保servlet支持上傳
@WebServlet("/productUploadServlet")
public class productUploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public productUploadServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
@SuppressWarnings("deprecation")
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");//設置編碼
//獲取文件
Part part = request.getPart("file");
//獲取文件名稱
String filename = part.getSubmittedFileName();//獲取文件名
//路徑設置//獲取上下文真實路徑,文件保存在當前上下文的image目錄下可以這樣設置
File path=new File(getServletContext().getRealPath("\\images"));
if (!path.exists()) {//路徑不存在則創建
path.mkdir();
}
String filePath = path.getPath() + "\\" + filename;
/*********保存到session**********/
int fileNum=0;
String[] Names=null;
HttpSession session=request.getSession();
if(session.getValueNames()!=null)//不爲空
{
Names=session.getValueNames();
fileNum=Names.length;//數量
}
//設置屬性
int pid=fileNum+1;
String name=request.getParameter("name");
String note=request.getParameter("note");
int price=Integer.parseInt(request.getParameter("price"));
int amount=Integer.parseInt(request.getParameter("amount"));
session.setAttribute(name,new Product(pid, name, note, price, amount, filename,filePath));
//寫入保存(上傳)
part.write(filePath);
response.getWriter().append("<p>文件"+(fileNum+1)+"上傳成功!保存目錄爲"+filePath+"</p>");
response.getWriter().append("<p><a href=\"index.html\">繼續上傳</a></p>");
response.getWriter().append("<p><a href=\"checkServlet\">查看文件</a></p>");
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
(4)checkServlet查看倉庫中的文件
checkServlet用於查看倉庫中的文件,從session會話中獲取所有的文件信息,並且以無需列表的形式展示到網頁上
- 圖片顯示:
response.getWriter().println("<div><img src=\""+filePath+"\"></div>")
- 打印超鏈接指向下載servlet程序:注意要傳遞參數filename,所以用URLEncoder.encode設置編碼方式爲UTF-8
String URL=URLEncoder.encode(filename, "UTF-8");
response.getWriter().println("<div>下載文件:<a href='downLoadServlet?filename="+URL+"'>點擊下載"+name+"</a></div>");
checkServlet實現
@WebServlet("/checkServlet")
public class checkServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public checkServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");//設置編碼
HttpSession session=request.getSession();
String[] Names=session.getValueNames();
int fileNum=Names.length;
response.getWriter().println("<!DOCTYPE html>\r\n" +
"<html>\r\n" +
"<head>\r\n" +
"<meta charset=\"UTF-8\">\r\n" +
"<title>Insert title here</title>\r\n" +
"</head>\r\n" +
"<body>");
for(int i=0;i<fileNum;i++)
{
//獲取文件名
int pid=i+1;
Product product=(Product) session.getAttribute(Names[i]);
String name=product.name;
String note=product.note;
int price=product.price;
int amount=product.amount;
String filePath=product.filePath;
String filename=product.filename;
response.getWriter().println("<li>");
response.getWriter().println("<div><img src=\""+filePath+"\"></div>");//顯示圖片
response.getWriter().println("<div>商品編號:"+pid+"</div>");
response.getWriter().println("<div>商品名稱:"+name+"</div>");
response.getWriter().println("<div>商品簡介:"+note+"</div>");
response.getWriter().println("<div>商品價格:"+price+"</div>");
response.getWriter().println("<div>商品數量:"+amount+"</div>");
String URL=URLEncoder.encode(filename, "UTF-8");
response.getWriter().println("<div>下載文件:<a href='downLoadServlet?filename="+URL+"'>點擊下載"+name+"</a></div>");
response.getWriter().println("</ul>");
response.getWriter().println("</li>");
}
//response.getWriter().println("</ol></body></html>");
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
(5)downLoadServlet下載servlet
下載流程
- 文件路徑獲取:路徑用
this.getServletContext().getRealPath("//images//")
獲取上下文路徑,和超鏈接的參數filename拼接而成 - ContentType類型,設定Content-disposition屬性值:
// 根據文件名稱獲取文件的MIME類型,用於指定ContentType
String mimetype = getServletContext().getMimeType(filename);
response.setContentType(mimetype);
// 設定Content-disposition屬性值,可以上網瞭解,inline表示在瀏覽器內部直接打開文件
response.setHeader("Content-disposition", "inline");
- 文件下載:
利用FileInputStream對象從服務器讀取文件,將其寫入:
//保存文件,每次從FileInputStream對象中獲取11個字節
FileInputStream file = new FileInputStream(filepath);
byte[] in = new byte[2048];
while (file.read(in, 0, in.length) != -1) {
response.getOutputStream().write(in);
}
response.getOutputStream().flush();
file.close();
downLoadServlet實現
import java.io.FileInputStream;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class downLoadServlet
*/
@WebServlet("/downLoadServlet")
public class downLoadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public downLoadServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");//設置編碼
//文件名
String filename=request.getParameter("filename");
//設置文件路徑獲取當前上下文中image目錄下的文件
String filepath=this.getServletContext().getRealPath("//images//")+filename;
// 根據文件名稱獲取文件的MIME類型,用於指定ContentType
String mimetype = getServletContext().getMimeType(filename);
response.setContentType(mimetype);
// 設定Content-disposition屬性值,可以上網瞭解,inline表示在瀏覽器內部直接打開文件
response.setHeader("Content-disposition", "inline");
//保存文件,每次從FileInputStream對象中獲取11個字節
FileInputStream file = new FileInputStream(filepath);
byte[] in = new byte[2048];
while (file.read(in, 0, in.length) != -1) {
response.getOutputStream().write(in);
}
response.getOutputStream().flush();
file.close();
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
實現效果
時間原因沒有調整樣式
(1)表單錄入
(2)上傳成功
(3)信息展示
(4)文件下載