1 課程補充
1.1 分片高階
1.1.1 如何理解分片多個key
說明:
分片對外的統一的整體,內部由多個redis共同維護,維護的記憶體是多臺redis的記憶體之和.
1.1.2 如果set(Key),通過haxi計算只能落入到唯一的一個node節點中,所以即使通過非法的操作手動為某一個節點set(key).它也不違反雜湊一致性.因為取值時該key永遠不會被獲取.
1.2 工廠介紹
1.2.1 靜態工廠
- 編輯配置檔案
<!--靜態工廠 --> <bean id="calendarA" class="java.util.Calendar" factory-method="getInstance"/> //測試靜態工廠 @Test public void test01(){ //建立spring容器 ApplicationContext context = new ClassPathXmlApplicationContext("/spring/applicationContext-factory.xml"); System.out.println("容器建立成功"); Calendar calendar = (Calendar) context.getBean("calendarA"); System.out.println(calendar.getTime()); }
說明:靜態工廠的使用:
當類不能直接例項化時,採用靜態工廠的方式.其呼叫的方法其實就是Class.靜態方法.
1.2.2 例項化工廠
說明:例項化工廠其實就是先建立工廠物件,之後代用工廠的方法建立需要物件
NewFacotry factory = new NewFactory();
Item item = factory.getItem();
<!--例項化工廠 1.會建立工廠物件 2.通過物件呼叫工廠方法 --> <bean id="newFactory" class="com.jt.manage.factory.NewInstanceFactory"/> <bean id="item" factory-bean="newFactory" factory-method="getItem"/>
測試類:
@Test public void test02(){ //建立spring容器 ApplicationContext context = new ClassPathXmlApplicationContext("/spring/applicationContext-factory.xml"); System.out.println("容器建立成功"); Item item = (Item) context.getBean("item"); System.out.println(item); }
1.2.3 Spring工廠模式
說明:Spring工廠模式需要實現指定的介面FacotryBean<T>介面,那麼當Spring容器在解析bean時,會自動的呼叫介面方法建立物件
public class ItemFactory implements FactoryBean<Item>{ @Override public Item getObject() throws Exception { System.out.println("我是spring工廠開始例項化物件"); return new Item(); } @Override public Class<?> getObjectType() { // TODO Auto-generated method stub return Item.class; } //是否為單例物件 @Override public boolean isSingleton() { // TODO Auto-generated method stub return false; } }
程式碼測試:
2 京淘專案的前臺搭建
2.1 前臺搭建
2.1.1 專案說明
說明:前臺系統只負責資料的展現.獲取商品資料時需要通過遠端呼叫從後臺系統中獲取Item資料.
框架的選擇:SpringMVC/Spring
2.2 建立前臺專案
2.2.1 建立專案
1.選擇骨架
- 編輯名稱
- 修改JDK 補齊檔案包
- 繼承jt-parent 之後儲存
- 依賴工具類
2.2.2 引入tomcat外掛
<!--引入tomcat外掛 將原有的build刪除 第8行 -->
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>8092</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
- 配置tomcat啟動
2.2.3 引入配置檔案
2.2.4 引入靜態資原始檔
說明:將課前資料中的webapp檔案匯入
2.2.5 修改web.xml檔案
1.將spring監聽器的方式註釋或刪除
2.修改前端控制器的檔案
2.2.6 修改springMVC的配置檔案
2.2.7 修改spring的配置檔案
將多餘的properties刪除.
2.3 京淘首頁跳轉
2.3.1 編輯Controller
@Controller
public class IndexController {
//實現京淘前臺頁面跳轉 localhost:8092/index.html
@RequestMapping("/index")
public String index(){
return "index";
}
頁面展現效果:
2.4 Nginx管理京淘前臺
2.4.1 修改nginx配置
#京淘前臺管理
server {
listen 80;
server_name www.jt.com;
#頁面轉向 轉向的是一個具體的url
location / {
proxy_pass http://localhost:8092;
}
}
2.修改hosts檔案
# 京淘電商環境
127.0.0.1 image.jt.com
127.0.0.1 manage.jt.com
127.0.0.1 www.jt.com
127.0.0.1 sso.jt.com
127.0.0.1 cart.jt.com
127.0.0.1 order.jt.com
127.0.0.1 solr.jt.com
2.5 跨域問題
2.5.1 跨域的測試
說明:
根據url的不同,會生跨域的問題.跨域問題是Http協議的禁止訪問的,出於安全性的考慮.
說明:通過圖上所示,瀏覽器不能直接解析跨域的檔案.
2.5.2 用域和跨域
同域:
域名相同
埠號相同
通訊協議相同
案例:
1.訪問檔案不同
http://www.a.com/a.js
同域
2.訪問路徑不用
同域
3.埠號不同
4.通訊協議不同
http://www.a.com/b.js
2.6 解決跨域
2.6.1 原理說明
說明:利用javaScript中src屬性實現跨域訪問.因為src瀏覽器沒有限制.
根據js呼叫的函式的名稱,對指定的JSON資料進行包裝 函式名({JSON資料}).
通過該方式實現跨域訪問.
<title>測試JSON跨域問題</title>
<script type="text/javascript">
/*引用src中的JS函式 */
function tarena(data){
alert(data.name);
}
</script> <!-- hello({"id":"1","name":"tom"}) -->
<script type="text/javascript" src="http://manage.jt.com/test.json"></script>
<script type="text/javascript" src="http://manage.jt.com/js/jquery-easyui-1.4.1/jquery.min.js"></script>
</head>
遠端JSON資料
2.7 JSONP
2.7.1 介紹
2.7.2 用法
說明:
- 採用JSONP的呼叫返回的格式是一個JSON
- JSONP在進行資料傳參時會新增callback=函式名稱.該名稱需要服務端動態獲取後,動態的拼接JSON資料=函式名稱({JSON資料})
案例:
url:
localhost:8092/findUser?callback=findUser
服務端編輯JSON資料
public String findUser(String callback){
User user = userService.findUser();
String JSON = User的json串
Return “callback+”(”+JSON +”)”
}
2.8 三級商品分類選單實現
2.8.1 分析頁面
說明:京淘的前端頁面是web前端開發工程師完成.都是需要和後端工程師配合一起完成.
2.8.2 JSON資料的分析
分析:
- 最外層只有一個屬性的物件 屬性型別 List<?> data
- 分析:根據圖中所示.一級商品的分類選單中需要包含3個屬性 u:n:i.
3.二級商品分類選單和一級相同
4.三級商品分類用字串編輯
2.8.3 編輯後臺Controller
2.8.4 編輯Service
/* * 分析: 由於商品的分類資訊較多,如果按照1級查詢2級查詢3級這樣的結構 * 會查詢很多次,資料庫壓力較大 * 解決: * 首先查詢全部的商品分類資訊.之後進行資料的整理 * Map<parentId,List<ItemCat> itemcatLists> * parentId 表示父級的Id * itemCatLists.表示的是當前父級Id下所有的子級選單 * * 步驟: * 1.封裝一級商品分類資訊 * 2.封裝二級商品分類資訊 * 3.封裝三級商品分類資訊 * */ @Override public ItemCatResult findItemCatAll() { //查詢全部的商品分類資訊 ItemCat tempItemCat = new ItemCat(); tempItemCat.setStatus(1); //查詢正常的商品分類資訊 List<ItemCat> itemCatLists = itemCatMapper.select(tempItemCat); //整理資料 Map<Long, List<ItemCat>> itemCatMap = new HashMap<Long, List<ItemCat>>(); for (ItemCat itemCat : itemCatLists) { if(itemCatMap.containsKey(itemCat.getParentId())){ //表示已經含有parentId,做資料的追加操作 itemCatMap.get(itemCat.getParentId()).add(itemCat); }else{ //為父級建立List集合 List<ItemCat> itemCatList = new ArrayList<ItemCat>(); itemCatList.add(itemCat); itemCatMap.put(itemCat.getParentId(), itemCatList); } } //構建返回物件 ItemCatResult itemCatResult = new ItemCatResult(); //封裝一級商品分類選單 List<ItemCatData> itemCatDataList = new ArrayList<ItemCatData>(); for (ItemCat itemCat1 : itemCatMap.get(0L)) { //定義一級商品分類物件 ItemCatData itemCatData1 = new ItemCatData(); itemCatData1.setUrl("/products/"+ itemCat1.getId()+".html"); itemCatData1.setName ("<a href='"+itemCatData1.getUrl()+"'>"+itemCat1.getName()+"</a>"); //封裝商品分類的二級選單 List<ItemCatData> itemCatDataList2 = new ArrayList<ItemCatData>(); for (ItemCat itemCat2 : itemCatMap.get(itemCat1.getId())) { ItemCatData itemCatData2 = new ItemCatData(); itemCatData2.setUrl("/products/"+itemCat2.getId()); itemCatData2.setName(itemCat2.getName()); //準備三級商品分類選單 List<String> itemCatDataList3 = new ArrayList<String>(); for (ItemCat itemCat3 : itemCatMap.get(itemCat2.getId())) { itemCatDataList3.add("/products/"+itemCat3.getId() + "|" +itemCat3.getName()); } //將三級分類的集合注入到二級物件中 itemCatData2.setItems(itemCatDataList3); itemCatDataList2.add(itemCatData2); } itemCatData1.setItems(itemCatDataList2); itemCatDataList.add(itemCatData1); //封裝引數 多餘的直接跳出 if(itemCatDataList.size() >13) break; } //封裝一級商品分類的選單 itemCatResult.setItemCats(itemCatDataList); return itemCatResult; }
2.8.5 工具類方法操作JSONP
/** * 利用工具類直接返回JSONP的物件 callback({JSON}) * @param callback * @return */ @RequestMapping("/web/itemcat/all") @ResponseBody public Object findItemCat(String callback){ ItemCatResult itemCatresult = itemCatService.findItemCatAll(); //負責JSONP物件返回 構造方法中新增返回的資料 MappingJacksonValue jacksonValue = new MappingJacksonValue(itemCatresult); //設定返回值方法 jacksonValue.setJsonpFunction(callback); return jacksonValue; }