整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          關于ExtJS與JQuery對比

          先分別介紹一下ExtJS和JQuery,然后進行對比分析

          一、什么是ExtJS?

          1、ExtJS可以用來開發RIA也即富客戶端的AJAX應用,是一個用javascript寫的,主要用于創建前端用戶界面,是一個與后臺技術無關的前端ajax框架。因此,可以把ExtJS用在.Net、Java、Php等各種開發語言開發的應用中。ExtJs最開始基于YUI技術,由開發人員JackSlocum開發,通過參考JavaSwing等機制來組織可視化組件,無論從UI界面上CSS樣式的應用,到數據解析上的異常處理,都可算是一款不可多得的JavaScript客戶端技術的精品。

          2、Ext的UI組件模型和開發理念脫胎、成型于Yahoo組件庫YUI和Java平臺上Swing兩者,并為開發者屏蔽了大量跨瀏覽器方面的處理。相對來說,EXT要比開發者直接針對DOM、W3C對象模型開發UI組件輕松。

          二、什么是JQuery?

          jQuery是一個兼容多瀏覽器的javascript框架,核心理念是write less,do more(寫得更少,做得更多)。jQuery在2006年1月由美國人John Resig在紐約的barcamp發布,吸引了來自世界各地的眾多JavaScript高手加入,由Dave Methvin率領團隊進行開發。如今,jQuery已經成為最流行的javascript框架,在世界前10000個訪問最多的網站中,有超過55%在使用jQuery。

          jQuery是免費、開源的,使用MIT許可協議。jQuery的語法設計可以使開發者更加便捷,例如操作文檔對象、選擇DOM元素、制作動畫效果、事件處理、使用Ajax以及其他功能。除此以外,jQuery提供API讓開發者編寫插件。其模塊化的使用方式使開發者可以很輕松的開發出功能強大的靜態或動態網頁。

          三、二者對比

          1.JQuery-EasyUI是仿照Ext做的。

          2.Ext框架是一個整體,面向對象的編程思想,每個控件之間可以相互通訊。

          3.JQuery的控件全都是分散的,沒有整體性可言。你可以單獨拿出來一個控件就能用。

          4.若要開發系統應用,首選Ext,控件庫豐富,擴展和維護都方便。若是簡單的頁面動畫和效果,首選JQuery

          5.jquery只是一個工具庫,比較簡單,相對容易。 Ext是一套真正的ria開發框架,甚至可以實現桌面應用一樣的強大功能。本身代碼質量極高,而且是高度的面向對象設計。jQuery 入門相對容易一些,實際用的過程中要用到各種插件,基本上用一個“學”一個。 ExtJS 入門稍難。

          6.大小比較:首先ExtJS是一個完整的Framework,是重量級別的,easy ui 是基于jquery庫的一套UI組件庫,是輕量級的,ExtJS是應用application級的,而jquery是page頁面級的。當然application也是由page組成的,那就需要你自己去完成了,考慮你的需求,和使用框架的初衷,選擇使用哪一種。同時ExtJs由于是重量級框架,完全面向對象風格,提供API非常完備也非常龐大,所以學習成本也想相對較大。

          7.兼容性比較:ExtJS兼容IE全系列瀏覽器和其他非IE現代瀏覽器,jquery UI向來不太考慮ie低版本瀏覽器的兼容,從態度上的鄙視。easy UI是基于jquery的,jquery2.X以上的版本不再支持IE6、7、8,,已鄭重聲明,請看官方網站,easyUI最新版本1.3.3使jQuery2.0,由于又很多HTML5特性,不再支持IE6,低版本由一些小部分的兼容不夠好,請自己做技術選型的時候去測試,你要使用那個版本。在兼容問題上,他們都有瑕疵,看你的接收程度。

          8.使用許可license. EXTJS 2.1以上版本,商用需要購買商業授權,jquery UI 使用MIT協議,開源。 jquery easyUI如果商用需遵循license commercial商業許可,也就是要購買使用權.

          于html5的Websocket網頁即時通訊技術,前端開發采用ExtJS前端框架

          JavaEE框架:Mybatis、SpringMVC

          先去官網下載ExtJS框架的資料文件:

          https://www.sencha.com/products/extjs/evaluate/

          可以參考中文翻譯過來的官網查看API:

          http://extjs-doc-cn.github.io/ext4api/

          下載集成的jar:


          websocket.css:

          @CHARSET "UTF-8";
          .l-im-message-warn {
           font-family: "微軟雅黑";
           cursor: default;
           width: 100%;
           padding: 5px 0px 5px 25px;
           -webkit-user-select : none;
           background: url("../images/information.png") no-repeat 5;
          }
          .l-im-message {
           font-family: "微軟雅黑";
           cursor: default;
           width: 100%;
          }
          .l-im-message-over {
           background-color: rgba(233, 233, 233, 0.5);
          }
          .l-im-message-selected {
           background-color: rgba(250, 218, 90, 0.5);
          }
          .l-im-message-header {
           font-size: 12px;
           padding: 5px 0px 5px 10px;
          }
          .l-im-message-header-self {
           color: green;
          }
          .l-im-message-header-remote {
           color: blue;
          }
          .l-im-message-body {
           font-size: 12px;
           padding: 2px 0px 2px 20px;
          }
          .user-win {
           background-image: url( ../images/user_win.png )
           !important;
          }
          .user-online {
           background-image: url( ../images/group.png )
           !important;
          }
          .user {
           background-image: url( ../images/user.gif )
           !important;
          }
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          42
          43
          44
          45
          46
          47
          48
          49
          50
          51
          52
          53
          54
          55
          56
          

          websocket.js:

          var websocket;
          var isCreatw = false;
          var title="";
          var win;
          var input;
          var isQj = true;
          var toUser="";
          function toUserMsg(toU){
           if((!isQj && toUser == toU) || toU == user){
           win.setTitle(title + " (已連接) 【現在全局對話】");
           isQj = true;
           toUser = "";
           }else{
           win.setTitle(title + " (已連接) 【現在單獨與"+toU+"對話】");
           isQj = false;
           toUser = toU;
           }
          }
           function creatw() {
           if(isCreatw){
           alert("已經啟動");
           return;
           }else{
           isCreatw = true;
           }
           //創建用戶輸入框
           input = Ext.create('Ext.form.field.HtmlEditor', {
           region : 'south',
           height : 120,
           enableFont : false,
           enableSourceEdit : false,
           enableAlignments : false,
           listeners : {
           initialize : function() {
           Ext.EventManager.on(me.input.getDoc(), {
           keyup : function(e) {
           if (e.ctrlKey === true
           && e.keyCode == 13) {
           e.preventDefault();
           e.stopPropagation();
           send();
           }
           }
           });
           }
           }
           });
           //創建消息展示容器
           var output = Ext.create('MessageContainer', {
           region : 'center'
           });
           var dialog = Ext.create('Ext.panel.Panel', {
           region : 'center',
           layout : 'border',
           items : [input, output],
           buttons : [{
           text : '發送',
           handler : send
           }]
           });
           //初始話WebSocket
           function initWebSocket() {
           if (window.WebSocket) {
           websocket = new WebSocket(encodeURI('ws://'+wimadress));
           websocket.onopen = function() {
           //連接成功
           win.setTitle(title + ' (已連接) 【現在全局對話】');
           websocket.send('admin'+user);
           }
           websocket.onerror = function() {
           //連接失敗
           win.setTitle(title + ' (連接發生錯誤)');
           }
           websocket.onclose = function() {
           //連接斷開
           win.setTitle(title + ' (已經斷開連接)');
           }
           //消息接收
           websocket.onmessage = function(message) {
           var message = JSON.parse(message.data);
           //接收用戶發送的消息
           if (message.type == 'message') {
           output.receive(message);
           } else if (message.type == 'get_online_user') {
           //獲取在線用戶列表
           var root = onlineUser.getRootNode();
           Ext.each(message.list,function(user){
           var node = root.createNode({
           id : user,
           text : user,
           iconCls : 'user',
           leaf : true
           });
           root.appendChild(node);
           });
           } else if (message.type == 'user_join') {
           //用戶上線
           var root = onlineUser.getRootNode();
           var user = message.user;
           var node = root.createNode({
           id : user,
           text : user,
           iconCls : 'user',
           leaf : true
           });
           root.appendChild(node);
           } else if (message.type == 'user_leave') {
           //用戶下線
           var root = onlineUser.getRootNode();
           var user = message.user;
           var node = root.findChild('id',user);
           root.removeChild(node);
           }
           }
           }
           };
           //在線用戶樹
           var onlineUser = Ext.create('Ext.tree.Panel', {
           title : '在線用戶',
           rootVisible : false,
           region : 'east',
           width : 150,
           lines : false,
           useArrows : true,
           autoScroll : true,
           split : true,
           iconCls : 'user-online',
           store : Ext.create('Ext.data.TreeStore', {
           root : {
           text : '在線用戶',
           expanded : true,
           children : []
           }
           })
           });
           title = '歡迎您:' + user;
           //展示窗口
           win = Ext.create('Ext.window.Window', {
           title : title + ' (未連接)',
           layout : 'border',
           iconCls : 'user-win',
           minWidth : 650,
           minHeight : 460,
           width : 650,
           animateTarget : 'websocket_button',
           height : 460,
           items : [dialog,onlineUser],
           border : false,
           listeners : {
           render : function() {
           initWebSocket();
           }
           }
           });
           win.show();
           win.on("close",function(){
           websocket.send('LeaveAdmin');
           isCreatw = false;
           });
           //發送消息
           function send() {
           var content = input.getValue();
           if(toUser != ""){content = "admin886"+toUser+"admin888" + content;}
           var message = {};
           if (websocket != null) {
           if (input.getValue()) {
           Ext.apply(message, {
           from : user,
           content : content,
           timestamp : new Date().getTime(),
           type : 'message'
           });
           websocket.send(JSON.stringify(message));
           //output.receive(message);
           input.setValue('');
           }
           } else {
           Ext.Msg.alert('提示', '您已經掉線,無法發送消息!');
           }
           }
          };
          //用于展示用戶的聊天信息
          Ext.define('MessageContainer', {
           extend : 'Ext.view.View',
           trackOver : true,
           multiSelect : false,
           itemCls : 'l-im-message',
           itemSelector : 'div.l-im-message',
           overItemCls : 'l-im-message-over',
           selectedItemCls : 'l-im-message-selected',
           style : {
           overflow : 'auto',
           backgroundColor : '#fff'
           },
           tpl : [
           '<div class="l-im-message-warn">?歡迎使用即時通訊系統。</div>',
           '<tpl for=".">',
           '<div class="l-im-message">',
           '<div class="l-im-message-header l-im-message-header-{source}">{from} {timestamp}</div>',
           '<div class="l-im-message-body">{content}</div>', '</div>',
           '</tpl>'],
           messages : [],
           initComponent : function() {
           var me = this;
           me.messageModel = Ext.define('Leetop.im.MessageModel', {
           extend : 'Ext.data.Model',
           fields : ['from', 'timestamp', 'content', 'source']
           });
           me.store = Ext.create('Ext.data.Store', {
           model : 'Leetop.im.MessageModel',
           data : me.messages
           });
           me.callParent();
           },
           //將服務器推送的信息展示到頁面中
           receive : function(message) {
           var me = this;
           message['timestamp'] = Ext.Date.format(new Date(message['timestamp']),
           'H:i:s');
           if(message.from == user){
           message.source = 'self';
           }else{
           message.source = 'remote';
           }
           me.store.add(message);
           if (me.el.dom) {
           me.el.dom.scrollTop = me.el.dom.scrollHeight;
           }
           }
          });
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          42
          43
          44
          45
          46
          47
          48
          49
          50
          51
          52
          53
          54
          55
          56
          57
          58
          59
          60
          61
          62
          63
          64
          65
          66
          67
          68
          69
          70
          71
          72
          73
          74
          75
          76
          77
          78
          79
          80
          81
          82
          83
          84
          85
          86
          87
          88
          89
          90
          91
          92
          93
          94
          95
          96
          97
          98
          99
          100
          101
          102
          103
          104
          105
          106
          107
          108
          109
          110
          111
          112
          113
          114
          115
          116
          117
          118
          119
          120
          121
          122
          123
          124
          125
          126
          127
          128
          129
          130
          131
          132
          133
          134
          135
          136
          137
          138
          139
          140
          141
          142
          143
          144
          145
          146
          147
          148
          149
          150
          151
          152
          153
          154
          155
          156
          157
          158
          159
          160
          161
          162
          163
          164
          165
          166
          167
          168
          169
          170
          171
          172
          173
          174
          175
          176
          177
          178
          179
          180
          181
          182
          183
          184
          185
          186
          187
          188
          189
          190
          191
          192
          193
          194
          195
          196
          197
          198
          199
          200
          201
          202
          203
          204
          205
          206
          207
          208
          209
          210
          211
          212
          213
          214
          215
          216
          217
          218
          219
          220
          221
          222
          223
          224
          225
          226
          227
          228
          229
          230
          231
          232
          233
          234
          235
          236
          237
          238
          239
          240
          241
          242
          243
          244
          245
          246
          247
          248
          249
          250
          251
          252
          253
          254
          

          業務代碼編寫:

          ChatServer.java

          package com.appms.websocket;
          import java.io.IOException;
          import java.net.InetSocketAddress;
          import java.net.UnknownHostException;
          import java.util.Date;
          import net.sf.json.JSONObject;
          import org.java_websocket.WebSocket;
          import org.java_websocket.WebSocketImpl;
          import org.java_websocket.framing.Framedata;
          import org.java_websocket.handshake.ClientHandshake;
          import org.java_websocket.server.WebSocketServer;
          /**
           * 即時通訊
           */
          public class ChatServer extends WebSocketServer{
           public ChatServer(int port) throws UnknownHostException {
           super(new InetSocketAddress(port));
           }
           public ChatServer(InetSocketAddress address) {
           super(address);
           }
           /**
           * 觸發連接事件
           */
           @Override
           public void onOpen( WebSocket conn, ClientHandshake handshake ) {
           }
           /**
           * 觸發關閉事件
           */
           @Override
           public void onClose( WebSocket conn, int code, String reason, boolean remote ) {
           userLeave(conn);
           }
           /**
           * 客戶端發送消息到服務器時觸發事件
           */
           @Override
           public void onMessage(WebSocket conn, String message){
           message = message.toString();
           if(null != message && message.startsWith("admin")){
           this.userjoin(message.replaceFirst("admin", ""),conn);
           }if(null != message && message.startsWith("LeaveAdmin")){
           this.userLeave(conn);
           }if(null != message && message.contains("admin886")){
           String toUser = message.substring(message.indexOf("admin886")+8, message.indexOf("admin888"));
           message = message.substring(0, message.indexOf("admin886")) +"[私信] "+ message.substring(message.indexOf("admin888")+8, message.length());
           ChatServerPool.sendMessageToUser(ChatServerPool.getWebSocketByUser(toUser),message);//向所某用戶發送消息
           ChatServerPool.sendMessageToUser(conn, message);//同時向本人發送消息
           }else{
           ChatServerPool.sendMessage(message.toString());//向所有在線用戶發送消息
           }
           }
           public void onFragment( WebSocket conn, Framedata fragment ) {
           }
           /**
           * 觸發異常事件
           */
           @Override
           public void onError( WebSocket conn, Exception ex ) {
           ex.printStackTrace();
           if( conn != null ) {
           //some errors like port binding failed may not be assignable to a specific websocket
           }
           }
           /**
           * 用戶加入處理
           * @param user
           */
           public void userjoin(String user, WebSocket conn){
           JSONObject result = new JSONObject();
           result.element("type", "user_join");
           result.element("user", "<a onclick=\"toUserMsg('"+user+"');\">"+user+"</a>");
           ChatServerPool.sendMessage(result.toString()); //把當前用戶加入到所有在線用戶列表中
           String joinMsg = "{\"from\":\"[系統]\",\"content\":\""+user+"上線了\",\"timestamp\":"+new Date().getTime()+",\"type\":\"message\"}";
           ChatServerPool.sendMessage(joinMsg); //向所有在線用戶推送當前用戶上線的消息
           result = new JSONObject();
           result.element("type", "get_online_user");
           ChatServerPool.addUser(user,conn); //向連接池添加當前的連接對象
           result.element("list", ChatServerPool.getOnlineUser());
           ChatServerPool.sendMessageToUser(conn, result.toString()); //向當前連接發送當前在線用戶的列表
           }
           /**
           * 用戶下線處理
           * @param user
           */
           public void userLeave(WebSocket conn){
           String user = ChatServerPool.getUserByKey(conn);
           boolean b = ChatServerPool.removeUser(conn); //在連接池中移除連接
           if(b){
           JSONObject result = new JSONObject();
           result.element("type", "user_leave");
           result.element("user", "<a onclick=\"toUserMsg('"+user+"');\">"+user+"</a>");
           ChatServerPool.sendMessage(result.toString()); //把當前用戶從所有在線用戶列表中刪除
           String joinMsg = "{\"from\":\"[系統]\",\"content\":\""+user+"下線了\",\"timestamp\":"+new Date().getTime()+",\"type\":\"message\"}";
           ChatServerPool.sendMessage(joinMsg); //向在線用戶發送當前用戶退出的消息
           }
           }
           public static void main( String[] args ) throws InterruptedException , IOException {
           WebSocketImpl.DEBUG = false;
           int port = 8887; //端口
           ChatServer s = new ChatServer(port);
           s.start();
           System.out.println( "服務器的端口" + s.getPort() );
           }
          }
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          42
          43
          44
          45
          46
          47
          48
          49
          50
          51
          52
          53
          54
          55
          56
          57
          58
          59
          60
          61
          62
          63
          64
          65
          66
          67
          68
          69
          70
          71
          72
          73
          74
          75
          76
          77
          78
          79
          80
          81
          82
          83
          84
          85
          86
          87
          88
          89
          90
          91
          92
          93
          94
          95
          96
          97
          98
          99
          100
          101
          102
          103
          104
          105
          106
          107
          108
          109
          110
          111
          112
          113
          114
          115
          116
          117
          118
          119
          120
          121
          122
          123
          124
          

          ChatServerPool.java:

          package com.appms.websocket;
          import java.util.ArrayList;
          import java.util.Collection;
          import java.util.HashMap;
          import java.util.List;
          import java.util.Map;
          import java.util.Set;
          import org.java_websocket.WebSocket;
          /**
           * 即時通訊
           */
          public class ChatServerPool {
           private static final Map<WebSocket,String> userconnections = new HashMap<WebSocket,String>();
           /**
           * 獲取用戶名
           * @param session
           */
           public static String getUserByKey(WebSocket conn){
           return userconnections.get(conn);
           }
           /**
           * 獲取WebSocket
           * @param user
           */
           public static WebSocket getWebSocketByUser(String user){
           Set<WebSocket> keySet = userconnections.keySet();
           synchronized (keySet) {
           for (WebSocket conn : keySet) {
           String cuser = userconnections.get(conn);
           if(cuser.equals(user)){
           return conn;
           }
           }
           }
           return null;
           }
           /**
           * 向連接池中添加連接
           * @param inbound
           */
           public static void addUser(String user, WebSocket conn){
           userconnections.put(conn,user); //添加連接
           }
           /**
           * 獲取所有的在線用戶
           * @return
           */
           public static Collection<String> getOnlineUser(){
           List<String> setUsers = new ArrayList<String>();
           Collection<String> setUser = userconnections.values();
           for(String u:setUser){
           setUsers.add("<a onclick=\"toUserMsg('"+u+"');\">"+u+"</a>");
           }
           return setUsers;
           }
           /**
           * 移除連接池中的連接
           * @param inbound
           */
           public static boolean removeUser(WebSocket conn){
           if(userconnections.containsKey(conn)){
           userconnections.remove(conn); //移除連接
           return true;
           }else{
           return false;
           }
           }
           /**
           * 向特定的用戶發送數據
           * @param user
           * @param message
           */
           public static void sendMessageToUser(WebSocket conn,String message){
           if(null != conn && null != userconnections.get(conn)){
           conn.send(message);
           }
           }
           /**
           * 向所有的用戶發送消息
           * @param message
           */
           public static void sendMessage(String message){
           Set<WebSocket> keySet = userconnections.keySet();
           synchronized (keySet) {
           for (WebSocket conn : keySet) {
           String user = userconnections.get(conn);
           if(user != null){
           conn.send(message);
           }
           }
           }
           }
          }
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          42
          43
          44
          45
          46
          47
          48
          49
          50
          51
          52
          53
          54
          55
          56
          57
          58
          59
          60
          61
          62
          63
          64
          65
          66
          67
          68
          69
          70
          71
          72
          73
          74
          75
          76
          77
          78
          79
          80
          81
          82
          83
          84
          85
          86
          87
          88
          89
          90
          91
          92
          93
          94
          95
          96
          97
          98
          99
          100
          101
          102
          103
          104
          105
          

          寫個過濾器,在項目執行時啟動:

          package com.appms.filter;
          import java.io.IOException;
          import java.net.UnknownHostException;
          import java.util.Calendar;
          import java.util.Date;
          import java.util.Timer;
          import java.util.TimerTask;
          import javax.servlet.Filter;
          import javax.servlet.FilterChain;
          import javax.servlet.FilterConfig;
          import javax.servlet.ServletException;
          import javax.servlet.ServletRequest;
          import javax.servlet.ServletResponse;
          import org.java_websocket.WebSocketImpl;
          import com.appms.base.BaseController;
          import com.appms.base.Const;
          import com.appms.utils.Tools;
          import com.appms.websocket.ChatServer;
          import com.appms.websocket.OnlineChatServer;
          public class StartFilter extends BaseController implements Filter{
           /**
           * 初始化
           */
           public void init(FilterConfig fc) throws ServletException {
           this.startWebsocketInstantMsg();
           this.startWebsocketOnline();
           }
           /**
           * 啟動即時聊天服務
           */
           public void startWebsocketInstantMsg(){
           WebSocketImpl.DEBUG = false;
           ChatServer s = null;
           try {
           String strWEBSOCKET = Tools.readTxtFile(Const.WEBSOCKET);//讀取WEBSOCKET配置,獲取端口配置
           if(null != strWEBSOCKET && !"".equals(strWEBSOCKET)){
           String strIW[] = strWEBSOCKET.split(",fh,");
           if(strIW.length == 4){
           s = new ChatServer(Integer.parseInt(strIW[1]));
           s.start();
           }
           }
           System.out.println( "websocket服務器啟動,端口" + s.getPort() );
           } catch (UnknownHostException e) {
           e.printStackTrace();
           }
           }
           /**
           * 啟動在線管理服務
           */
           public void startWebsocketOnline(){
           WebSocketImpl.DEBUG = false;
           OnlineChatServer s = null;
           try {
           String strWEBSOCKET = Tools.readTxtFile(Const.WEBSOCKET);//讀取WEBSOCKET配置,獲取端口配置
           if(null != strWEBSOCKET && !"".equals(strWEBSOCKET)){
           String strIW[] = strWEBSOCKET.split(",fh,");
           if(strIW.length == 4){
           s = new OnlineChatServer(Integer.parseInt(strIW[3]));
           s.start();
           }
           }
           System.out.println( "websocket服務器啟動,端口" + s.getPort() );
           } catch (UnknownHostException e) {
           e.printStackTrace();
           }
           }
           //計時器
           public void timer() {
           Calendar calendar = Calendar.getInstance();
           calendar.set(Calendar.HOUR_OF_DAY, 9); // 控制時
           calendar.set(Calendar.MINUTE, 0); // 控制分
           calendar.set(Calendar.SECOND, 0); // 控制秒
           Date time = calendar.getTime(); // 得出執行任務的時間
           Timer timer = new Timer();
           timer.scheduleAtFixedRate(new TimerTask() {
           public void run() {
           //PersonService personService = (PersonService)ApplicationContext.getBean("personService");
           }
           }, time, 1000*60*60*24);// 這里設定將延時每天固定執行
           }
           public void destroy() {
           // TODO Auto-generated method stub
           }
           public void doFilter(ServletRequest arg0, ServletResponse arg1,
           FilterChain arg2) throws IOException, ServletException {
           // TODO Auto-generated method stub
           }
          }
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          42
          43
          44
          45
          46
          47
          48
          49
          50
          51
          52
          53
          54
          55
          56
          57
          58
          59
          60
          61
          62
          63
          64
          65
          66
          67
          68
          69
          70
          71
          72
          73
          74
          75
          76
          77
          78
          79
          80
          81
          82
          83
          84
          85
          86
          87
          88
          89
          90
          91
          92
          93
          94
          95
          96
          97
          98
          99
          100
          101
          102
          103
          104
          105
          106
          107
          108
          109
          

          在web.xml里配置:

           <filter>
           <filter-name>startFilter</filter-name>
           <filter-class>com.appms.filter.StartFilter</filter-class>
           </filter>
          1
          2
          3
          4
          

          在jsp頁面進行調用:

           <script type="text/javascript">var wimadress="127.0.0.1:8887";</script>
           <script type="text/javascript">var oladress="127.0.0.1:8889";</script>
           <link rel="stylesheet" type="text/css" href="plugins/websocket/ext4/resources/css/ext-all.css">
           <link rel="stylesheet" type="text/css" href="plugins/websocket/css/websocket.css" />
           <script type="text/javascript" src="plugins/websocket/ext4/ext-all-debug.js"></script>
           <script type="text/javascript" src="plugins/websocket/websocket.js"></script>
           <!--引入屬于此頁面的js -->
           <script type="text/javascript" src="source/js/jquery-1.8.3.js"></script>
          1
          2
          3
          4
          5
          6
          7
          8
          9
          

          點擊li標簽跳出聊天頁面

          ul class="am-avg-sm-1 am-avg-md-4 am-margin am-padding am-text-center admin-content-list ">
           <li onclick="creatw();"><a href="javascript:;"><span class="am-icon-btn am-icon-file-text"></span><br/>即時通訊<br/></a></li>
           <li><a href="fusioncharts/index.do" class="am-text-warning"><span class="am-icon-btn am-icon-briefcase"></span><br/>圖表統計<br/></a></li>
           <li><a href="#" class="am-text-danger"><span class="am-icon-btn am-icon-recycle"></span><br/>昨日訪問<br/>80082</a></li>
           <li><a href="#" class="am-text-secondary"><span class="am-icon-btn am-icon-user-md"></span><br/>在線用戶<br/>3000</a></li>
           </ul>
          1
          2
          3
          4
          5
          6
          

          私聊:


          群聊:


          基于ExtJS前端框架的Websocket即時通訊系統


          里妹導讀:今年的雙11已經是阿里資深前端技術專家舒文來阿里的第11年,從應屆生到雙11前端PM,他一路升級打怪,實現了崗位上從P4到P9的晉升。這第11屆雙11順利結束之際,他把在阿里這些年的成長經歷做一個總結和分享,希望你能在他的故事中得到些許啟發。

          作者簡介:舒文,來自淘系技術部前端團隊。目前負責淘系(淘寶+天貓)的營銷活動、互動的業務,也在阿里巴巴前端委員會主導搭建體系的技術方向。

          P4:懵懂學生入行記 (2008.10-2009.12)

          2008年10月,入職阿里巴巴日文站,以前端崗加入UED團隊。日文站的業務源于阿里巴巴國際站 - 提供在線的平臺化服務,專注撮合中日貿易。

          在那個前端的鴻蒙年代,頁面重構工程師和Javascript程序員還是兩個細分職位: 在阿里,前端、交互、視覺共同劃屬用戶體驗部門。

          而在部份公司,有專門的重構工程師。

          在日文站亦如是:現實情況是杭州和東京的團隊,具備寫JS能力的工程師均不多。不少同事專注在HTML/CSS領域,且專研極深。舉個例子:在日文站,所有的HTML/CSS代碼必須通過兩個Lint工具:HTML文書の文法をチェックし、採點します、[The W3C Markup Validation - 這讓代碼的規范性更好外,也能獲得更好的搜索引擎分析&索引權重。

          隨著業務發展,需求場景多且復雜起來,對Javascript開發能力要求就越高。同時,也激發了我的技術熱情。除了看書,我迫切想參與其他事業部的前端交流會。感謝時任主管的支持,我開始主動跨部門溝通,將他山之玉和學習所得有了更多結合。慢慢地,在團隊內部提出一些技術方案并逐漸應用到杭州/東京兩個團隊 (特別感謝最早時代的D2)。

          在那個階段,我幾乎參與了所有較為復雜的項目。結合當年的熱門大作《高性能網站建設指南》、Yahoo網站性能優化黃金法則,負責了主站的性能優化,取得了一些不錯結果。

          2009年10月獲得了日文站優秀員工,年底順利晉升到新的層級(P5)。

          P5:從熱血到成長(2010.01-2011.06)

          2010年開始,業務略微調整,參與“日本買家獲得”(Buyer Growth)。這個業務本質是通過平臺技術優化(SEO、SEM等)獲得更高的搜索引擎權重、提高Landing到轉化。

          在這期間,隨著被認可度提升、持續的項目歷練,我的自信心也得到了鍛煉。除了參與更復雜的項目外,我開始主動對業務和技術體系做出一些提案(Proposal) - 包括參考Google Webmaster Guidelines進行技術優化、參與了各種SEO項目,提出了現在回想起來各種或靠譜或不靠譜的提案。非常感謝歷任主管的支持和包容,讓一個楞頭青能夠沒有后顧之憂地敢想敢做。

          日文站初版克隆自Alibaba.com,加之外包參與、跨東京和杭州多團隊開發等原因,全站前端框架混雜,包括不限于YUI/Mootools/PrototypeJS/ExtJS/TBra等前端框架&類庫混雜在同一業務甚至頁面。新人上手、多人協作、性能優化的成本很高,但歷史原因積重難返,大家苦不堪言。

          結束一個大項目后,時值“憤青”的我對全站的代碼做了個調研和分析,說服了主管們,決定啟動一個重構項目——旨在將全站混雜的代碼統一到 jQuery。并大體確定了執行方案:隨業務迭代上線、項目成員1人,我兼任PM、開發/自測。

          在之后,一個如同打了雞血般的前端程序員,白天黑夜的翻歷史PRD、熟悉代碼邏輯、閱讀各種類庫的手冊,陸續將各業務線的腳本重寫了一遍,邊做業務項目邊重構,整個項目持續了半年多,直到11年Q1完成。

          現在回想起來,有些事情真需要一股沖動,正如買房、結婚。如果主管讓我再多考慮半天,我興許就慫了。當然,人生也可能走入另外一條主線。

          2011年日文站業務合入B2B,我也參加并通過新事業部的年中晉升(至P6 ) 。


          2011年阿里巴巴日文站誓師大會

          P6:內部創業 + 前端的無線爆發 (2011.07-2014.06)

          兩段非常寶貴又特別的經歷。

          2011年下半年主動選擇加入阿里內部的創業項目:打造一款面向個人消費者的云產品。 團隊不大,20多人,各路專家云集,各負責人級別都很高。很享受這段工作旅程,我第一次參與桌面Hybrid端項目,第一次開發SPA Web應用,第一次參與跨桌面軟件/PC Web/H5的項目,第一次領略敏捷管理的魅力。在來自美國的技術Leader帶領下,我接觸到很多新領域,極大地開闊了技術視野。

          “創業失敗是要承擔風險的,沒有加薪,沒有晉升,而且還是996,直到項目成功”。第一次面試這個項目前,業務負責人,阿里工號16的虛竹告訴我。

          不算幸運的是,最終這個項目沒有取得如預期的成功,業務有了變化和調整。

          但幸運的是:這段經歷讓我親身體驗了一把“創業”,也感受了技術以外的方方面面艱難。這個過程中形成的產品和業務思維,對我日后帶來了深刻影響。當然,也在我之后幾百次想離職創業時,這段經歷讓我能夠靜下心來思考創業的內核 - “為什么要創業?我有什么資源、能做什么事情、創造什么價值?”

          忘了說,這段經歷之所有特別,還因為辦公地點在湖畔花園——馬老師家。


          湖畔花園辦公場地

          2012年7月,加入到天貓的前端團隊。 主管給予了充分的信任,讓我負責天貓H5首頁的研發,開始接觸淘寶前端—— 一個更成熟完整的技術體系。

          2012年底,@三七 加入天貓帶領前端團隊,作為國內前端領域最早的拓荒者之一,他在隨后的兩年時間給天貓的前端技術帶來體系化的變革——從模塊化到工程化再到生產環境的NodeJS,并引入了Mobile First理念。在他的支持下,我帶領了一支前端小組陸續參與多條業務線的開發工作。我自己也加入集團級技術建設,主導跨端Web的項目,推進了前端體系的移動化建設。

          除專業技術外,花了比原來更多的功夫在團隊工作上,包括不限于團隊氛圍、風格和文化的打造,學會在內網分享中學習借鑒前輩大拿的的管理方法論。在阿里的文化中,非常強調傳承。一個人牛不算什么,讓一群人厲害才算厲害,最好是讓下屬比自己還強。

          時間花在哪兒,結果就會在哪兒。團隊內一些業務尖兵逐漸冒出頭來,在后來幾年成為天貓甚至大淘系的中堅力量。

          這個過程既痛苦又快樂。痛苦在于要做越來越多的超過自己能力層級、遠離舒適區的工作,快樂的則是能明顯感知到自己在這個過程中的快速成長。

          很幸運,在14年年中,順利通過晉升(P7)。

          P7:從雙十一中打將出來 (2014.08 - 2016.01)

          2014年注定是難忘的一年。在這一年,我開始負責營銷活動的業務,并擔任2014年雙十一前端技術PM工作。

          營銷活動是一個頂有趣、富有故事的業務:

          從技術上:它可以極致簡潔到切一個頁面上線就行,也可以復雜到如雙11一般 ——它是阿里技術的年度大考。

          從業務上:它既可以簡單到直接把現實生活的促銷活動進行虛擬世界的進行流程投射,也能如互聯網史上的春運般整合零售生態和供應鏈。

          我和多個團隊在天貓制定了各個維度的技術規范,如內控標準、外包規范,有驚無險地渡過了14年雙十一。

          在PC時代,營銷活動的研發模式,對于前端來說,實在過于“簡樸”:“5到6位正式前端常年帶著數十個外包,根據運營需求開發成百數千的頁面,通過一個叫做TMS的運營系統預留坑位給運營同學填數據,交由后端應用推上線(CDN)。” 這類業務活動頻次高、頁面量大、協同成本高。某種意義上講,對前端技術挑戰并不高,為了更高效的研發,我們能做的是不斷提高組件和模塊復用率。

          感謝TMS,它幫助前端們快速迭代出一個又一個頁面,支持了集團的業務,即使在今天,它的設計思路都能稱得上精巧犀利。

          發生變化來自2014年雙十一前,線上發生了一次令我終生難忘的離奇故障(涉及敏感信息,略過細節):當時因臨時未排查出原因,VP現場觀摩面,我和CDN運維團隊的同學們能做的只是不斷重啟集群應用緩解問題。

          我作為時任前端PM,也因技術方案選擇失誤受到批評責罰。(時隔多年,大家也偶爾調侃,責罰不冤,幸而那天的問題提前暴露而未發生在11.11號當天,否則后果難料 )。

          那年雙11最終還是完美謝幕,GMV 571億,移動端成交42.6% ,很多人敏銳的感覺到:移動化時代到來了。

          之后技術復盤,我們針對問題做了多輪討論和推演,決定啟動一個代號“斑馬”的產品項目:基于我們對營銷的理解,運營的實際需求、過往的技術痛點,設計一個高效的頁面系統來支持運營快速發布活動上線,更重要的是它是完全的基于Mobile First設計的系統。

          正所謂 “一飲一啄,莫非前定” ,因為過去一年的打磨錘煉、痛過后的反思,我們很快把方案框架敲定,并和多個業務搭檔共同推進項目實施。

          項目于15年初立項,我代表團隊“激進”的將階段目標定為“支撐2015年3月的春季大促” 。這種既要支撐日常高頻的大促業務,又要同時從0到1做平臺研發,不啻于“飛行中升級引擎”,困難很大。但我背后的思考是:“這就如同創業,沒有一往無前的決心和一鼓作氣的氣勢,等想多了細了,多半就慫了怕了”。

          我負責整個系統及PM工作,團隊培養出來的中堅力量們承擔各個功能模塊研發。為實現我們心中所定計劃,整個項目組如同創業般激情,為了一個共同的目標奮進。春節假期不少同學還在主動提交代碼,節后迅速返回公司繼續項目。

          很幸運,克服了重重困難,“斑馬”項目順利上線,并成功支持了2015年第一個S級大促。基于新的系統,我們共同把營銷活動送上新的軌道:因模塊化帶來的效率提升讓我們完全解除了外包依賴、因具備跨端能力運營們可以單次同時進行PC和無線活動、我們設計并推動了CDN構架,單在15年雙11就節省了數千萬預算。

          隨著技術迭代,“斑馬”這個技術產品,在后面幾年成為阿里的基礎運營平臺之一。

          2015年5月,我參與了P8的晉升提名,結果未通過。Leader和我溝通:“成長很快,能力和規劃出色,業務成果需要時間驗證”。我很坦然接收了建議,晉升答辯中的技術評委的建議中肯不失公正,讓我受益很大。

          “但行好事,莫問前程”——在隨后的時間,“斑馬”的能力更為完備。我再次擔任了2015年雙11的前端PM工作,業務也順利上線。那一年,雙11當天GMV 912億,移動端成交68%。

          16年1月,新主管告訴我,綠色通道通過,晉升至P8。


          雙十一令牌/虎符

          P8:立足業務,敢想敢造 (2016.02 - 2019.07)

          一次偶然的機會,看到一張圖:如遵循民意蘋果手機會變成什么樣?給我帶來一些對業務和技術的思考:“頁面發布系統本質上是一個通用的工具平臺:前端/運營/設計師都是它的用戶,每個角色都有對它的功能需求。但每個新增功能在解決一類用戶需求的同時又增加了平臺復雜度,降低的客戶的易用性,丟失掉另一類用戶的民心。”

          “這興許是一個產品的輪回宿命”,我內心有些敬畏地想。帶著這個敬畏,時間到了2017年,隨著斑馬的功能日趨復雜,我決定將運營操作平臺和底層技術能力進行剝離:

          • 將斑馬定義為運營系統,專為運營打造極致的頁面搭建。
          • 將底層能力抽象成服務平臺(代號“天馬”),提供開放的研發標準、搭建方案、頁面渲染能力。

          隨著時間推移,“天馬”的開放能力不斷完善,越來越多的事業部基于它構建面向業務的平臺系統,帶來的技術回報是:技術復用減少從0到1的研發&硬件成本、標準統一使跨業務協同變為可行。

          而在技術的另外一邊,業務發生著悄無聲息的變化:16年雙11GMV 1207億、17年雙11則是1682億。每年雙十一在如此巨大的基數下還能持續業務高增長,個性化算法、推薦技術的大規模應用起到了非常重要的作用。在全局效率上,大數據優于人工干預逐漸得到了共識。在我看來,這些變化意味著時下大家認可的大促會場模式,也將帶來新的變化。

          2018年2月,我在內部做了個分享,描述了對營銷活動未來的預判:

          • 業務化:面向“活動”組織,而非頁面。
          • 產品化:構建常態化、心智化的大促產品矩陣,而非單純是模塊級的抽象。
          • 智能化:投放算法化和規則化,而非運營的動態化。

          基于以上預判,我和團隊的小伙伴,計劃聯同業務、上下游技術團隊共同構建一個面向營銷活動的平臺產品(項目代號:方舟)。

          很感謝歷任主管實仙/四虎的信任,愿意幫我頂住重重壓力,經過多輪溝通,我們達成了一致共識。

          和過去幾年稍有不同的是,我逐漸把包括不限于方舟的一些重要產品放手給團隊中的骨干/TL,讓他們去規劃、去驅動、去變革。我更多做了輔導性、資源性、業務判斷的全局性工作。

          隨著時間的推移,越來越多的結果開始凸現:

          1. 斑馬逐漸成為集團級的通用平臺,數萬小二同學用它發布管理業務。
          2. 方舟作為業務平臺交付成為大促體系的核心部分,并成功應用到雙11期間,在效率、效果和交付質量上取得矚目的結果。
          3. 天馬通過“開放共建、出海上云”,為集團多個BU提供基礎的技術搭建服務。
          4. 在業務中,團隊中沉淀出一個個技術產品:渲染引擎、API聚合網關等,也把曾經僅服務于內部的產品開放到商家、ISV。

          在2018年中,提名參加晉升面試,結果未通過,技術委員會的評委們建議更多參與“集團級的技術建設、更高格局的視野”。

          我很快走出了沮喪,畢竟在阿里,常勝不常有失敗倒常伴。更重要是,主管 @四虎 的開導讓我開始思考更全局的未來。

          隨后的時間,我繼續投入了2018的雙11前端整體工作,推進了多個端技術方案落地天貓。感謝阿里前端技術委員會主席圓心的舉薦,我加入前端委員會,擔任搭建技術方向的Sponsor - 旨在站在集團視角,定制標準、融合并打通搭建技術體系,在更大范圍內賦能業務。

          在集團內各個前端Leader的支持下,我們很快跨多個事業群達成了共識,制定完善了技術標準,基于一體化方案啟動了多個層面的項目。

          2019年5月,參加了年度晉升,順利通過P9晉升。感恩。

          P9:不止于前端

          現在,仍然有太多的事情值得去深入:

          1. 以雙11為代表的大促前端體系仍然是業內最具技術挑戰的業務場景之一,包括不限于客戶端容器技術、服務端渲染(Node)、框架與組件體系、跨終端技術等綜合應用。
          2. 阿里有數以億計的消費者,如何為我們的消費者構建一個好玩有趣的互動購物體驗,是我們這個團隊一直需要探索和改進的。
          3. 在未來,源自于前端的搭建技術,不僅能支持小二還能服務生態角色,不僅能支持國內還要服務全球。

          除以上,我也深度參與阿里前端技術委員會的工作:

          在阿里的前端體系,除了搭建方向以外,有相當數量的跨事業群共同建設的技術方向&項目,包括不限于Serverless、IDE、智能化、中后臺、數據可視化、工程化、Node技術等。這些技術方向或者始于前端,但又不止于前端,共同為打造行業領先的技術生態服務。

          有期待有更多的優秀的同學加入阿里,讓我們的智力和努力觸碰到數以十億計的用戶。歡迎加入聯系我:wenliang.shuwl [at]alibaba-inc.com

          最后分享一些過往些年的的心得:

          關于工作:

          1.想做好一件事情前,獲得上級的認可非常非常重要,這是把一件事情做成、做好的催化劑。

          2.很多時候,源自“事”的困難都可以用態度解決,來自“人”的困難可以用換位思考解決。

          3.對于剛參加工作的同學,如果家中無礦,啥也別說,努力就對了!畢業五年內的表現,可以決定人生很多事情。

          4.如果你和領導發生分歧:拿出你的數據/理由/態度盡最大的努力去說服他,如果充分溝通還形不成共識,那就先聽他的 。這不是媚上,而是“在必須達成一致的前提下,相信更有概率做出正確決定的人。”

          5.在工作中,如果某個時間突然發現和往常不一樣,陡然壓力變大/身心疲憊,別害怕 ,因為,這有可能是你在成長、突破瓶頸前的黑暗期。

          6.專業技能是立身之本。從長期來看,它是性價比最高的投資標的之一。

          7.結合資源,盡最大的努力、用最好的態度,做好手上的工作,也是一種創業。

          8.不要因為背靠大樹久了,就誤認為自己是顆大樹。對客戶&用戶的尊重和價值創造是我們很大的護城河。

          關于生活:

          1.技術人讀書工作掙錢養家,一步步成長同時也會一歲歲變老。相比不少行業,互聯網行業自身有賽道上的優勢,但如果單純以同比其他行業略高的溢價按年/月出售自己的時間和技能,這不應該是我們做的。堅持不斷的思考、通過技術優勢帶來疊加價值,在過程中不斷成長 , 這興許會更好。

          2.學會獎勵自己。如果經受了辛勞、痛苦和壓力走了過來,再不好好的、肉痛地獎勵自己一把,哪對得起過去和未來的自己。

          3.除了在工作中,人生處處皆可學習:學理財、學打球、學拍照、學游泳、學健身、學拍短視頻、學習怎么把生活過得更好。

          4.最后,咱們技術人可能很忙,有可能沒法“work-life balance”,這是一種取舍。但健康的身體一定是最寶貴的一筆財富,沒有之一,不能舍。謝謝大家。

          作者:舒文

          本文為云棲社區原創內容,未經允許不得轉載。


          主站蜘蛛池模板: 91久久精品国产免费一区| 免费高清av一区二区三区| 精品一区二区高清在线观看| 久久国产一区二区三区| 乱中年女人伦av一区二区| 日韩一区精品视频一区二区| 国产精品被窝福利一区| 国产AV天堂无码一区二区三区| 精品性影院一区二区三区内射 | 精品3d动漫视频一区在线观看| 色老头在线一区二区三区| 熟女少妇丰满一区二区| 成人无码AV一区二区| 人妻少妇精品一区二区三区| 一区二区三区午夜| 一区二区三区在线观看中文字幕| 日本一区免费电影| 欧美成人aaa片一区国产精品| 亚洲精品精华液一区二区| 精品不卡一区二区| 国精产品一区一区三区MBA下载 | 国产经典一区二区三区蜜芽 | 黑巨人与欧美精品一区| 精品少妇人妻AV一区二区 | 一区二区三区日本电影| 无码精品久久一区二区三区 | 国产A∨国片精品一区二区| 高清在线一区二区| av无码精品一区二区三区四区| 亚洲乱码国产一区网址| 免费看一区二区三区四区| 好看的电影网站亚洲一区| 久久精品动漫一区二区三区| 精品一区二区三区东京热| 人妻av综合天堂一区| 亚洲片一区二区三区| 国产精品丝袜一区二区三区| 精品人无码一区二区三区 | 人妻夜夜爽天天爽一区| 男人的天堂精品国产一区| 精品亚洲一区二区三区在线观看|