2017年12月11日 星期一

簡易使用log4javascript

有時候碰到難以複製的User操作情境產生的Javascript Error,或是想要追蹤網頁上的Javascript Error,光是BrowserConsole功能只能log出當前操作的JS錯誤,難以完全掌握JS Error

尤其現在又越來越多的程式開發透過nodejs執行,直接cli的開發方式碰到複雜的程式更是難檢視相關log!

這時候就可以使用log4javascript來幫忙啦!

log4javascript設計的概念基於Javalog4j,主要實做了loggers, appenders, layoutslevel

設定方式
1. 下載log4javascript.js - http://log4javascript.org/
2. 定義js
<script type="text/javascript" src="log4javascript.js"></script>
3. 直接使用。
<script type="text/javascript">
        var log = log4javascript.getDefaultLogger();
        log.trace(message[, message2, ... ][, exception])
        log.debug(message[, message2, ... ][, exception])
        log.info(message[, message2, ... ][, exception])
        log.warn(message[, message2, ... ][, exception])
        log.error(message[, message2, ... ][, exception])
        log.fatal(message[, message2, ... ][, exception])
</script>

實際案例
以下整理幾個使用的目的並結合相關設定說明:
l   log4javascript.getDefaultLogger預設的Log顯示方式是PopUpAppender,若用在Web開發會造成User Confuse,所以不使用預設的Logger
l   用在正式環境(Production Env.)時,通常僅需要檢視有發生Error或者監控一些狀態的時候使用,因此通常需要保存下來存查。
l   目前已經在很多的開發程式中使用了console在監控,又不想要每一隻都改寫。
綜合上述會變成以下的Code

/**
 *
初始化log4javascript相關設定
 
* initial log4javascript
 * **/
function initialLogger(){
   
/**
     *
預設不會印出ErrorStack資訊,不容易Trace Code
     * Default won't print error stack,set true to get stack information **/
   
log4javascript.setShowStackTraces(true);
   
/**
     *
使用Default沒有PopupAppenderLogger
     * Use logger without PopupAppender
     *  **/
   
var logger = log4javascript.getLogger('simpleLogger'),
       
/**
         * Use JSP or PHP to handler every log request
         * **/
       
requestUrl = 'urlToHandleLogInfo',
       
/**
         * Setup Ajax appender
         * **/
       
ajaxAppender = new log4javascript.AjaxAppender(requestUrl),
       
/**
         *
使用JSON的格式傳送log
         * Use JSON format to send log
         * **/
       
jsonLayout = new log4javascript.JsonLayout(),
       
/**
         *
設定需要通知的Log Level
         * Threshold to send ajax request
         * ALL,TRACE,DEBUG,INFO,WARN,ERROR,FATAL,OFF is available
         * **/
       
threshold = log4javascript.Level.ERROR;

   
/** Optional if cross domain is needed**/
   
ajaxAppender.addHeader('Access-Control-Allow-Origin', '*');
   
ajaxAppender.addHeader("Content-Type", "application/json");
   
ajaxAppender.setThreshold(threshold);
   
ajaxAppender.setLayout(jsonLayout);
   
logger.addAppender(ajaxAppender);

    return
logger;
}

/**
 *
覆蓋Consolelog機制,在console.error的同時印出logAjax記錄相關資訊
 
* Override Console Log ,
 * use original console.error to print in console and send ajax request to save log **/
(function () {
   
let logger = initialLogger();
    if
(window.console && console.error) {
       
let old = console.error;
       
console.error = function () {
            logger.error.apply(
this, arguments);
           
Array.prototype.unshift.call(arguments, 'JS Error Report: ');
           
old.apply(this, arguments);
       
}
    }
})()
;

參考資料



2016年11月16日 星期三

Spring Bean List max size (Spring AutoPopulatingList)


在使用Spring的時候會把資料封裝在Model(Bean)中使用,有時候資料傳輸用的Model(Bean)的屬性有List類型的資料時,資料數量預設是256筆。(BeanWrapperImpl#autoGrowCollectionLimit)

但有時候需要回傳的資料超過此限制時,就需要在Controller中定義調整,可透過以下方式將上限增加。

@InitBinderpublic void initListBinder(WebDataBinder binder) {
    binder.setAutoGrowCollectionLimit(5000);}

最近開發時碰到此一問題,做個紀錄。

2016年10月23日 星期日

使用tomcat建立WebSocket

什麼是WebSocket?

HTML5後出現的新功能,主要功能可使Client端瀏覽器與Server端建立一個持續的雙向連線,有興趣查詢詳細說明請自行參閱WikiwebsocketIThome

HTTP連線時,是一個Client端的請求發出後再由Server端回覆,Server端完成回覆後需待下次Client端再次發出請求後才會再次回覆。(如下圖)


WebSocket時,先由Client端發出請求建立一個WebSocket連線(handshaking),連線完成後ServerClient彼此建立了一個雙向的連線,使得Server可不需再透過Client發出的請求即可直接送出訊息。(如下圖)

  

WebSocket需求

為了達到上述的目的,因此需要兩個部份的Code來完成,Server端及Client

Server這裡選擇用Tomcat8Java來開發。

Client支援WebSocket的瀏覽器及Javascript來開發。


WebSocket   Code

  • Server   Side(Tomcat)

支援WebSocketTomcat需要7.x以上才可支援,需要的jar檔案是javax.websocket-api,若是Weblogic12.x或是Jetty9.x則不需要額外的Jar檔案。
  • Server Side   Code(Java)

/**
 * Created by yc_lin on 2016/10/14.
 */
import javax.websocket.*;
import 
javax.websocket.server.ServerEndpoint;
import 
java.io.IOException;
import 
java.util.HashMap;
import 
java.util.Map;/**
 * @ServerEndpoint gives the relative name for the end point
 * This will be accessed via ws://hostName:port/ApplicationName/
echo
 */
@ServerEndpoint("/echo")public class EchoServer {

    
static Map<StringRemoteEndpoint.BasicallRemote new HashMap<StringRemoteEndpoint.Basic>();

    
/**
     * @OnOpen 
透過此Method在開啟連線時可取得UserSession,將Session保存後可再次利用來傳送訊息
     */
    
@OnOpen
    
public void onOpen(Session session){
        System.out.println(session.getId() + 
" has opened a connection");
        try 
{
            RemoteEndpoint.Basic basicRemote = session.getBasicRemote()
;
            
allRemote.put(session.getId()basicRemote);
            
basicRemote.sendText("Connection Established");
        
catch (IOException ex) {
            ex.printStackTrace()
;
        
}
    }

    
/**
     * 
Server端接收到訊息時觸發
     */
    
@OnMessage
    
public void onMessage(String messageSession session){
        System.out.println(
"Message from " session.getId() + ": " + message);
        try 
{
            session.getBasicRemote().sendText(message)
;
            for 
(String id : allRemote.keySet()) {
                RemoteEndpoint.Basic basic = 
allRemote.get(id);
                
basic.sendText("123..." + message);
            
}
            System.out.println(
"allRemote..." allRemote.size());
        
catch (IOException ex) {
            ex.printStackTrace()
;
        
}
    }

    
/**
     * 
WebSocket連線關閉時觸發
     */
    
@OnClose
    
public void onClose(Session session) {
        
allRemote.remove(session.getId());
        
System.out.println("Session " session.getId() + " has ended");
    
}
}

  • Client Side   Code(Javascript)

<html>
<head>
    <title></title>
    <script>
        
var wsLoc = "ws://hostName:port/ApplicationName/echo";
        
//WebSocket可以選擇ws或是wss通訊協定,ws就相當於一般的httpwss則相當於https
        
var ws = new WebSocket(wsLoc);

        
//當連線開啟時觸發
        
ws.onopen function () {
            
console.log("Websocket is opened!!");
        
};
        
//收到訊息時觸發
        
ws.onmessage function (msgEvent) {
            
console.log("Received Message!!"msgEvent);
            var 
msgDisplay = document.getElementById("msgDisplay");
            
msgDisplay.innerText msgEvent.data;
        
};

        
//直接測試傳送訊息
        
ws.send('Hello WebSocket.');
    
</script>
</head>
<body>
Waiting for order!!<div id="msgDisplaystyle="colorblue;padding15px;">

</div>
</body>
</html>

完整的Code就如上述的部分,需要特別注意的是ws://hostName:port/ApplicationName/echo這串WebSocket網址,echo是透過@ServerEndpointannotation所指定的,這部分也可透過extend EndPoint的方式進行,這邊就另行討論。

其他參考資料:
http://blog.csdn.net/jia20003/article/details/48751847

2016年8月30日 星期二

使用jQuery時,HTML中的ID避免使用"."做串接

使用jQuery為了選擇特定的DOM常會使用ID這個屬性,命名時候需要注意使用"."

$("[id='some.cssCls.xx']")是可行的,但若用$("#ID")的模式需要改成$("#some\\. cssCls\\.xx")

這是為了避免selector"."的話是會選到Class的混淆

 $(#some.cssCls
指的會是 <span id="some" class="cssCls"> 
 而不是 <span id="some.cssCls" class="cssCls">

SO也有

所以ID盡量不要放"."


2016年8月24日 星期三

Nodejs npm install error

最近AngularJS2又更新了,連Type Script5 MIN QUICKSTART也更新,之前做過的Sample不知道丟哪去了。為了想重新看了一下裡面的差異,決定再做一次好了,沒想到nodejs此時的需求居然又變了,只好重新再下載一次。

以下是官網的需求說明
Install Node.js® and npm if they are not already on your machine.
Verify that you are running at least node v4.x.x and npm 3.x.x by running node -v and npm -vin a terminal/console window. Older versions produce errors.


因為在公司使用,所以必須修改proxy設定。

npm config set https-proxy http://proxyServer:80
npm config set proxy http://proxyServer:80

結果出現了一堆的Errororz

剛開始注意到的error codeUNABLE_TO_VERIFY_LEAF_SIGNATURE

error code UNABLE_TO_VERIFY_LEAF_SIGNATURE

查了半天只知道大概可能是網路問題,但Proxy Server已經定義好了,為什麼還是有這問題?
後來才又仔細看了一下npm-debug.log裡面,找到了unable to verify the first certificate

Error: unable to verify the first certificate

才找到可能的原因可能是因為http://registry.npmjs.org/沒有被proxy信任,參考

所以再執行以下指令才終於成功T_T

npm config set registry http://registry.npmjs.org/ --global

做個紀錄一下…..

2016年4月21日 星期四

ExtJS "sencha package upgrade"排除方式

最近必須花點時間研究Extjs了,於是從Sencha Cmd開始.....碰到了一個小問題,順手紀錄一下。

使用Sencha Cmd with Ext JS XXX時,先透過sencha which確認目前Sencha Cmd的版本。

>  Sencha which


若碰到所下載的Sencha Cmd與指定的sdk版本不相符,此時進行generate會出現錯誤。


Please run "sencha package upgrade" to update to 6.0.1.76.


>  sencha -sdk D:\extjs\ext-6.0.0\ext-6.0.0 generate app HelloWorld D:\Sencha\HelloWorld
 

需要透過命令列執行sencha package upgrade方可正常進行。

>  cd D:\extjs\ext-6.0.0-gpl\ext-6.0.0
>  sencha package upgrade