首先,來看一下程序的運行結果:
1. 商品展示部分
2.添加商品界面
下面說一下具體的實現過程:
1.創建數據庫表,任何一個系統首先要做的事情就是建表,明確自己的需求建相應表,該表中我只說一下
pimg字段,其他的大家都應該懂的吧(paddr表示的是商品產地) ,pimg字段用於存放上傳圖片的文件名,比如 美 女.jpeg ,而不是在 項目中的路徑,因爲我們要用時直接在文件名前面添加相對路徑(即圖片的源文件地址)就 可以了,比如:web/img/美女.jpeg
CREATE TABLE `product` (
`pid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`pname` varchar(50) NOT NULL,
`pprice` int(10) unsigned NOT NULL,
`paddr` varchar(10) NOT NULL,
`pimg` varchar(128) NOT NULL,
PRIMARY KEY (`pid`)
) ENGINE=InnoDB AUTO_INCREMENT=79 DEFAULT CHARSET=utf8
2. 建立數據庫連接
package com.test.sqlconnection;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MysqlConnection {
// 表示定義數據庫的用戶名
private static String USERNAME = "root";
// 定義數據庫的密碼
private static String PASSWORD = "123";
// 定義數據庫的驅動信息
private static String DRIVER = "com.mysql.jdbc.Driver";
// 定義訪問數據庫的地址
private static String URL = "jdbc:mysql://127.0.0.1:3306/shop";
// 定義數據庫的鏈接
private Connection connection;
// 定義sql語句的執行對象
private PreparedStatement pstmt;
// 定義查詢返回的結果集合
private ResultSet resultSet;
public MysqlConnection() {
}
/**
* 獲取數據庫連接
*
* @return 數據庫連接
*/
public Connection getConnection() {
try {
Class.forName(DRIVER); // 註冊驅動
connection = DriverManager.getConnection(URL, USERNAME, PASSWORD); // 獲取連接
} catch (Exception e) {
throw new RuntimeException("get connection error!", e);
}
return connection;
}
/**
* 執行更新操作
*
* @param sql
* sql語句
* @param params
* 執行參數
* @return 執行結果
* @throws SQLException
*/
public boolean updateByPreparedStatement(String sql, List<?> params)
throws SQLException {
boolean flag = false;
int result = -1;// 表示當用戶執行添加刪除和修改的時候所影響數據庫的行數
pstmt = connection.prepareStatement(sql);
int index = 1;
// 填充sql語句中的佔位符
if (params != null && !params.isEmpty()) {
for (int i = 0; i < params.size(); i++) {
pstmt.setObject(index++, params.get(i));
}
}
result = pstmt.executeUpdate();
flag = result > 0 ? true : false;
return flag;
}
/**
* 執行查詢操作
*
* @param sql
* sql語句
* @param params
* 執行參數
* @return
* @throws SQLException
*/
public List<Map<String, Object>> findResult(String sql, List<?> params)
throws SQLException {
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
int index = 1;
pstmt = connection.prepareStatement(sql);
if (params != null && !params.isEmpty()) {
for (int i = 0; i < params.size(); i++) {
pstmt.setObject(index++, params.get(i));
}
}
resultSet = pstmt.executeQuery();
ResultSetMetaData metaData = resultSet.getMetaData();
int cols_len = metaData.getColumnCount();
while (resultSet.next()) {
Map<String, Object> map = new HashMap<String, Object>();
for (int i = 0; i < cols_len; i++) {
String cols_name = metaData.getColumnName(i + 1);
Object cols_value = resultSet.getObject(cols_name);
if (cols_value == null) {
cols_value = "";
}
map.put(cols_name, cols_value);
}
list.add(map);
}
return list;
}
/**
* 釋放資源
*/
public void releaseConn() {
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (pstmt != null) {
try {
pstmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
這一步沒什麼好說的
3. 建立javabean類
package com.test.model;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.jasper.tagplugins.jstl.core.ForEach;
import com.test.sqlconnection.MysqlConnection;
public class Product {
private int id;
private String pnameString;
private String paddresString;
private int pprice;
private String pimgString;
public Product(int id,String pnameString, String paddresString, int pprice, String pimgString) {
super();
this.id = id;
this.pnameString = pnameString;
this.paddresString = paddresString;
this.pprice = pprice;
this.pimgString = pimgString;
}
public Product(){
super();
this.id = 0;
this.pnameString = "";
this.paddresString = "";
this.pprice = 0;
this.pimgString = "";
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getPnameString() {
return pnameString;
}
public void setPnameString(String pnameString) {
this.pnameString = pnameString;
}
public String getPaddresString() {
return paddresString;
}
public void setPaddresString(String paddresString) {
this.paddresString = paddresString;
}
public int getPprice() {
return pprice;
}
public void setPprice(int pprice) {
this.pprice = pprice;
}
public String getPimgString() {
return pimgString;
}
public void setPimgString(String pimgString) {
this.pimgString = pimgString;
}
//根據id獲得商品信息
public static Product getProductById(int id){
Product product = new Product();
product.setId(id);
MysqlConnection con = new MysqlConnection();
con.getConnection();
String sql = "select* from product where pid = '"+id+"'";
try {
Map<String, Object> map = con.findResult(sql, null).get(0);
product.setPprice(Integer.parseInt(map.get("pprice").toString()));
product.setPnameString(map.get("pname").toString());
product.setPaddresString(map.get("paddr").toString());
product.setPimgString(map.get("pimg").toString());
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
con.releaseConn();
}
return product;
}
//獲得所有產品
public static List<Product> getAllProducts(){
String sql = "select * from product";
MysqlConnection con = new MysqlConnection();
con.getConnection();
List<Product> list = new ArrayList<Product>(); //此處犯下重大錯誤
try {
List<Map<String, Object>> mapList = con.findResult(sql, null);
//System.out.println(mapList.size());
for (Map<String, Object> map : mapList) {
int id = Integer.parseInt(map.get("pid").toString());
int price = Integer.parseInt(map.get("pprice").toString());
String name = map.get("pname").toString();
String addr = map.get("paddr").toString();
String imgurl = map.get("pimg").toString();
System.out.println(imgurl);
Product product = new Product(id, name, addr, price, imgurl);
// System.out.println(product.getId());
// product.setPnameString(map.get("pname").toString());
// System.out.println(product.getPnameString());
// product.setPaddresString(map.get("paddr").toString());
//
// System.out.println(product.getPaddresString());
// product.setPprice(Integer.parseInt(map.get("pprice").toString()));
// System.out.println(product.getPprice());
// product.setPimgString(map.get("pimg").toString());
// System.out.println(product.getPimgString());
list.add(product);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
con.releaseConn();
}
// for (Product product1 : list) {
// System.out.println(product1.getId()+product1.getPaddresString()+" "+product1.getPimgString());
// }
//
return list;
}
// public static void main(String[] args){
// List<Product> list = Product.getAllProducts();
//
// }
}
這一步也沒什麼好說的,就是一個普通的Javabean類,裏面有兩個方法,商品展示的時候會用到
4 商品添加頁面 jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ page contentType="text/html;charset=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="<%=basePath%>">
<title>My JSP 'UploadProduct.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="styles.css">
-->
<link rel="stylesheet" type="text/css" href="css/back.css"/>
<script type=text/javascript src="js/SubmitCheck.js" charset="utf-8"></script>
<script type="text/javascript" src="js/jquery-1.11.1.js" charset="utf-8"></script>
<script type="text/javascript" src="js/preview.js" charset="utf-8"></script>
</head>
<body>
<form action="/midTermTest1/UploadServlet" method="post" name="addform" enctype="multipart/form-data" οnsubmit="return on_submit()">
<div id="Nav"><h1>添加商品:</h1></div><hr>
<br/><br/>
<div id="NavTop">
<div class="PName">
商品名稱:<input type="text" name="pname" id="name">
</div>
<div class="PAddr">
商品產地:<input type="text" name="paddr" id="address">
</div>
<div class="PPrice">
商品價格:<input type="text" name="pprice" id="price"> *單位 $
</div>
<div class="PImg">
<div id="img">圖片上傳:   <input type="file" id="imgs" name="pimgfile" οnchange="showPreview(this)"></div>
<div id="scan">圖片預覽:</div>
<div id="sourceImg"></div>
<div id="img_url"><img id="img_urlj" src="preview_img/preview.jpg" width=130px height=130px></div>
<div id="submit"><input type="submit" value="提交" id="submitbutton"></div>
</div>
</div>
</form>
</body>
</html>
就是一個普通的商品添加頁面,用js實現了圖片預覽的功能,你可以不用實現,這裏在做的時候遇到一個麻煩,花了好久才解決,就是我在添加商品圖片的時候,下面會顯示我添加的圖片,本來我是直接用js獲取其上傳圖片的本地磁盤路徑的,結果服務器爲了安全是不允許訪問服務器的本機文件地址的,結果本地磁盤路徑就給我改掉了 改成c://fdsk/beaty.jpeg 解決辦法就是,將你準備添加的存放圖片的那個文件夾映射到tomcat中,即可顯示,網上有教程,這裏就不詳說了。
5. 處理添加商品的servlet
package com.test.servlet;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.Statement;
import java.util.Iterator;
import java.util.List;
import javax.servlet.DispatcherType;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
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 com.mysql.fabric.Response;
import com.mysql.jdbc.MySQLConnection;
import com.test.sqlconnection.MysqlConnection;
import sun.rmi.server.Dispatcher;
/**
* Servlet implementation class UploadServlet
*/
@WebServlet("/UploadServlet")
public class UploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private String filePath; // 文件存放目錄
private String tempPath; // 臨時文件目錄
private String pname;
private String paddr;
private String pprice;
private String filename ;
private String SQLFileName;
// 初始化
// public void init(ServletConfig config) throws ServletException {
// super.init(config);
// // 可以從配置文件中獲得初始化參數
// //filePath = config.getInitParameter("filepath");
// //tempPath = config.getInitParameter("temppath");
// //ServletContext context = getServletContext();
// //filePath = context.getRealPath(filePath);
// //tempPath = context.getRealPath(tempPath);
// filePath="D:/ClassHelpFile/file";
// tempPath="D:/ClassHelpFile/temp";
// }
public UploadServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
// TODO Auto-generated method stub
}
protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(req, res);
//res.setCharacterEncoding("GBK");
PrintWriter pw = res.getWriter();
tempPath = getServletContext().getRealPath("/tempPImgs");
filePath = getServletContext().getRealPath("/pimgs");
System.out.println(tempPath);
// req.setAttribute("path", tempPath);
try {
DiskFileItemFactory diskFactory = new DiskFileItemFactory();
// threshold 極限、臨界值,即硬盤緩存 1M
diskFactory.setSizeThreshold(10 * 1024);
// repository 貯藏室,即臨時文件目錄
diskFactory.setRepository(new File(tempPath));
ServletFileUpload upload = new ServletFileUpload(diskFactory);
//防止亂碼
upload.setHeaderEncoding("utf-8");
// 設置允許上傳的最大文件大小 4M
upload.setSizeMax(10 * 1024 * 1024);
// 解析HTTP請求消息頭
List<FileItem> fileItems = upload.parseRequest(req);
Iterator<FileItem> iter = fileItems.iterator();
while (iter.hasNext()) {
FileItem item = (FileItem) iter.next();
if (item.isFormField()) {
processFormField(item, pw);//處理表單內容
} else {
processUploadFile(item, pw);//處理上傳的文件
}
}
SQLFileName=filename;
System.out.println(SQLFileName);
//保存到數據庫
//String sqlStart = "set names gbk";
String sql = "insert into product(pname,pprice,paddr,pimg) values('"+pname+"','"+pprice+"','"+paddr+"','"+SQLFileName+"')";
MysqlConnection con = new MysqlConnection();
con.getConnection();
//con.updateByPreparedStatement(sqlStart, null);
con.updateByPreparedStatement(sql, null);
con.releaseConn();
pw.println("<script>");
pw.println("alert('商品插入成功!即將跳轉首頁')");
pw.println("</script> ");
// pw.close();
} catch (Exception e) {
System.out.println("異常:使用 fileupload 包發生異常!");
e.printStackTrace();
}
res.setHeader("refresh", "1;url=jsp/showProduct.jsp");
// RequestDispatcher rd =req.getRequestDispatcher("/jsp/showProduct.jsp");
//
// try{
// rd.forward(req, res);
// return;
// }catch(Exception e){
// System.out.print(e.toString());
// }
// res.sendRedirect("/jsp/showProduct.jsp");
}
//處理表單內容
private void processFormField(FileItem item, PrintWriter pw)
throws Exception {
String name = item.getFieldName();
String value =new String((item.getString("iso8859-1")).getBytes("iso8859-1"),"utf-8");
// value = new String(value.getBytes("utf-8"));
// System.out.println(value);
if(name.equals("pname")){
pname = value;
}else if(name.equals("paddr")){
paddr = value;
}
else if(name.equals("pprice")){
pprice = value;
}
}
// 處理上傳的文件
private void processUploadFile(FileItem item, PrintWriter pw)
throws Exception {
filename = item.getName();
int index = filename.lastIndexOf("\\");
filename = filename.substring(index + 1, filename.length());
long fileSize = item.getSize();
if ("".equals(filename) && fileSize == 0) {
System.out.println("文件名爲空 !");
return;
}
File uploadFile = new File(filePath + "/" + filename);
if(!uploadFile.exists()){
item.write(uploadFile);
}
//pw.println(filename + " 文件保存完畢 !");
//pw.println("文件大小爲 :" + fileSize + "\r\n");
}
}
這一步比較重要的就是上傳文件與表單文本數據,如果是我們自己處理的話會比較麻煩,要將文件轉化二進制流後再寫入圖片在保存,因此我直接用了fileupload組件(也可用smartyupload)處理表單,簡單實用,其中需要用到兩個包,commons-io 與 commons-fileuplaod包 網上也有教程,這裏也不細說,要的留言
6.商品展示列表與分頁實現 jsp 頁面
<%@page import="com.test.model.Product"%>
<%@ 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="<%=basePath%>">
<title>My JSP 'showProduct.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="styles.css">
-->
<link rel="stylesheet" type="text/css" href="css/showProductCss.css"/>
</head>
<body>
<br/><br/><br/>
<h1 id="nav">商品展示               
<a id="back" href="jsp/UploadProduct.jsp" >添加商品</a></h1>
<br/><br/><br/>
<hr/>
<%!
public static final int PAGESIZE = 4; //單頁容量
int pageCount; //記錄頁數
int curPage = 1; //當前頁
int absolute; //定位到某條記錄
%>
<%
List<Product> list = Product.getAllProducts();
int size = list.size();
pageCount = (size%PAGESIZE==0)?(size/PAGESIZE):(size/PAGESIZE+1);
String tmp = request.getParameter("curPage");
String pcount = request.getParameter("getPageCount");
if(tmp==null || tmp.equals("0")){
tmp="1";
}
curPage = Integer.parseInt(tmp);
if(pcount!=null){
curPage = Integer.parseInt(pcount);
}
if(curPage>=pageCount) curPage = pageCount;
absolute = (curPage-1)*PAGESIZE+1; //定位到當前頁的第一條記錄
// int count = 0;
for(int i =absolute-1;i<(absolute-1+PAGESIZE);i++){
if(i>size-1){break;}
Product product = list.get(i);
//out.println(i);
// out.println(product.getId()+product.getPnameString()+product.getPaddresString());
%>
<div>
<dl>
<dt>
<a href="jsp/productDetails.jsp?id=<%=product.getId()%>"><img alt="商品"
src="pimgs/<%=product.getPimgString()%>" width="130" height="130"
border="1" /></a>
</dt>
<dd class="dd_name"><%=product.getPnameString() %></dd>
<dd class="dd_city">
產地:<%=product.getPaddresString() %>
價格:<span id="redPrice"><%=product.getPprice()%></span>
</dd>
</dl>
</div>
<%
}
%>
<div id="linkPage">
<a href="jsp/showProduct.jsp?curPage=1">首頁</a>
<a href="jsp/showProduct.jsp?curPage=<%if(curPage==1){out.print(1);}else{out.print(curPage-1);}%>">上一頁</a>
<a href="jsp/showProduct.jsp?curPage=<%if(curPage==pageCount){out.print(curPage);}else{out.print(curPage+1);}%>">下一頁</a>
<a href="jsp/showProduct.jsp?curPage=<%=pageCount%>">尾頁</a> 第<%=curPage%>頁/共<%=pageCount%>頁
</div>
<div id="getPage">
<form action="jsp/showProduct.jsp?">
跳轉至<input type="text" id="pageText" name="getPageCount"/>頁
<input type="submit" id="pageSubmit" value="確定"/>
</form>
</div>
</body>
</html>
這裏要說的是分頁實現,注意是以httpget方式傳遞參數的,如 showProduct.jsp?curPage=<%=pageCount%>,將curPage傳遞過去看到底要取哪些數據在頁面上顯示
完結~~~
7.總結
這個實例看起來已經有點接近mvc的設計模式了,但商品展示的界面並沒有交給相應的servlet處理,導致jsp中的java代碼太多,下面將會對該實例進行一些升級,比如使用mysql語句進行分頁查詢,這樣就不會加大查詢負擔,像該實例就是一次取出所有商品置於結果集中,然後再分頁顯示,但當商品數量很多的時候,服務器的壓力會很大可能導致很久才能反應或者不響應,其次,將會採用JSP+SERVLET+JAVABEAN實現比較完整的mvc設計模式,敬請期待