在shopback項(xiàng)目的WEB下新建登陸頁面,利用ajax或者form表單進(jìn)行登陸業(yè)務(wù)設(shè)計(jì),
//三層? web service Dao
依舊是mvc模型,三層架構(gòu)細(xì)分control層,
首先用戶在jsp頁面登陸,web層接收數(shù)據(jù),調(diào)用其他層判斷登陸是否成功,存放登陸標(biāo)志,在利用分頁技術(shù)獲取初始頁及頁面長(zhǎng)度等信息,然后然后多表查詢獲取商品詳細(xì)信息放入list<Goods>,在goodsBean中增加相應(yīng)查詢的字段名作為成員變量,提供set、get方法。
之后在頁面接收的list中,利用導(dǎo)入包jstl的c:foreach方法遍歷展示list每一個(gè)goods元素,在其前后增加修改刪除等超鏈接,調(diào)用相應(yīng)函數(shù)傳遞當(dāng)前goods的id,利用ajax進(jìn)行后臺(tái)web層增刪查改,返回成功或失敗信息封裝進(jìn)ResponseMessage中,利用json工具包,返回json對(duì)象到前臺(tái),前臺(tái)再根據(jù)返回結(jié)果進(jìn)行相應(yīng)處理。
至于文件上傳,及圖像上傳,可以在項(xiàng)目中編寫上傳下載servlet,也可自定義一個(gè)文件服務(wù)器,進(jìn)行文件的上傳下載,在服務(wù)器或上傳類中,編寫保存的位置,返回給請(qǐng)求端。下載類則根據(jù)請(qǐng)求地址,找到地址中的相應(yīng)文件并寫回。
同源策略
同源 : ip+port+… 相同
瀏覽器禁止js訪問和當(dāng)前頁面不同源的服務(wù)器
瀏覽器禁止不同源的頁面中的js獲取對(duì)方的cookie
瀏覽器發(fā)送到服務(wù)器的請(qǐng)求會(huì)默認(rèn)攜帶cookie信息,如果用戶訪問了惡意頁面, 惡意頁面中有ajax悄悄的訪問用戶
跨域(跨源)
有的時(shí)候, 我們自己的兩個(gè)服務(wù)器之間需要相符訪問, 這時(shí), 就必須要跨域了, 比如說,圖片服務(wù)器和本地服務(wù)器就屬于不同源
要解決跨域問題, 就需要瀏覽器和服務(wù)器相互配合,瀏覽器發(fā)出跨域請(qǐng)求, 服務(wù)器允許跨域請(qǐng)求
兩種請(qǐng)求
簡(jiǎn)單請(qǐng)求, 同時(shí)滿足一下兩個(gè)條件
請(qǐng)求方法是以下三種方法之一:
? HEAD
? GET
? POST
HTTP的頭信息不超出以下幾種字段:
? Accept
? Accept-Language
? Content-Language
? Last-Event-ID
? Content-Type:只限于三個(gè)值application/x-www-form-urlencoded、multipart/form-data、text/plain
非簡(jiǎn)單請(qǐng)求: 不能同時(shí)滿足以上兩個(gè)條件
簡(jiǎn)單請(qǐng)求基本流程
瀏覽器如果發(fā)現(xiàn)是跨域請(qǐng)求, 就會(huì)在請(qǐng)求頭中添加Origin字段,該字段的值為當(dāng)前域名
? ? ? ? ? ? ? ? ? 服務(wù)器收到請(qǐng)求后,檢查這個(gè)字段的值, 判斷是否允許這個(gè)域名下的請(qǐng)求跨域進(jìn)來
如果允許的話, 就需要在響應(yīng)中返回特殊字段, 字段的值要設(shè)置為允許請(qǐng)求的域名
當(dāng)瀏覽器接受到請(qǐng)求,檢查服務(wù)返回的特殊字段,如果這個(gè)特殊字段中記錄的值是符合當(dāng)前域名, 才會(huì)將返回的數(shù)據(jù)傳遞給js的接收方法,否則就報(bào)錯(cuò)
Access-Control-Allow-Origin: http://localhost:8080
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: FooBar
Content-Type: text/html; charset=utf-8
非簡(jiǎn)單請(qǐng)求基本流程
非簡(jiǎn)單請(qǐng)求的CORS請(qǐng)求,會(huì)在正式通信之前,增加一次HTTP查詢請(qǐng)求,稱為"預(yù)檢"請(qǐng)求(preflight),就請(qǐng)求當(dāng)前url指向的Servlet中的 OPTIONS方法
如果 OPTIONS 方法返回的信息中沒有允許的特殊字段, 瀏覽器就會(huì)拒絕發(fā)起正式請(qǐng)求
除了Origin字段,"預(yù)檢"請(qǐng)求的頭信息包括兩個(gè)特殊字段。
Access-Control-Request-Method
該字段是必須的,用來列出瀏覽器的CORS請(qǐng)求會(huì)用到哪些HTTP方法,上例是PUT。
Access-Control-Request-Headers
該字段是一個(gè)逗號(hào)分隔的字符串,指定瀏覽器CORS請(qǐng)求會(huì)額外發(fā)送的頭信息字段,上例是X-Custom-Header
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: X-Custom-Header
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 1728000
復(fù)選框分類查詢
在goodsbean中加入typeIds[]成員變量
根據(jù)typeid數(shù)組內(nèi)容查詢,
并把傳過去的goods類,在返回前端頁面進(jìn)行回顯。判斷已選擇的typeid和所有typeId如果相同,則checked=cheked;
<form action="/shop/toMainPage" id="form">
<input id="search" name="name" value="${goods.name}"><button>搜索</button><br>
類型 :
<c:forEach items="${types}" var="item">
<%--form表單提交參數(shù)的時(shí)候,可以一個(gè)參數(shù)對(duì)應(yīng)多個(gè)值--%>
? ? ? ? ${item.name}<input type="checkbox" name="typeIds" value="${item.id}" onclick="cc()"
? ? ? ? <c:forEach items="${goods.typeIds}" var="typeId">? ? ? ? ? ? ? ? ? ? ? ? ? <c:if test="${typeId==item.id}">checked="checked"</c:if>? ? ? ? </c:forEach>? ? >
</c:forEach>
</form>
dao層 查詢數(shù)據(jù)時(shí),加入name like條件
public List getGoods(Goods goods){
Connection cn =null;
PreparedStatement ps =null;
ResultSet rs =null;
try {
cn = JDBCUtils.getConnection();
//拼接預(yù)制型sql語句
? ? ? ? //sql語句中每拼接一個(gè)問號(hào), 就需要往數(shù)組中存入一個(gè)對(duì)應(yīng)的值,
? ? ? ? //// 這樣,我們就可以知道總共有幾個(gè)問號(hào),而且對(duì)應(yīng)的值的順序還是正確的
? ? ? ? List objects =new ArrayList<>();
//基礎(chǔ)sql語句
? ? ? ? String sql ="select * from goods where status=1 ";
//如果有商品名稱傳遞過來, 拼接到sql中
? ? ? ? if(goods.getName()!=null){
sql +=" and name like ?";
objects.add("%"+goods.getName()+"%");
}
//如果有類型id傳遞過來,拼接到sql中,注意, 類型id可能時(shí)多個(gè)
? ? ? ? if(goods.getTypeIds()!=null){
sql +=" and typeId in (" ;
int[] typeIds = goods.getTypeIds();//遍歷類型id
? ? ? ? ? ? for (int i =0; i < typeIds.length; i++) {
if(i==typeIds.length-1){
sql +="? )";
}else{
sql +="? , ";
}
}
objects.add(goods.getTypeIds());
}
ps = cn.prepareStatement(sql+" limit ? , ?");
//設(shè)置sql語句對(duì)應(yīng)的參數(shù)值
? ? ? ? int n =0;//記錄已經(jīng)設(shè)置了多少個(gè)參數(shù)值
? ? ? ? for (Object object : objects) {
//如果拿到的值時(shí)一個(gè)數(shù)組, 需要轉(zhuǎn)換并遍歷
? ? ? ? ? ? if(object.getClass().isArray()){
int[] typeIds = (int[]) object;
for (int i =0; i
n++;
ps.setObject(n,typeIds[i]);
}
}else{
n++;
ps.setObject(n,object);
}
}
ps.setInt(n+1,goods.getStart());
ps.setInt(n+2,goods.getPageSize());
rs = ps.executeQuery();
List list = DBUtils.selectMore(Goods.class,rs);
return list;
}catch (Exception? e){
e.printStackTrace();
}finally {
JDBCUtils.close(rs,ps,cn);
}
return null;
}