javaWeb專案總結
這篇部落格是對我學習的記錄。
---------------------------------------------------------------------2015-07-29晚---------------------------------------------------------------
最近幾個月都在學習java,我當初為什麼要選擇技術,其實我當初是看中了技術的薪水,但是後來發現技術不僅僅是要看中薪水,還要看重技術,因為我覺得技術是一門非常美麗的藝術,至少我是這麼認為的,在現在的社會當中,人們越來越離不開電子科技了,而很多的電子科技都是開發人員拼死拼活做出來的,當然作為一個程式設計師的話,編碼的過程可以說是血淚與歡笑的交替。好了,不羅嗦了,直接進入正題。
最近學習完了java WEB,要一個小組合作完成一個小型的專案(類似於淘寶網),其實做的東西也不多,主要是要我們熟悉正式編程式碼的時候走的流程。
因為需求文件和頁面以及資料庫都是現成的了,所以我們只做後臺也前臺互動就可以了。當然前臺也需要稍微調整,例如拿到後臺的資料再把它們顯示在頁面上。
這次的專案使用的是STS(Spring Tool Suit)開發工具,這個開發工具其實就是對eclipse進行了自定義改造。使用起來也沒多大的差別,就是多了一些外掛而已。然後專案使用的框架是SpringMVC+hibernate,目前市場上應該主流的有幾個搭配:SSH,SpringMVC+hibernate,SpringMVC+mybatis我目前知道的就這三種搭配。
這次的專案我做的部分是頁面的顯示,當開啟首頁的時候就需要使用一個forward標籤來進行跳轉到後臺取資料,之後再跳轉回首頁,將拿到的資料進行顯示。此處需要注意的地方是:如果單單寫了個forward標籤而不加以判斷的話就會出現死迴圈。所以在進入後臺之後要把一些要顯示的資料設定到applicationScope裡面或者是SessionScope裡面,個人覺得,只要在整個網站中所有人見到的東西都一樣的話就設定成applicationScope,這樣既方便又簡潔。
<c:if test="${(applicationScope.brands)==null }"> <jsp:forward page="${pageContext.request.contextPath }/../page/toIndex.do"></jsp:forward> </c:if>
這裡面的brands是所有的商標的意思。如果是首次進入index.jsp頁面時這個brands是空的,所以就需要跳轉到後臺拿資料,第二次進入index.jsp的時候brands不為空,所以就不需要在調到後臺的controller裡面了。
首頁當然不僅僅只有商標,還有產品,產品也是需要在第一次跳到後臺的時候拿到資料,這些資料一般都是經過處理的,例如經過了特定的要求排好序的一個產品集合。首頁拿到資料後在使用jstl的標籤foreach遍歷出來並顯示在頁面上。
<c:forEach var="brand" items="${applicationScope.brands }">
<dl>
<dt>
<a href="${pageContext.request.contextPath }/product/product_list.do?selectType=1&&pageCount=1" title="${brand.name }"><img src="${pageContext.request.contextPath }/pages/${brand.logo}" alt="${brand.name }" width="88" height="38" border="0"></a>
</dt>
<span style="white-space:pre"> </span><dd>
<a title="${brand.name }" href="${pageContext.request.contextPath }/product/product_list.do?selectType=1&&pageCount=1">${brand.name }</a>
</dd>
</dl>
</c:forEach>
以上是迴圈遍歷從applicationScope裡面拿到的資料,這裡只演示一下迴圈遍歷商標的資訊並顯示在頁面上。產品的遍歷同出一轍。
對了,大家都發現在淘寶的最頂端那一欄會有一個註冊登入的按鈕吧。這個就得判斷使用者是否已經登陸,若沒有登陸則顯示這兩個按鈕,若已經登陸了則顯示“歡迎您,***”,其實這個也是挺好做的,就是登陸成功之後將使用者物件儲存到sessionScope裡面,然後再頁面上判斷該session到底有沒有值,是不是空,如果是空則顯示登陸註冊按鈕,反之顯示“歡迎您,***”;
<pre name="code" class="html"><c:if test="${(sessionScope.s_user)!=null }">
您好,<font class="f4_b">${s_user.name }</font>, 歡迎您回來! [
<a href="${pageContext.request.contextPath }/userUndo/doUserUndo.do" rel="nofollow">退出
<span style="white-space:pre"> </span></a> ]
</c:if>
<c:if test="${(sessionScope.s_user)==null }">
<span style="white-space: pre;"> </span><a href="${pageContext.request.contextPath }/product/isLogin.do?pageInfo=index">[ 登入
<span style="white-space:pre"> </span></a>|
<a href="${pageContext.request.contextPath }/product/isLogin.do?pageInfo=index"> 註冊 ]
<span style="white-space:pre"> </span></a>
</c:if>
以上就是簡單的判斷。
接下來再說一下分頁的功能吧!如果商品有很多,我們總不能把全部商品一次性從資料庫中讀取出來,然後全部顯示在頁面中吧,這不科學。所以才出現了分頁顯示的功能。就好像一本書有很多文字,我們也不會把全部的文字都放在一頁紙上吧,我們通常的做法都是講文字分成每一頁顯示多少個字元,分為多少頁來顯示,這樣讓人看起來一點也不揪心。
分頁其實也是蠻簡單的,由於我這個專案使用的是mysql-connector-java-5.1.16-bin.jar,大家應該都知道mysql的分頁是最簡單的,只需要一個limit關鍵字就可以輕鬆實現,相對於SQL Server , Oracle的分頁來說簡單太多了。
SQL語句固然簡單,但如何才能把讀取到的資料返回給頁面並顯示出來呢?而且還要注意一些細節上的問題。例如:當前頁是第一頁是就隱藏掉“上一頁”這個按鍵,如果當前頁是最後一頁就隱藏掉“下一頁”這個按鍵,使用者體驗也會好很多。還有就是想要選擇第幾頁直接就跳轉到該頁就需要輸入一個自己想要的頁碼數,傳到後臺,後臺處理完後再將相應的資料返回給頁面。
c:if test="${sessionScope.currentPageNum >1}">
<span class="previou1"><a class="previou1"
href="${pageContext.request.contextPath }/product/product_list.do?selectType=${sessionScope.selectType }&&pageCount=${sessionScope.currentPageNum -1}" rel="nofollow">上一頁</a></span>
</c:if>
<c:if test="${sessionScope.currentPageNum<pageNum }">
<a href="${pageContext.request.contextPath }/product/product_list.do?selectType=${sessionScope.selectType }&&pageCount=${sessionScope.currentPageNum +1}"
class="next2" rel="nofollow">下一頁</a>
</c:if>
<td class="pagebt">
<a href="${pageContext.request.contextPath }/product/product_list.do?selectType=${sessionScope.selectType }&&pageCount=${pageNum }" rel="nofollow">末頁
</a>
跳轉到第 <input id="pageCode" name="pageCount" type="text" id="curpage" />頁
<input name="pagebt" type="submit" id="pagebt" value="確定" />
</td>
以上就是上一頁,下一頁以及選擇第幾頁的做法。
接下來我想講的是購物車這塊,其實我講的地方都是我自己提醒我自己要注意的地方,也是我在做專案的過程中遇到的問題,之後又通過各種途徑解決之後的成果。
今天就先到這吧,快一點了,明天再繼續...keep moving and stay strong!!!
---------------------------------------------------------------------2015-07-30晚---------------------------------------------------------------
好了,繼續昨天晚上沒有寫完的。
購物車,其實我一開始的時候是直接在頁面上操作,意圖在頁面完成新增到購物車之後的各種計算功能,但是後來發現這種做法是比較麻煩的。後來在老師的指點之下,選擇了使用VO(通常用於業務層之間的資料傳遞,和POJO一樣也是僅僅包含資料而已。但應是抽象出的業務物件,可以和表對應,也可以不,這根據業務的需要.),把購物車所需要的所有資料封裝到一個VO裡,這樣子,操作VO的時候就可以操作購物車了.
當然,在點選新增到購物車的時候需要將產品的id傳給後臺,後臺通過產品id查詢到該產品實體,在把這個產品set到一個包含產品詳情的POJO類的模型,通常是建立一個繼承原POJO類的VO,將該產品set到這個VO裡面後,在設定其他引數,例如訂單表,隱藏域的值(作為判斷是否是同一個訂單,作為該訂單的唯一識別符號),該產品的數量,單價,以及總價等資訊。然後拿到資料之後就可以對購物車進行單獨的操作了,購物車是暫時放到一個sessionScope裡面,當點選結算中心時才會插入到資料庫中。對購物車的刪除單個產品以及清空整個購物車的功能都不難實現,只需要傳入一個產品id給後臺,後臺remove掉session裡面的這個id的產品,清空就是removeAll。比較難做的就是購物車的更新了,每當在購物車更新了產品數量並點選更新購物車的時候,就要把整個購物車的各種數值重新整理一遍。
我的做法是,將該修改的數量以一個陣列的形式(request.getParameterValues("changeCount");)傳送給後臺,其實也可以使用SpringMVC 裡面的list資料繫結,這裡暫不做介紹。拿到陣列之後在與原來session裡面的值進行對比,看看那個產品的數量變化了,然後再更新該產品的總價,以及整個購物車的總價,到這裡,整個購物車就算是完成了。
/**
* 對購物車進行重新整理和清空。
*
* @param request
* @return
* @author frank
*/
@RequestMapping(value = "/operateCart.do", method = RequestMethod.GET)
public String operateCart(ShoppingCart shoppingCart,HttpServletRequest request,
HttpSession session) {
ShoppingCart cart = (ShoppingCart) session
.getAttribute("s_productList_shopCart");
String operation = request.getParameter("operation");
System.out.println(operation + "購物車中的產品");
if ("refresh".equals(operation)) {
// 獲取表單中所有name為changeCount的值
String[] values = request.getParameterValues("changeCount");
for (int i = 0; i < values.length; i++) {
Integer productCount = new Integer(values[i]);
if (cart.getOrderDetails().get(i).getProductCount() != productCount) {
cart.getOrderDetails().get(i).setProductCount(productCount);
cart.getOrderDetails()
.get(i)
.setProductPrice(
cart.getOrderDetails().get(i).getProduct()
.getSpecialPrice()
* productCount);
}
}
float totalPrice = 0;
for (OrderDetailModel oModel : cart.getOrderDetails()) {
totalPrice = oModel.getProductPrice() + totalPrice;
}
// 封裝一個購物車物件
cart.getUserOrder().setTotalPrice(totalPrice);
session.setAttribute("s_productList_shopCart", cart);
} else if ("removeAll".equals(operation)) {
float totalePrice = 0;
// 如果集合不為空才清空集合,否則會報空指標異常。
if (cart.getOrderDetails() != null
&& cart.getOrderDetails().size() > 0) {
cart.getUserOrder().setTotalPrice(totalePrice);
cart.getOrderDetails().removeAll(cart.getOrderDetails());
}
session.setAttribute("s_productList_shopCart", cart);
}
return "cart";
}
/**
* 將商品新增到購物車。
*
* @param modelMap
* ModelMap物件,用於將物件傳遞給頁面。
* @param id
* product的ID.
* @return 返回相應的跳轉資訊。
* @author frank
*/
@RequestMapping(value = "/{productId}/addToCart.do", method = RequestMethod.POST)
public String addToCart(ModelMap modelMap,
@PathVariable(value = "productId") int id, HttpSession session,
HttpServletRequest request, int number) {
Product product = productServiceImpl.getProductById(id);
String token = request.getParameter("token");
System.out.println("token的值--------------->" + token);
Iterator<String> tokenIterator = tokens.iterator();
boolean tokenFlag = true;
while (tokenIterator.hasNext()) {
if (tokenIterator.next().equals(token)) {
tokenFlag = false;
}
}
if (tokenFlag) {
ShoppingCart shopCart = new ShoppingCart();
if (session.getAttribute("s_productList_shopCart") != null) {
ShoppingCart shoppingCart = (ShoppingCart) session
.getAttribute("s_productList_shopCart");
shopCart.getOrderDetails().addAll(
shoppingCart.getOrderDetails());
}
Iterator<Product> iterator = cartList.iterator();
boolean flag = true;
// 迴圈迭代購物車集合,如果有重複的就不新增。
while (iterator.hasNext()) {
if (iterator.next().getId() == product.getId()) {
flag = false;
}
}
if (flag == true) {
float totalPrice = 0;
OrderDetailModel orderModel = new OrderDetailModel();
orderModel.setProduct(product);
orderModel.setSid(System.currentTimeMillis() + "");
orderModel.setProductPrice(product.getSpecialPrice() * number);
orderModel.setProductCount(number);
shopCart.getOrderDetails().add(orderModel);
List<OrderDetailModel> orderDetailModels = shopCart
.getOrderDetails();
for (OrderDetailModel oModel : orderDetailModels) {
totalPrice = oModel.getProductPrice() + totalPrice;
}
// 封裝一個購物車物件
shopCart.getUserOrder().setTotalPrice(totalPrice);
}
session.setAttribute("s_productList_shopCart", shopCart);
tokens.add(token);
return "cart";
} else {
tokens.add(token);
modelMap.put("product", product);
return "cart";
}
}
好了,這裡就暫時告一段落了。也算是我對這個專案的一個小總結。可能多年回過頭來看的時候又是另一番風味。