家居網購項目實現012 以下皆為部分代碼,詳見 https://github.com/liyuelian/furniture_mall.git 29.功能27-Ajax檢驗註冊名 29.1需求分析/圖解 用戶註冊時,後端通過驗證,提示用戶當前輸入的用戶名是否可用。 29.2思路分析 29.3代碼實現 ...
家居網購項目實現012
以下皆為部分代碼,詳見 https://github.com/liyuelian/furniture_mall.git
29.功能27-Ajax檢驗註冊名
29.1需求分析/圖解
用戶註冊時,後端通過驗證,提示用戶當前輸入的用戶名是否可用。
29.2思路分析
29.3代碼實現
dao層和service層的方法在之前已經實現過了,這裡不必再寫
29.3.1web層
MemberServlet添加方法isExistUserName,該方法返回json格式的數據給前端
/**
* 校驗某個用戶名是否已經存在資料庫中
*
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void isExistUserName(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.獲取用戶名
String username = req.getParameter("username");
//2.調用service
boolean isExistUsername = memberService.isExistsUsername(username);
//3.返回json格式[按照前端的需求]
//{"isExist":false}
//先使用最簡單的拼接,一會使用可拓展的方式
//String resultJson = "{\"isExist\":" + isExistUsername + "}";
//=>將要返回的數據返回map=>json
//使用map可以方便拓展
HashMap<String, Object> resultMap = new HashMap<>();
resultMap.put("isExist", isExistUsername);
String resultJson = new Gson().toJson(resultMap);
//4.返回json
resp.getWriter().write(resultJson);
}
29.3.2前端
login.jsp使用Ajax局部請求刷新
//給註冊模塊的用戶名輸入框綁定一個失去焦點事件
$("#username").blur(function () {
//獲取輸入的用戶名
var username = this.value;
//發出ajax請求(使用jquery的$.getJSON())
//jQuery.getJSON(url,data,success(data,status,xhr))
$.getJSON(
"memberServlet",
//使用json格式發送數據
{
"action": "isExistUserName",
"username": username,
},
function (data) {
if (data.isExist) {
$("span.errorMsg").text("用戶名已經存在,不能使用");
} else {
$("span.errorMsg").text("用戶名可用");
}
})
})
29.4完成測試
30.功能28-Ajax添加購物車
30.1需求分析/圖解
當前每次添加家居到購物車方式,每次都需要sendRedirect(),會刷新整個頁面,數據傳輸開銷大
實際上添加家居到購物車,整個頁面只需要刷新購物車的數量
因此使用ajax進行優化,只要刷新購物車的數量即可
30.2思路分析
30.3代碼實現
30.3.1web層
CartServlet:
/**
* 添加家居數據到購物車-Ajax方式
*
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void addItemByAjax(HttpServletRequest req, HttpServletResponse resp) throws IOException {
//得到添加的家居ID
int id = DataUtils.parseInt(req.getParameter("id"), 0);
//獲取到id對應的Furn對象
Furn furn = furnService.queryFurnById(id);
if (furn == null || furn.getStock() == 0) {//如果沒有對應的家居信息或者該家居庫存為0
return;//結束業務
}
//根據furn構建CartItem
CartItem item =
new CartItem(furn.getId(), furn.getName(), furn.getPrice(), 1, furn.getPrice());
//從session獲取cart對象
Cart cart = (Cart) req.getSession().getAttribute("cart");
if (null == cart) {//如果當前的session沒有cart對象
//創建一個cart對象
cart = new Cart();
//將其放入到session中
req.getSession().setAttribute("cart", cart);
}
//將cartItem加入到cart對象
cart.addItem(item);
//添加完畢後,將當前購物車的商品數量以json形式的數據返回
//前端得到json後進行局部刷新即可
//1.規定json格式{"cartTotalcount,3"}
Map<String, Object> resultMap = new HashMap<>();
//2.創建map
resultMap.put("cartTotalcount", cart.getTotalCount());
//3.轉為json
String resultJson = new Gson().toJson(resultMap);
resp.getWriter().write(resultJson);
}
30.3.2前端
customer/index.jsp
//給add to cart綁定事件
$("button.add-to-cart").click(function () {
//獲取到點擊的furn-id
var furnId = $(this).attr("furnId");
//發出一個請求-添加家居=>後面改成ajax
//location.href = "cartServlet?action=addItem&id=" + furnId;
//改為ajax請求,得到數據進行局部刷新,解決刷新這個頁面的效率低的問題
//jQuery.getJSON(url,data,success(data,status,xhr))
$.getJSON(
"cartServlet",
{
"action": "addItemByAjax",
"id": furnId
},
function (data) {
//刷新局部 <span class="header-action-num">
$("span.header-action-num").text(data.cartTotalCount)
}
)
})
30.3.3解決ajax請求轉發失效的問題
測試上面的代碼,會發現針對ajax的重定向和請求轉發失效了,AuthFilter.java的許可權攔截沒有用了,即我們點擊add to cart,後臺服務沒有響應,怎麼辦?
使用ajax向後臺發送請求跳轉頁面無效的原因:
- 主要是伺服器得到的是ajax發送過來的request,這個請求不是瀏覽器發送的請求,而是ajax請求的。因此servlet對request進行請求轉發或者重定向都不能影響瀏覽器的跳轉
- 這時就出現了請求轉發和重定向失效的問題
- 解決方案:如果想要實現跳轉,可以返回url,在瀏覽器執行window.location(url)
utils包WebUtils:
package com.li.furns.utils;
import javax.servlet.http.HttpServletRequest;
/**
* @author 李
* @version 1.0
*/
public class WebUtils {
/**
* 判斷一個請求是否是ajax請求
*
* @param request
* @return
*/
public static boolean isAjaxRequest(HttpServletRequest request) {
return "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));
}
}
AuthFilter:
package com.li.furns.filter;
import com.google.gson.Gson;
import com.li.furns.entity.Member;
import com.li.furns.utils.WebUtils;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
/**
* 這是用於許可權驗證的過濾器,對指定的url進行驗證
* 如果登錄過,就放行;如果沒有登錄,就返回登錄頁面
*
* @author 李
* @version 1.0
*/
public class AuthFilter implements Filter {
//後面我們把要排除的url放入到excludedUrls中
private List<String> excludedUrls;
public void init(FilterConfig config) throws ServletException {
//獲取到配置的excludedUrls
String strExcludedUrls = config.getInitParameter("excludedUrls");
//進行分割
String[] splitUrl = strExcludedUrls.split(",");
//將splitUrl轉成List,賦給excludedUrls
excludedUrls = Arrays.asList(splitUrl);
System.out.println("excludedUrls=>" + excludedUrls);
}
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
//許可權驗證
HttpServletRequest req = (HttpServletRequest) request;
//得到請求的url
String url = req.getServletPath();
//判斷是否要驗證
if (!excludedUrls.contains(url)) {//如果url不在配置的規則中,就進行校驗
//得到session中的member對象
Member member = (Member) req.getSession().getAttribute("member");
if (member == null) {//說明用戶沒有登錄過
//先判斷該請求是否為Ajax請求
if (!WebUtils.isAjaxRequest(req)) {//不是ajax請求
//轉發到登錄頁面
//不要使用重定向,因為重定向的url符合過濾器規則時也會被攔截,
//如果設置不合理就會出現 請求無線迴圈重定向的 情況
req.getRequestDispatcher("/views/member/login.jsp").forward(request, response);
} else {//如果是ajax請求
//以json格式返回一個url
HashMap<String, Object> resultMap = new HashMap<>();
resultMap.put("url", "views/member/login.jsp");
String resultJson = new Gson().toJson(resultMap);
response.getWriter().write(resultJson);
}
return;//返回
}
}
//否則就放行
chain.doFilter(request, response);
}
}
修改前端介面customer/index.jsp
//給add to cart綁定事件
$("button.add-to-cart").click(function () {
//獲取到點擊的furn-id
var furnId = $(this).attr("furnId");
//發出一個請求-添加家居=>後面改成ajax
//location.href = "cartServlet?action=addItem&id=" + furnId;
//改為ajax請求,得到數據進行局部刷新,解決刷新這個頁面的效率低的問題
//jQuery.getJSON(url,data,success(data,status,xhr))
$.getJSON(
"cartServlet",
{
"action": "addItemByAjax",
"id": furnId
},
function (data) {
if (data.url == undefined) {
//說明沒有返回url,過濾器沒有讓跳轉到登錄頁面,即說明已經登錄過了
$("span.header-action-num").text(data.cartTotalCount);
} else {
//否則說明當前伺服器返回了url,要求定位
location.href = data.url;
}
}
)
})
30.4完成測試
沒有登錄的情況下,點擊add to cart,頁面成功跳轉到login.jsp
登錄後,點擊添加購物車,成功添加
31.功能29-上傳/更新家居圖片
31.1需求分析/圖解
- 後臺修改家居,可以點擊圖片,選擇新的圖片
- 這裡會使用到文件上傳功能