鳴謝:http://www.shuyangyang.com.cn/jishuliangongfang/qianduanjishu/2014-02-18/196.htmljavascript
-------------------------------------------------------------------------------------------css
說明:本節採用技術:SpringMVC+ExtJs4.2+Maven+MySQL5.1以上+SLF4J(前幾節學習的你們不知道記住了沒,如今來總結複習下,順便加點新技術)html
學習本節前的準備:Eclipse高版本,Maven插件,JDK1.7java
項目:shuyangyangmysql
1、準備工做,建立MySQL數據庫shuyangyangweb
/* Navicat MySQL Data Transfer Source Server : localhost Source Server Version : 50133 Source Host : localhost:3306 Source Database : shuyangyang Target Server Type : MYSQL Target Server Version : 50133 File Encoding : 65001 Date: 2014-02-18 23:04:49 */ SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for `t_users` -- ---------------------------- DROP TABLE IF EXISTS `t_users`; CREATE TABLE `t_users` ( `ID` int(255) NOT NULL AUTO_INCREMENT, `Name` varchar(255) DEFAULT NULL, `age` smallint(6) DEFAULT NULL, `Address` varchar(255) DEFAULT NULL, `CardID` varchar(255) DEFAULT NULL, `Role` varchar(255) DEFAULT NULL, `DepartMent` varchar(255) DEFAULT NULL, `Sex` varchar(255) DEFAULT NULL, PRIMARY KEY (`ID`) ) ENGINE=MyISAM AUTO_INCREMENT=19 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of t_users -- ---------------------------- INSERT INTO t_users VALUES ('1', '張三', '20', '北京市海淀區', '342425199002131239', '普通用戶', '用戶組', '男'); INSERT INTO t_users VALUES ('2', '李四', '22', '上海市長寧區', '342425199107203116', '管理員', '管理組', '女'); INSERT INTO t_users VALUES ('3', '王五', '24', '南京市', '3426198920314669', '客服人員', '客服組', '女'); INSERT INTO t_users VALUES ('4', '趙大頭', '23', '南通市', '3424198805134567', '普通用戶', '用戶組', '男'); INSERT INTO t_users VALUES ('5', '孫國', '21', '山東省', '3526199001234569', '普通用戶', '用戶組', '男'); INSERT INTO t_users VALUES ('6', '測試', '26', 'test', '456489731312123', 'test', 'test', '男'); INSERT INTO t_users VALUES ('7', '張三1', '20', '北京市海淀區', '342425199002131239', '普通用戶', '用戶組', '男'); INSERT INTO t_users VALUES ('8', '李四1', '22', '上海市長寧區', '342425199107203116', '管理員', '管理組', '女'); INSERT INTO t_users VALUES ('9', '王五1', '24', '南京市', '3426198920314669', '客服人員', '客服組', '女'); INSERT INTO t_users VALUES ('10', '趙大頭1', '23', '南通市', '3424198805134567', '普通用戶', '用戶組', '男'); INSERT INTO t_users VALUES ('11', '孫國1', '21', '山東省', '3526199001234569', '普通用戶', '用戶組', '男'); INSERT INTO t_users VALUES ('12', '測試1', '26', 'test', '456489731312123', 'test', 'test', '男'); INSERT INTO t_users VALUES ('13', '張三2', '20', '北京市海淀區', '342425199002131239', '普通用戶', '用戶組', '男'); INSERT INTO t_users VALUES ('14', '李四2', '22', '上海市長寧區', '342425199107203116', '管理員', '管理組', '女'); INSERT INTO t_users VALUES ('15', '王五2', '24', '南京市', '3426198920314669', '客服人員', '客服組', '女'); INSERT INTO t_users VALUES ('16', '趙大頭2', '23', '南通市', '3424198805134567', '普通用戶', '用戶組', '男'); INSERT INTO t_users VALUES ('17', '孫國2', '21', '山東省', '3526199001234569', '普通用戶', '用戶組', '男'); INSERT INTO t_users VALUES ('18', '測試2', '26', 'test', '456489731312123', 'test', 'test', '男');
2、搭好框架ajax
3、最終效果,主要是框架中間的數據展現spring
前臺界面代碼(這裏給出的是數據展現層代碼):sql
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page isELIgnored="false" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>首頁</title> <link href="../ExtJS4.2/resources/css/ext-all-neptune-rtl.css" rel="stylesheet"> <script src="../ExtJS4.2/ext-all.js"></script> <script src="../ExtJS4.2/locale/ext-lang-zh_CN.js"></script> <script type="text/javascript" src="/demo/js/localXHR.js"></script> <script type="text/javascript"> Ext.onReady(function(){ //表格配置開始 // 定義列。包括定義表頭、列索引、列渲染器 var columns = [ {header:'編號',dataIndex:'id'}, {header:'名稱',dataIndex:'name'}, {header:'年齡',dataIndex:'age'}, {header:'性別',dataIndex:'sex',renderer:function(value){ if(value=='男'){ return "<span style='color:green;font-weight:bold';>男</span>"; } else { return "<span style='color:red;font-weight:bold';>女</span>"; } }}, {header:'地址',dataIndex:'address'}, {header:'身份證號碼',dataIndex:'cardId',width:150}, {header:'角色',dataIndex:'role'}, {header:'部門',dataIndex:'departMent'} ]; //定義數據。(從客戶端獲取數據並渲染爲json格式) var store = new Ext.data.Store({ pageSize:6, //每頁顯示幾條數據 proxy:{ type:'ajax', url:'/user/showUser', reader:{ //用來對服務器端響應數據進行解碼,或從客戶端讀取數據.Readers一般用於翻譯數據,使其被加載爲 Model 實例或Store. type:'json', totalProperty:'total', //檢索數據集中記錄總數. 只有在全部的數據集沒有一次獲得,而是由服務端分頁獲得時,該屬性才須要用。(Defaults to: "total") root:'data', //包含的數據項與Reader配置的Model(s)中的相符合的屬性名稱。 idProperty:'id' //主鍵。默認爲model的id. 如有特別指定一個idProperty,該值將覆蓋model中定義的idProperty. } }, fields:[ {name:'id'}, //mapping:0 這樣的能夠指定列顯示的位置,0表明第1列,能夠隨意設置列顯示的位置 {name:'name'}, {name:'age'}, {name:'sex'}, {name:'address'}, {name:'cardId'}, {name:'role'}, {name:'departMent'} ] }); //定義表格 var grid = new Ext.grid.GridPanel({ store: store,//數據 columns: columns,//列 title: '數據',//標題 region: 'center', //框架中顯示位置,單獨運行可去掉此段 loadMask:true, //顯示遮罩和提示功能,即加載Loading…… //forceFit:true //自動填滿表格 bbar:new Ext.PagingToolbar({ //bbar:便利的配置。''Bottom Bar'的縮略形式。Ext.PagingToolbar:分頁工具欄.此組件的loads塊數據存入store,經過傳遞參數用於分頁的標準。 store:store, displayInfo:true, //是否顯示數據信息 displayMsg:'顯示第 {0} 條到 {1} 條記錄,一共 {2} 條', //只要當displayInfo爲true時纔有效,用來顯示有數據時的提示信息,{0},{1},{2}會自動被替換成對應的數據 emptyMsg: "沒有記錄" //沒有數據時顯示信息 }) }); //加載數據。經過配置的 proxy 加載數據到Store 中. store.load({params:{start:0,limit:6}}); // 表格配置結束 // 樹形配置開始 var tree = new Ext.tree.TreePanel({ store: new Ext.data.TreeStore({ proxy: { type: 'ajax', url: '/demo/config/tree.txt'// 'demo/config/tree.txt'也能夠。與resource中的dispatcher-servlet.xml靜態資源映射地址一致。 }, root: {//當前store的根節點。 expand: true,//展開本節點 text: '我是根sssss' } }), title: '菜單', region: 'north',//Defines the region inside border layout.(來自Ext.Component-cfg-region,4.2版本) split: true,//全部含split:true屬性的區域都將獲得 一個Splitter並容許手動調整大小.(它是Ext.layout.container.Border中的配置,不明白爲什麼在此能調用此配置?) border: true,//指定該組件的邊框. collapsible: true,//擁有摺疊功能 width: 120, height:'80%', minSize: 80,//未找到該配置 maxSize: 200//-- }); // 樹形配置結束 //左邊下部Panel。 var detailsPanel = { id: 'details-panel', title: '信息', region: 'center', bodyStyle: 'padding-bottom:15px;background:#eee;',//用戶自定義CSS樣式被應用到panel的body元素上 (來自Ext.panel.AbstractPanel中的配置) autoScroll: true,//在panel內容溢出時自動顯示滾動條(來自Ext.Component中的配置) html: '<p class="details-info">信息顯示神馬的</p>'//一個 HTML 片斷, 或者一個 DomHelper 描述, 用做 layout 元素的內容. (來自Ext.AbstractComponent中的配置) }; // 左邊下部Panel結束 // 表單配置開始 var form = new Ext.form.FormPanel({ defaultType: 'textfield', labelAlign: 'right', title: 'form', labelWidth: 50, frame:true, width: 220, title: '圖形表格', region: 'north', items: [{ fieldLabel: '文本框', anchor: '90%' }], buttons: [{ text: '按鈕' }] }); // 表單配置結束 // 佈局開始 var viewport = new Ext.Viewport({//Viewport渲染自身到網頁的documet body區域, 並自動將本身調整到適合瀏覽器窗口的大小,在窗口大小發生改變時自動適應大小。 layout:'border', /** * items:單個組件,或者是以數組形式定義的子組件集合 將會自動添加到容器中去. * 若是子組件是指定的,它的實際組件的類型將根據xtype選項進行實例化. 每一個組件都有各自的xtype. * 若是沒有指定 xtype, 那麼將會使用 defaultType,默認是panel. * 如下items所有采用defaultType(panel) */ items:[{ region: 'north', contentEl: 'north-div',//指定一個已存在的HTML元素, 或者一個已存在HTML元素的 id , 它們將被用做當前組件的內容. height: 73, bodyStyle: 'background-color:#BBCCEE;' },{ region: 'south', contentEl: 'south-div', height: 20, bodyStyle: 'background-color:#BBCCEE;' },{ layout: 'border', id: 'layout-browser', region:'west', border: false, split:true, margins: '2 0 5 5',//上 右 下 左 (未找到此屬性的明確來源) width: 275, minSize: 100, maxSize: 500, items: [tree, detailsPanel] },{ region: 'center', split: true, border: true, layout: 'border', items: [grid,form] }] }); // 佈局結束 }); </script> </head> <body> <div id="north-div" style="height: 73px; background-color: #101010;"><img alt="思考者日記網|束洋洋我的博客" src="/demo/image/shuyangyang_01.jpg"></div> <div id="south-div" align="center">Copyright by 束洋洋© www.shuyangyang.com.cn <a href="${pageContext.request.contextPath}/index.jsp">返回主頁</a> </div> <div id="div2" ><input id="inputTest" value="name">input</div> </body> </html>
解析:數據庫
GridPanel如何獲取服務端的數據?
看一下這裏的代碼:
//定義數據。(從客戶端獲取數據並渲染爲json格式) var store = new Ext.data.Store({ pageSize:6, //每頁顯示幾條數據 proxy:{ type:'ajax', url:'/user/showUser', reader:{ //用來對服務器端響應數據進行解碼,或從客戶端讀取數據.Readers一般用於翻譯數據,使其被加載爲 Model 實例或Store. type:'json', totalProperty:'total', //檢索數據集中記錄總數. 只有在全部的數據集沒有一次獲得,而是由服務端分頁獲得時,該屬性才須要用。(Defaults to: "total") root:'data', //包含的數據項與Reader配置的Model(s)中的相符合的屬性名稱。 idProperty:'id' //主鍵。默認爲model的id. 如有特別指定一個idProperty,該值將覆蓋model中定義的idProperty. } }, fields:[ {name:'id'}, //mapping:0 這樣的能夠指定列顯示的位置,0表明第1列,能夠隨意設置列顯示的位置 {name:'name'}, {name:'age'}, {name:'sex'}, {name:'address'}, {name:'cardId'}, {name:'role'}, {name:'departMent'} ] });
Extjs是採用代理的方式,以ajax的提交方式從服務端獲取數據的,並將它渲染爲Extjs支持的json格式。
先看一下服務端返回的數據格式:
打印的數據以下:(爲了方便看清,下面的數據只保留了2個User)
Response{success=true, code=OK, message='',
data=[User{id=11, name='孫國1', age=21, sex='男', address='山東省', cardId='3526199001234569', role='普通用戶', departMent='用戶組'},
User{id=18, name='測試2', age=26, sex='男', address='test', cardId='456489731312123', role='test', departMent='test'}],
total=18}
由此能夠看出,store定義的fields的name的屬性值與以上數據的data中的字段名是對應的,由此來解析數據;而reader中的totalProperty的屬性值對應以上數據的total——來獲取總記錄數,root的屬性值對應以上數據的data——來獲取數據,idProperty定義的是每一行記錄的主鍵,對應以上數據的id字段。
這裏的url請求地址是/user/showUser,這裏請求的是SpringMVC的地址,看下面的Controller代碼:
package com.shyy.web.controller.anntation; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import com.shyy.web.controller.response.EmptyResponse; import com.shyy.web.controller.response.NormalResponse; import com.shyy.web.controller.response.Response; import com.shyy.web.entity.User; import com.shyy.web.service.UserService; import com.shyy.web.service.impl.UserServiceImpl; @Controller @RequestMapping("/user/") public class UserController { Logger logger = LoggerFactory.getLogger(UserController.class); UserService userService = new UserServiceImpl(); /** * SpringMVC返回json數據 * @return */ @RequestMapping("showUser") @ResponseBody public Response resp(HttpServletRequest req, HttpServletResponse resp){ String start = req.getParameter("start");//起始頁 String limit = req.getParameter("limit");//每頁數量 int index = Integer.parseInt(start); int pageSize = Integer.parseInt(limit); System.out.println(index+"-qqqqqqqqqqqq-"+pageSize); List<User> list = userService.query(index,pageSize); //獲取全部用戶數據 long total = list.size(); if(total>0){ logger.debug("now {}" , "返回用戶數據。。。"); Response r=new NormalResponse(list,userService.total()); // System.out.println("後臺的數據格式:"+r); return r; }else{ logger.debug("now {}" , "用戶數據爲空!"); return new EmptyResponse(); } } @RequestMapping("mytest") public String test(){ return "wang"; } }
最後的NormalResponse返回的是我封裝的一個返回對象,以下代碼所示:
package com.shyy.web.controller.response; public class NormalResponse extends Response { public NormalResponse(Object data) { this.setCode(ResponseCode.OK); this.setMessage(""); this.setData(data); this.setSuccess(true); } public NormalResponse(Object data, Long total) { this.setCode(ResponseCode.OK); this.setMessage(""); this.setData(data); this.setSuccess(true); this.setTotal(total); } public NormalResponse() { this.setCode(ResponseCode.OK); this.setMessage(""); this.setData(null); this.setSuccess(true); } }
附:1.此項目的pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.wql</groupId> <artifactId>shuyangyang</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>shuyangyang Maven Webapp</name> <url>http://maven.apache.org</url> <properties> <spring.version>4.1.1.RELEASE</spring.version> </properties> <dependencies> <!-- spring-core --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <!-- spring-web --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <!-- spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <!-- spring-test --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> <scope>test</scope> </dependency> <!-- servlet-api --> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <!-- Jsp Support --> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.1</version> <scope>provided</scope> </dependency> <!-- MySQL --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.26</version> </dependency> <!--jackson --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.2.3</version> </dependency> <!-- SLF4J --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.2</version> </dependency> </dependencies> <build> <finalName>shuyangyang</finalName> </build> </project>
說明:
1.其中的依賴spring-core與spring-web可用一個依賴——spring context代替:
<!--spring context --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.0.0.RELEASE</version> </dependency>
2.其中的jackson是解析json格式數據的。若是漏掉會報406錯誤:Failed to load resource: the server responded with a status of 406 (Not Acceptable)
3.spring-test是springMVC的測試依賴。
4.SLF4J是日誌依賴,它用於在項目中記載日誌。
2.此項目的資源文件:
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <context:component-scan base-package="com.shyy.web"/> </beans>
dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="com.shyy.web.controller.anntation"/> <mvc:annotation-driven/> <!-- 靜態文件的訪問 --> <mvc:resources location="/ExtJS4.2/" mapping="/ExtJS4.2/**"/> <mvc:resources location="/demo/image/" mapping="/demo/image/**"/> <mvc:resources location="/demo/js/" mapping="/demo/js/**"/> <mvc:resources location="/demo/config/" mapping="/demo/config/**"/> <!-- 視圖解析器 --> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 視圖前綴 --> <property name="prefix" value="/"></property> <!-- 視圖後綴 --> <property name="suffix" value=".jsp"></property> </bean> </beans>
3.此項目的web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>Archetype Created Web Application</display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:dispatcher-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <filter> <filter-name>changMethod</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> </filter> <filter-mapping> <filter-name>changMethod</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
後記:1.原做者博文中提到的Jetty尚且不知有何用途;2.Extjs像java那樣存在繼承特性,所以有些像本博文的js代碼中涉及到的未發現有繼承關係的卻能夠調用其屬性不太明白;其次本博客用的是Extjs4.2版本,但本博文的js代碼中涉及到的一些屬性卻未能在官方API中找到。3.前面提到的Extjs的分頁問題在此博客已解決。4.此博客中涉及的項目對原博文中分享的項目做了簡化和整理,如須要聯繫我:18681199407,qq:472543236.