チェンジセット 117

差分発生行の前後
無視リスト:
コミット日時:
2007/09/26 16:11:42 (13 年前)
コミッタ:
shinomiya
ログメッセージ:

#517:im-Jssp RPCの統合

  • 通信エラー発生時のエラー内容伝達方法の修正。
  • CSJSライブラリの追加を自動化
ファイル:

凡例:

変更無し
追加
削除
更新
コピー
移動
  • trunk/im-jssp/.settings/org.eclipse.core.resources.prefs

    r4 r117  
    1 #Mon Oct 16 19:08:59 JST 2006 
     1#Tue Sep 25 19:26:39 JST 2007 
    22eclipse.preferences.version=1 
     3encoding//src/main/webapp/csjs/im_ajax_request.js=UTF-8 
     4encoding//src/main/webapp/csjs/im_json.js=UTF-8 
     5encoding//src/main/webapp/jssp_rpc/common/im_json.js=UTF-8 
    36encoding/<project>=UTF-8 
  • trunk/im-jssp/src/main/java/org/intra_mart/jssp/page/provider/JsspRpcPageBuilderImpl.java

    r104 r117  
    99import java.io.UnsupportedEncodingException; 
    1010import java.io.Writer; 
     11import java.rmi.UnmarshalException; 
    1112 
    1213import javax.servlet.ServletException; 
     
    2021import org.intra_mart.jssp.script.provider.ScriptScopeBuilder; 
    2122import org.intra_mart.jssp.script.provider.ScriptScopeBuilderManager; 
     23import org.intra_mart.jssp.util.ImAjaxUtil; 
    2224import org.intra_mart.jssp.util.config.JSSPConfigHandler; 
    2325import org.intra_mart.jssp.util.config.JSSPConfigHandlerManager; 
     
    2729import org.mozilla.javascript.JavaScriptException; 
    2830import org.mozilla.javascript.NativeArray; 
     31import org.mozilla.javascript.ScriptableObject; 
    2932import org.mozilla.javascript.Undefined; 
    3033import org.mozilla.javascript.WrappedException; 
     
    3740 
    3841        private static ScriptScope _marshallerScriptScope = null; 
     42        private static String _marshallerPagePath = null; 
     43        private static String _functionName4Marshall = null; 
    3944        private static String _functionName4Unmarshall = null; 
    40         private static String _functionName4Marshall = null; 
    4145        private static boolean _isThrowUnmarshallException = true; 
     46        private static boolean _isCacheMarshallerScriptScope = true; 
    4247         
    4348        private HttpServletRequest request;  
     
    4550        private JSSPQuery jsspQuery; 
    4651 
    47  
    4852    /** 
    4953         * Static変数の初期化を行います。 
    5054         */ 
    5155        static { 
    52                  
    5356                JsspRpcConfigHandler jsspRpcConfigHandler; 
    5457                try{ 
     
    6164                        throw new IllegalStateException(errorMessage, e); 
    6265                } 
    63                  
    64                 _functionName4Unmarshall = jsspRpcConfigHandler.getUnmarshallFunctionName();    //"unmarshall"; 
    65                 _functionName4Marshall = jsspRpcConfigHandler.getMarshallFunctionName();                //"marshall"; 
    66                  
    67                 try { 
    68                         String _marshallerPagePath = jsspRpcConfigHandler.getMarshallerPagePath();              //"jssp_rpc/common/json"; 
    69                         ScriptScopeBuilder builder = ScriptScopeBuilderManager.getBuilder(); 
    70                         _marshallerScriptScope = builder.getScriptScope(_marshallerPagePath); 
    71                 } 
    72                 catch (Exception e) { 
    73                         throw new IllegalStateException(e); 
    74                 } 
    75  
    76                 _isThrowUnmarshallException = jsspRpcConfigHandler.isThrowUnmarshallException(); 
    77 
     66 
     67                // マーシャル用スクリプトの設定 
     68                _marshallerPagePath           = jsspRpcConfigHandler.getMarshallerPagePath(); 
     69                _functionName4Marshall        = jsspRpcConfigHandler.getMarshallFunctionName(); 
     70                _functionName4Unmarshall      = jsspRpcConfigHandler.getUnmarshallFunctionName(); 
     71                _isThrowUnmarshallException   = jsspRpcConfigHandler.isThrowUnmarshallException(); 
     72                _isCacheMarshallerScriptScope = jsspRpcConfigHandler.isCacheMarshallerScriptScope(); 
     73                 
     74                // マーシャル用スクリプトをキャッシュ 
     75                refreshMarshallerScriptScope();  
     76        } 
    7877         
    7978        /** 
     
    113112                Object[] args4Java = unmarshall(jsonArgs); 
    114113 
    115                 String JsonString; 
     114                String jsonString; 
    116115                Context cx = Context.enter(); 
    117116                try{ 
     
    121120                         
    122121                        // マーシャル 
    123                         JsonString = marshall(cx, returnObj); 
     122                        jsonString = marshall(cx, returnObj); 
    124123 
    125124                } 
     
    133132                                this.response.reset(); 
    134133                                this.response.setContentType("text/html; charset=utf-8"); 
     134                                 
     135                                ImAjaxUtil.setErrorResponseHeaders(this.response, "IM-JSSP-00001"); 
     136                                 
    135137                                PrintWriter out = this.response.getWriter(); 
    136138                                out.write(src); 
     
    149151                                // (∵JSSP-RPCは、CSJSからSSJSの関数を呼び出す機構なので、遷移処理は必要なし) 
    150152                                throw we; 
    151                         }                       
     153                        } 
    152154                } 
    153155                catch (Exception e) { 
     156                        ImAjaxUtil.setErrorResponseHeaders(this.response, "IM-JSSP-99999"); 
    154157                        throw e; 
    155158                } 
     
    161164                this.response.setContentType("application/json; charset=utf-8"); 
    162165                Writer out = this.response.getWriter(); 
    163                 out.write(JsonString); 
     166                out.write(jsonString); 
    164167                out.flush(); 
    165168                out.close(); 
     
    222225        } 
    223226 
    224  
     227        /** 
     228         * @return 
     229         */ 
     230        private ScriptScope getMarshaller() { 
     231                 
     232                if(_isCacheMarshallerScriptScope == false){ 
     233                        // キャッシュしない場合 
     234                        refreshMarshallerScriptScope(); 
     235                } 
     236 
     237                return _marshallerScriptScope;           
     238        } 
     239 
     240        /** 
     241         *  
     242         */ 
     243        private static synchronized void refreshMarshallerScriptScope() { 
     244                try { 
     245                        ScriptScopeBuilder builder = ScriptScopeBuilderManager.getBuilder(); 
     246                        _marshallerScriptScope = builder.getScriptScope(_marshallerPagePath); 
     247                } 
     248                catch (Exception e) { 
     249                        throw new IllegalStateException("[JSSP-RPC] Marshaller page load error: " + _marshallerPagePath, e); 
     250                } 
     251        } 
     252 
     253         
    225254        /** 
    226255         * アンマーシャル 
     
    229258         * @throws UnmarshalException 
    230259         */ 
    231         private Object[] unmarshall(String jsonArgs) throws UnmarshalException { 
     260        private Object[] unmarshall(String jsonArgs) throws UnmarshalJSONStringException { 
    232261                 
    233262                Object[] args4Java; 
     
    238267                        // 引数(=JSON形式のPOSTデータ)をアンマーシャル 
    239268                        Object[] receiveArgs = { jsonArgs }; 
    240                         Object argsInNativeArray = _marshallerScriptScope.call(cx, _functionName4Unmarshall, receiveArgs); 
     269                        ScriptScope marshaller = getMarshaller(); 
     270                         
     271                        if(!ScriptableObject.hasProperty(marshaller, _functionName4Unmarshall)){ 
     272                                throw new IllegalStateException("[JSSP-RPC] Unmarshall function is not defined: " +  
     273                                                                                                _marshallerPagePath + "#" + _functionName4Unmarshall); 
     274                        } 
     275                         
     276                        Object argsInNativeArray = marshaller.call(cx, _functionName4Unmarshall, receiveArgs); 
    241277                         
    242278                        // 「JavaScript配列 (=NativeArray)」で渡された引数を、Object[] 配列に入れ替え 
     
    259295                } 
    260296                catch (JavaScriptException jse) { 
    261                         Object wrappedValue = jse.getValue(); 
    262                          
    263                         // JSONのアンマーシャル失敗 
    264                         if(wrappedValue != null && wrappedValue.toString().indexOf("SyntaxError: parseJSON") != -1) { 
    265                                  
    266                                 if(_isThrowUnmarshallException){ 
    267                                         throw new UnmarshalException(wrappedValue.toString(), jse); 
    268                                 } 
    269                                 else { 
    270                                         // 空の引数を渡す 
    271                                         // ※引数に null を指定してJS関数を実行するとNullPointerExceptionが発生します 
    272                                         //  (発生箇所(Rhino 1.6R5) → Interpreter.interpret(Interpreter.java:2248)) 
    273                                         args4Java = new Object[0]; 
    274                                 } 
    275                         } 
    276                         else{ 
    277                                 throw jse; 
     297                        if(_isThrowUnmarshallException){ 
     298                                throw new UnmarshalJSONStringException(jse.getMessage(), jse); 
     299                        } 
     300                        else { 
     301                                // 空の引数を渡す 
     302                                // ※引数に null を指定してJS関数を実行するとNullPointerExceptionが発生します 
     303                                //  (発生箇所(Rhino 1.6R5) → Interpreter.interpret(Interpreter.java:2248)) 
     304                                args4Java = new Object[0]; 
    278305                        } 
    279306                } 
     
    294321        private String marshall(Context cx, Object returnObj) { 
    295322                 
    296                 String JsonString; 
     323                String jsonString; 
    297324 
    298325                if(returnObj == null){ 
    299                         JsonString = "null"; 
     326                        jsonString = "null"; 
    300327                } 
    301328                else { 
    302329                        Object[] objects = { returnObj }; 
    303                         JsonString = (String)_marshallerScriptScope.call(cx, _functionName4Marshall, objects);                           
    304                 } 
    305                  
    306                 return JsonString; 
     330                        ScriptScope marshaller = getMarshaller(); 
     331                         
     332                        if(!ScriptableObject.hasProperty(marshaller, _functionName4Marshall)){ 
     333                                throw new IllegalStateException("[JSSP-RPC] Marshall function is not defined: " +  
     334                                                                                                _marshallerPagePath + "#" + _functionName4Marshall); 
     335                        } 
     336                         
     337                        jsonString = (String)marshaller.call(cx, _functionName4Marshall, objects);                               
     338                } 
     339                 
     340                return jsonString; 
    307341        } 
    308342 
  • trunk/im-jssp/src/main/java/org/intra_mart/jssp/util/config/JsspRpcConfigHandler.java

    r104 r117  
    3737         */ 
    3838        public String getMarshallFunctionName(); 
    39  
    40          
    41         /** 
    42          * Functionオブジェクトの argumentsプロパティを、配列を表すJSON形式の文字列表現に変換する関数の名称を取得します。<br/> 
    43          * クライアントサイドJavaScrip用の設定です。<br/> 
    44          * 具体的には、&lt;IMART type="jsspRpc"&gt;で生成されるJavaScriptソース内で使用します。<br/> 
    45          * <br/> 
    46          * (本メソッドで返却値で特定される関数は、 
    47          * JSSP-RPCを用いてサーバサイドJavaScript のロジックを呼び出す際、可変長引数を利用可能にするために必要です。 
    48          * この関数を利用するには「Functionオブジェクトの argumentsプロパティ」を引数として渡す必要があります。) 
    49          *  
    50          * @return Functionオブジェクトの argumentsプロパティを、配列を表すJSON形式の文字列表現に変換する関数の名称 
    51          */ 
    52         public String getMarshall4ArgumentsFunctionName(); 
    5339         
    5440        /** 
     
    6551        public boolean isThrowUnmarshallException(); 
    6652         
     53        /** 
     54         * 「JSON形式の文字列表現」と「JavaScriptオブジェクト」の変換処理を行うスクリプト(以下、Marshallerスクリプト) 
     55         * をキャッシュするか否かを返却します。<br> 
     56         * デフォルトは、true を返却します。<br> 
     57         * このメソッドの返却値が trueの場合、Marshallerスクリプトは、キャッシュされます。<br> 
     58         *  
     59         * このメソッドの返却値が falseの場合、変換処理を行う度にMarshallerスクリプトを解釈しなおします。<br> 
     60         * (つまり、サーバ起動後も、Marshallerスクリプトの変更が反映されます。Marshallerスクリプトの開発時に有用です。) 
     61         *  
     62         * @return Marshallerスクリプトをキャッシュする場合は true、 
     63         *                      それ以外は false を返却します。 
     64         */ 
     65        public boolean isCacheMarshallerScriptScope(); 
     66                 
     67        /** 
     68         * JSSP-RPCを利用する際に必要なCSJSライブラリ「im_json.js」のパスを取得します。<br> 
     69         * 本メソッドで返却されるパスが "/" で始まる場合は、現在のコンテキストのルートに対する相対パスであると解釈します。<br> 
     70         * デフォルトは、「/csjs/im_json.js」を返却します。<br> 
     71         *  
     72         * <!--このメソッドの返却値は、&lt;jsspRpc&gt;タグ生成時にあわせて作成される&lt;script&gt;タグのsrc属性に利用されます。--> 
     73         *  
     74         * @return CSJSライブラリ「im_json.js」のパス 
     75         */ 
     76        public String getCsjsPath4ImJson(); 
    6777         
     78         
     79        /** 
     80         * JSSP-RPCを利用する際に必要なCSJSライブラリ「im_ajax_request.js」のパスを取得します。<br> 
     81         * 本メソッドで返却されるパスが "/" で始まる場合は、現在のコンテキストのルートに対する相対パスであると解釈します。<br> 
     82         * デフォルトは、「/csjs/im_ajax_request.js」を返却します。<br> 
     83         *  
     84         * <!--このメソッドの返却値は、&lt;jsspRpc&gt;タグ生成時にあわせて作成される&lt;script&gt;タグのsrc属性に利用されます。--> 
     85         *  
     86         * @return CSJSライブラリ「im_ajax_request.js」のパス 
     87         */ 
     88        public String getCsjsPath4ImAjaxRequest(); 
     89 
     90         
     91        /** 
     92         * JSSP-RPCを利用する際に必要なCSJSライブラリ「im_jssp_rpc.js」のパスを取得します。<br> 
     93         * 本メソッドで返却されるパスが "/" で始まる場合は、現在のコンテキストのルートに対する相対パスであると解釈します。<br> 
     94         * デフォルトは、「/csjs/im_jssp_rpc.js」を返却します。<br> 
     95         *  
     96         * <!--このメソッドの返却値は、&lt;jsspRpc&gt;タグ生成時にあわせて作成される&lt;script&gt;タグのsrc属性に利用されます。--> 
     97         *  
     98         * @return CSJSライブラリ「im_jssp_rpc.js」のパス 
     99         */ 
     100        public String getCsjsPath4ImJsspRpc(); 
     101 
    68102} 
     103 
  • trunk/im-jssp/src/main/java/org/intra_mart/jssp/util/config/JsspRpcConfigHandlerImpl.java

    r104 r117  
    2525    private String _unmarshallFunctionName; 
    2626    private String _marshallFunctionName; 
    27     private String _marshall4ArgumentsFunctionName; 
    2827    private Boolean _isThrowUnmarshallException; 
     28    private Boolean _isCacheMarshallerScriptScope; 
     29     
     30        private String _csjsPath4imJson        = null; 
     31        private String _csjsPath4imAjaxRequest = null; 
     32        private String _csjsPath4imJsspRpc     = null;     
    2933     
    3034        /** 
     
    9195                        // 未設定の場合 
    9296                        if(_marshallerPagePath == null){ 
    93                                 _marshallerPagePath = "jssp_rpc/common/json"; 
     97                                _marshallerPagePath = "jssp_rpc/common/im_json"; 
    9498                        } 
    9599                } 
     
    108112                        // 未設定の場合 
    109113                        if(_unmarshallFunctionName == null){ 
    110                                 _unmarshallFunctionName = "unmarshall"; 
     114                                _unmarshallFunctionName = "imJsonUnmarshall"; 
    111115                        } 
    112116                } 
     
    125129                        // 未設定の場合 
    126130                        if(_marshallFunctionName == null){ 
    127                                 _marshallFunctionName = "marshall"; 
     131                                _marshallFunctionName = "imJsonMarshall"; 
    128132                        } 
    129133                } 
    130134                return _marshallFunctionName; 
    131135        } 
    132  
    133          
    134         /* (non-Javadoc) 
    135          * @see org.intra_mart.jssp.util.config.JsspRpcConfigHandler#getMarshall4ArgumentsFunctionName() 
    136          */ 
    137         public String getMarshall4ArgumentsFunctionName() { 
    138                 if(_marshall4ArgumentsFunctionName == null){ 
    139                         _marshall4ArgumentsFunctionName =  
    140                                 jsspConfigProperties.getProperty(ROOT_ELEMENT + "/marshller/function-name/marshall-arguments"); 
    141  
    142                         // 未設定の場合 
    143                         if(_marshall4ArgumentsFunctionName == null){ 
    144                                 _marshall4ArgumentsFunctionName = "marshall4Arguments"; 
    145                         } 
    146                 } 
    147                 return _marshall4ArgumentsFunctionName; 
    148         } 
    149  
     136         
     137         
    150138        /* (non-Javadoc) 
    151139         * @see org.intra_mart.jssp.util.config.JsspRpcConfigHandler#isThrowUnmarshallException() 
     
    167155        } 
    168156 
     157         
     158        /* (non-Javadoc) 
     159         * @see org.intra_mart.jssp.util.config.JsspRpcConfigHandler#isCacheMarshallerScriptScope() 
     160         */ 
     161        public boolean isCacheMarshallerScriptScope() { 
     162                if(_isCacheMarshallerScriptScope == null){ 
     163                        String isCacheMarshallerScriptScopeString =  
     164                                jsspConfigProperties.getProperty(ROOT_ELEMENT + "/marshller/cache-marshaller-script"); 
     165                         
     166                        if(isCacheMarshallerScriptScopeString != null){ 
     167                                _isCacheMarshallerScriptScope = Boolean.valueOf(isCacheMarshallerScriptScopeString); 
     168                        } 
     169                        // 未設定の場合 
     170                        else{ 
     171                                _isCacheMarshallerScriptScope = true; 
     172                        } 
     173                } 
     174                return _isCacheMarshallerScriptScope; 
     175        } 
     176 
     177         
     178        /* (non-Javadoc) 
     179         * @see org.intra_mart.jssp.util.config.JsspRpcConfigHandler#getCsjsPath4ImJson() 
     180         */ 
     181        public String getCsjsPath4ImJson() { 
     182                if(_csjsPath4imJson == null){ 
     183                        _csjsPath4imJson =  
     184                                jsspConfigProperties.getProperty(ROOT_ELEMENT + "/csjs-path/im-json"); 
     185 
     186                        // 未設定の場合 
     187                        if(_csjsPath4imJson == null){ 
     188                                _csjsPath4imJson = "/csjs/im_json.js"; 
     189                        } 
     190                } 
     191                return _csjsPath4imJson; 
     192        } 
     193 
     194         
     195        /* (non-Javadoc) 
     196         * @see org.intra_mart.jssp.util.config.JsspRpcConfigHandler#getCsjsPath4ImAjaxRequest() 
     197         */ 
     198        public String getCsjsPath4ImAjaxRequest() { 
     199                if(_csjsPath4imAjaxRequest == null){ 
     200                        _csjsPath4imAjaxRequest =  
     201                                jsspConfigProperties.getProperty(ROOT_ELEMENT + "/csjs-path/im-ajax-request"); 
     202 
     203                        // 未設定の場合 
     204                        if(_csjsPath4imAjaxRequest == null){ 
     205                                _csjsPath4imAjaxRequest = "/csjs/im_ajax_request.js"; 
     206                        } 
     207                } 
     208                return _csjsPath4imAjaxRequest; 
     209        } 
     210 
     211         
     212        /* (non-Javadoc) 
     213         * @see org.intra_mart.jssp.util.config.JsspRpcConfigHandler#getCsjsPath4ImJsspRpc() 
     214         */ 
     215        public String getCsjsPath4ImJsspRpc() { 
     216                if(_csjsPath4imJsspRpc == null){ 
     217                        _csjsPath4imJsspRpc =  
     218                                jsspConfigProperties.getProperty(ROOT_ELEMENT + "/csjs-path/im-jssp-rpc"); 
     219 
     220                        // 未設定の場合 
     221                        if(_csjsPath4imJsspRpc == null){ 
     222                                _csjsPath4imJsspRpc = "/csjs/im_jssp_rpc.js"; 
     223                        } 
     224                } 
     225                return _csjsPath4imJsspRpc; 
     226        } 
     227 
    169228} 
  • trunk/im-jssp/src/main/java/org/intra_mart/jssp/view/tag/ImartTag4JsspRpc.java

    r104 r117  
    3131 * ここで指定するパスは、JSSPコンテンツのソースディレクトリからの相対パス形式になります。(デフォルトはコンテキストパスに対応する実際のパス)<br/> 
    3232 * <br/> 
    33  * サーバの処理結果を非同期で受け取りたい場合は、属性 callback を指定します。<br/> 
     33 * サーバサイドの処理結果を非同期で受け取りたい場合は、属性 callback を指定します。<br/> 
    3434 * 属性 callback には、CSJS関数名を指定します。 
    35  * 属性 callback が指定されている場合、サーバ側の処理結果が 属性 callback で指定されたCSJS関数の引数に渡されます。 
    36  * <br/> 
    37  * <br/> 
    38  * <strong><i>例:</i></strong> 
    39  * <blockquote> 
    40  * サーバサイドに「<b><font color="green">sample/test1</font></b>.js」が存在し、 
    41  * そのJSファイル内に「<b><font color="red">testFunction</font></b>()」という関数が定義されている場合、 
    42  * 以下を行うことによって、CSJSから上記関数を実行することができます。 
    43  * <ol> 
    44  *      <li> 
    45  *              HTMLファイルの &lt;HEAD&gt; タグ内に以下のCSJSライブラリを追加します。<br/> 
    46  *      </li> 
    47  *      <pre> 
    48                 &lt;script language="JavaScript" src="csjs/im_jssp_rpc.js"&gt;&lt;/script&gt; 
    49                 &lt;script language="JavaScript" src="csjs/json.js"&gt;&lt;/script&gt; 
    50  *      </pre> 
     35 * 属性 callback が指定されている場合、サーバサイドの処理結果が 属性 callback で指定されたCSJS関数の引数に渡されます。<br/> 
     36 * <br/> 
     37 * 属性 onErrorCallback には、非同期通信時にエラーが発生した場合に呼び出される関数名を指定します。<br/> 
     38 * 属性 onErrorCallback で指定された関数の引数には、 
     39 * <a href="#JsspRpcComErrorObject">JSSP-RPC 通信エラーオブジェクト</a>が渡されます。<br/> 
    5140 *  
    52  *      <li>HTMLファイル内に&lt;IMART type="jsspRpc"&gt; タグを以下のように記述します。</li> 
    53  * <pre> 
    54                 &lt;IMART type="jsspRpc" name="<b><font color="blue">serverLogic</font></b>" page="<b><font color="green">sample/test1</font></b>" &gt; 
    55  * </pre> 
    56  *  
    57  *      <li>CSJS内に以下を記述することで、サーバサイドのロジックを実行します。</li> 
    58  *      <pre><b><font color="blue">serverLogic</font></b>.<b><font color="red">testFunction</font></b>();</pre> 
    59  * </ol> 
    60  * </blockquote> 
    61  *  
    62  * <strong><i>注意事項:</i></strong> 
    63  * <blockquote> 
    64  * <ul> 
    65  *      <li> 
    66  *              HTMLファイルの &lt;HEAD&gt; タグ内に、必ず以下のCSJSライブラリを追加してください。<br/> 
    67  *      </li> 
    68  *              <pre> 
    69                         &lt;script language="JavaScript" src="csjs/im_jssp_rpc.js"&gt;&lt;/script&gt; 
    70                         &lt;script language="JavaScript" src="csjs/json.js"&gt;&lt;/script&gt; 
    71  *              </pre> 
    72  *              (なお、im_jssp_rpc.js 、および、json.js は、URLの関係で呼び出し時のソースパスは変わります。<br/> 
    73  *              &lt;IMART type="link"&gt;や&lt;IMART type="form"&gt;タグで画面遷移を行った場合は、 
    74  *              csjs/im_jssp_rpc.js、および、csjs/json.js といった相対パス指定でリンクできます) 
    75  *      <br/> 
    76  *      <br/> 
    77  *      <li> 
    78  *              &lt;IMART type="jsspRpc"&gt; タグでは、 
    79  *              ブラウザとサーバ間の通信に <a href="http://ja.wikipedia.org/wiki/XMLHttpRequest">XMLHttpRequest</a> を利用しています。 
    80  *      </li> 
    81  *      <li> 
    82  *              ブラウザとサーバ間通信のデータ形式は <a href="http://ja.wikipedia.org/wiki/JSON">JSON</a> です。 
    83  *      </li> 
    84  *      <li> 
    85  *              JSONデータとJavaScriptオブジェクトの変換には、 
    86  *              <a href="http://www.json.org/js.html">json.js</a> を改良したライブラリを使用しています。 
    87  *      </li> 
    88  *      <li> 
    89  *              JSONデータとJavaScriptオブジェクトの変換を行うサーバサイドロジックのデフォルトは、jssp_rpc/common/json.js です。<br/> 
    90  *              クライアントサイドロジックのデフォルトは、csjs/json.js です。<br/> 
    91  *      </li> 
    92  *      <li> 
    93  *              json.js内でArray、Boolean、Date、Number、Object、Stringに対してtoJSONString()関数を 
    94  *              プロトタイプオブジェクトとして設定しています。<br/> 
    95  *              その為、for/in ループ文で取得可能なオブジェクト要素一覧に toJSONString() 関数が列挙されます。<br/> 
    96  *              取得した要素が自オブジェクトのプロパティかどうかを、hasOwnProperty() 関数等を利用し、 
    97  *              必要に応じて判定してください。<br/> 
    98  *      </li> 
    99  * </ul> 
    100  * </blockquote> 
     41 * @version 1.0 
    10142 */ 
    10243public class ImartTag4JsspRpc implements ImartTagType { 
    10344 
    104         private static String _jsspRpcSuffix = null; 
    105         private static String _functionName4MarshallArguments = null; 
    106         private static String _functionName4Unmarshall = null; 
     45        private static final String KEY_JSSPRPC_TAG_ALREADY_USE_FLG = "org.intra_mart.jssp.view.tag.ImartTag4JsspRpc.jsspRpcTagAlreadyUseFlg"; 
     46 
     47        private static String _jsspRpcSuffix          = null; 
     48        private static String _csjsPath4imJson        = null; 
     49        private static String _csjsPath4imAjaxRequest = null; 
     50        private static String _csjsPath4imJsspRpc     = null; 
    10751 
    10852        static { 
    109  
    11053                JsspRpcConfigHandler jsspRpcConfigHandler; 
    11154                try{ 
     
    11962                } 
    12063                 
    121                 _jsspRpcSuffix = jsspRpcConfigHandler.getJsspRpcURISuffix();           //".jssprpc";           
    122                 _functionName4MarshallArguments = jsspRpcConfigHandler.getMarshall4ArgumentsFunctionName(); //"marshall4Arguments"
    123                 _functionName4Unmarshall = jsspRpcConfigHandler.getUnmarshallFunctionName();   //"unmarshall"
    124                  
     64                _jsspRpcSuffix          = jsspRpcConfigHandler.getJsspRpcURISuffix(); //".jssprpc";                            
     65                _csjsPath4imJson        = jsspRpcConfigHandler.getCsjsPath4ImJson()
     66                _csjsPath4imAjaxRequest = jsspRpcConfigHandler.getCsjsPath4ImAjaxRequest()
     67                _csjsPath4imJsspRpc     = jsspRpcConfigHandler.getCsjsPath4ImJsspRpc(); 
    12568        } 
    12669         
     
    14588                // コールバック関数名を取得 
    14689                String callback = getAttributeValue(oAttr, "callback", false); 
    147                  
     90 
     91                // エラー発生時のコールバック関数名を取得 
     92                String onErrorCallback = getAttributeValue(oAttr, "onErrorCallback", false); 
     93 
    14894                // 対象ページの関数名一覧を取得 
    14995                List<String> functionNames = getFunctionNames(pagePath); 
     
    160106 
    161107                // ソース作成 
    162                 StringBuffer buf = new StringBuffer();           
    163                 buf.append("<SCRIPT language=\"JavaScript\">\n"); 
     108                StringBuffer buf = new StringBuffer(); 
     109                 
     110                // JsspRpcタグの一回目の出現 
     111                HTTPContext httpContext = HTTPContextManager.getInstance().getCurrentContext(); 
     112                HttpServletRequest request = httpContext.getRequest(); 
     113                Object tag1stUseFlg = request.getAttribute(KEY_JSSPRPC_TAG_ALREADY_USE_FLG); 
     114                if(tag1stUseFlg == null){ 
     115                        request.setAttribute(KEY_JSSPRPC_TAG_ALREADY_USE_FLG, Boolean.valueOf(true)); 
     116                         
     117                        // 絶対パス指定の場合 (=パスが "/" で始まる場合は、現在のコンテキストのルートに対する相対パスであると解釈) 
     118                        if("/".equals(_csjsPath4imJson.substring(0, 1))){ 
     119                                buf.append("<script language=\"javascript\" src=\"" + contextPath + _csjsPath4imJson        + "\"></script>\n"); 
     120                                buf.append("<script language=\"javascript\" src=\"" + contextPath + _csjsPath4imAjaxRequest + "\"></script>\n"); 
     121                                buf.append("<script language=\"javascript\" src=\"" + contextPath + _csjsPath4imJsspRpc     + "\"></script>\n"); 
     122                        } 
     123                        // 相対パス指定の場合 
     124                        else{ 
     125                                buf.append("<script language=\"javascript\" src=\"" + _csjsPath4imJson        + "\"></script>\n"); 
     126                                buf.append("<script language=\"javascript\" src=\"" + _csjsPath4imAjaxRequest + "\"></script>\n"); 
     127                                buf.append("<script language=\"javascript\" src=\"" + _csjsPath4imJsspRpc     + "\"></script>\n"); 
     128                        } 
     129                } 
     130 
     131                buf.append("<script language=\"javascript\">\n"); 
    164132                buf.append("    var " + objName + " = new Object();\n");         
    165133                 
    166134                // 対象ページ内の関数を呼び出すためのCSJSソースを作成 
    167                 // 【注意】「csjs/im_jssp_rpc.js」「csjs/json.js」を HTMLファイルから参照可能にする必要があります。 
    168                 //     (∵JavaScript関数「sendJsspRpcRequest()」「marshall4Arguments()」を利用するため) 
    169135                for(String functionName : functionNames){ 
    170136                                                 
     
    178144                        String url = contextPath + "/" + jsspQuery.createJSSPQueryString(); 
    179145                         
     146                        String arguments = objName + "." + functionName + ".arguments"; 
     147                         
    180148                        buf.append("    " + objName + "[\"" + functionName + "\"] = "); 
    181149                        buf.append("function(){" ); 
    182                         buf.append(             "return sendJsspRpcRequest(");  
    183                         buf.append(                                     "\"" + url + "\", " );  
    184                         buf.append(                                     _functionName4MarshallArguments + "(" + objName + "." + functionName + ".arguments), " ); 
     150                        buf.append(             "var argsArray = new Array();");  
     151                        buf.append(             "for(var idx = 0, max = " + arguments + ".length; idx < max; idx++){");  
     152                        buf.append(                     "argsArray[idx] = " + arguments + "[idx]");  
     153                        buf.append(             "}");  
     154                        buf.append(             "return ImJsspRpc.sendJsspRpcRequest(");  
     155                        buf.append(                                     "\"" + url + "\", " ); 
     156                        buf.append(                                     "argsArray, " ); 
    185157                        buf.append(                                     callback + ", " ); 
    186                         buf.append(                                     "\"post\", " ); 
    187                         buf.append(                                     _functionName4Unmarshall );                     
     158                        buf.append(                                     onErrorCallback + ", " ); 
     159                        buf.append(                                     "\"post\" " ); 
    188160                        buf.append(                             ");" ); 
    189161                        buf.append(             "};\n"); 
    190162                } 
    191163                 
    192                 buf.append("</SCRIPT>"); 
     164                buf.append("</script>"); 
    193165 
    194166                return buf.toString(); 
  • trunk/im-jssp/src/main/webapp/WEB-INF/classes/conf/jssp-config.xml

    r114 r117  
    66                </key>                                   
    77                <marshller> 
    8                         <page-path>jssp_rpc/common/json</page-path> 
     8                        <page-path>jssp_rpc/common/im_json</page-path> 
    99                        <throw-unmarshall-exception>true</throw-unmarshall-exception> 
     10                        <cache-marshaller-script>true</cache-marshaller-script> 
    1011                        <function-name> 
    11                                 <unmarshall>unmarshall</unmarshall>                                                                                                      
    12                                 <marshall>marshall</marshall> 
    13                                 <marshall-arguments>marshall4Arguments</marshall-arguments> 
     12                                <unmarshall>imJsonUnmarshall</unmarshall>                                                                                                        
     13                                <marshall>imJsonMarshall</marshall> 
    1414                        </function-name> 
    15                 </marshller>             
     15                </marshller> 
     16                <csjs-path> 
     17                        <im-json>/csjs/im_json.js</im-json> 
     18                        <im-ajax-request>/csjs/im_ajax_request.js</im-ajax-request> 
     19                        <im-jssp-rpc>/csjs/im_jssp_rpc.js</im-jssp-rpc> 
     20                </csjs-path> 
    1621        </jssp-rpc> 
    1722        <jssp> 
  • trunk/im-jssp/src/main/webapp/csjs/im_jssp_rpc.js

    r104 r117  
    1 /** 
    2  * Send request 
    3  */ 
    4 function sendJsspRpcRequest(url, jsonString, callBack, method, unmarshallFunc) { 
     1var ImJsspRpc = { 
    52 
    6         method = (method == undefined) ? "post" : method; 
    7         unmarshallFunc = (unmarshallFunc == undefined) ? unmarshall : unmarshallFunc; 
     3        JSON_CONTENT_TYPE : "application/json; charset=utf-8", 
    84 
    9         var http = createXMLHttpRequest(); 
     5        /** 
     6         * Default callback function when error occurs 
     7         */ 
     8        defaultOnErrorCallback : function(ex){ 
    109 
    11         if(callBack != null){ 
    12                 if(window.ActiveXObject){ 
    13                         http.onreadystatechange = function () { 
    14                                 if (http.readyState == 4) { 
    15                                         callBack(receive(http, unmarshallFunc)); 
    16                                 } 
    17                         }; 
    18                 } else { 
    19                         http.onload = function () { 
    20                                 callBack(receive(http, unmarshallFunc)); 
    21                         }; 
    22                 } 
    23         } 
    24         else { 
    25                 if(window.ActiveXObject){ 
    26                         http.onreadystatechange = function () {}; 
     10                var errorStr = "" + ex.message; 
     11 
     12                // errorStr += "\n"; 
     13                // errorStr += "httpStatus : "  + ex.httpStatus  + "\n"; 
     14                // errorStr += "code: "         + ex.code        + "\n"; 
     15                // errorStr += "contentType : " + ex.contentType + "\n"; 
     16                // errorStr += "data : "        + ex.data        + "\n"; 
     17 
     18                alert(errorStr); 
     19                return; 
     20        }, 
     21 
     22        /** 
     23         * Send request 
     24         */ 
     25        sendJsspRpcRequest : function(url, argsArray, callback, onErrorCallback, method){ 
     26 
     27                onErrorCallback = (onErrorCallback == null) ? ImJsspRpc.defaultOnErrorCallback : onErrorCallback; 
     28                method = (method == undefined) ? "post" : method; 
     29 
     30                var jsonString = ImJson.toJSONString(argsArray); 
     31                var asynFlag   = (callback != null); 
     32 
     33                //==================================== 
     34                // Create XMLHttpRequest(=xhr) 
     35                //==================================== 
     36                var xhr = ImAjax.createXMLHttpRequest(); 
     37 
     38                //==================================== 
     39                // Set callback function 
     40                //==================================== 
     41                if(asynFlag){ 
     42                        if(window.ActiveXObject){ 
     43                                xhr.onreadystatechange = function () { 
     44                                        if (xhr.readyState == 4) { 
     45                                                var result; 
     46 
     47                                                try{ 
     48                                                        result = ImJsspRpc.receive(xhr); 
     49                                                } 
     50                                                catch(ex){ 
     51                                                        onErrorCallback(ex); 
     52                                                        return; 
     53                                                } 
     54 
     55                                                callback(result); 
     56                                        } 
     57                                }; 
     58                        } 
     59                        else { 
     60                                xhr.onload = function () { 
     61                                                var result; 
     62 
     63                                                try{ 
     64                                                        result = ImJsspRpc.receive(xhr); 
     65                                                } 
     66                                                catch(ex){ 
     67                                                        onErrorCallback(ex); 
     68                                                        return; 
     69                                                } 
     70 
     71                                                callback(result); 
     72                                }; 
     73                        } 
    2774                } 
    2875                else { 
    29                         http.onload = function () {}; 
     76                        if(window.ActiveXObject){ 
     77                                xhr.onreadystatechange = function(){}; 
     78                        } 
     79                        else { 
     80                                xhr.onload = function(){}; 
     81                        } 
    3082                } 
    31         } 
    3283 
    33         http.open(method, url, (callBack != null)); 
    34         setContentType(http); 
    35         try { 
    36                 http.send(jsonString); 
    37         } 
    38         catch(ex) { 
    39                 // For IE on WinXP (Error: 0x800c0008(-2146697208)) 
    40                 writeDocument(http.responseText); 
    41                 throw ex; 
    42         } 
     84                //==================================== 
     85                // Send Request 
     86                //==================================== 
     87                xhr.open(method, url, asynFlag); 
     88                xhr = ImAjax.setContentTypeAndReqHeaders(xhr, ImJsspRpc.JSON_CONTENT_TYPE); 
     89                xhr.send(jsonString); 
    4390 
    44         if(callBack != null){ 
    45                 return; 
    46         } 
    47         else{ 
    48                 return receive(http, unmarshallFunc); 
     91 
     92                //==================================== 
     93                // Return result 
     94                //==================================== 
     95                if(asynFlag){ 
     96                        return; 
     97                } 
     98                else{ 
     99                        return ImJsspRpc.receive(xhr); 
     100                } 
     101        }, 
     102 
     103        /** 
     104         * Receive response data 
     105         */ 
     106        receive : function(xhr){ 
     107 
     108                var objResult = ImAjax.createResultObject(xhr); 
     109 
     110                if(objResult.error == true){ 
     111                        var err = new Error(objResult.message); 
     112                                err.httpStatus  = objResult.httpStatus; 
     113                                err.code        = objResult.code; 
     114                                err.message     = objResult.message; 
     115                                err.contentType = objResult.contentType; 
     116                                err.data        = objResult.data; 
     117 
     118                        // **** THROW ERROR **** 
     119                        throw err; 
     120                } 
     121                else{ 
     122                        return objResult.data; 
     123                } 
     124 
    49125        } 
    50126} 
    51  
    52  
    53 /** 
    54  * Create XMLHttpRequest 
    55  */ 
    56 function createXMLHttpRequest(){ 
    57         var msxmlNames = 
    58                         new Array("MSXML2.XMLHTTP.5.0", "MSXML2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"); 
    59  
    60         /* Mozilla XMLHttpRequest */ 
    61         try { 
    62                 return new XMLHttpRequest(); 
    63         } catch(e) {} 
    64  
    65         /* Microsoft MSXML ActiveX */ 
    66         for (var i=0;i < msxmlNames.length; i++) { 
    67                 try { 
    68                         return new ActiveXObject(msxmlNames[i]); 
    69                 } catch (e) {} 
    70         } 
    71 } 
    72  
    73  
    74 /** 
    75  * Receive response data 
    76  */ 
    77 function receive(http, unmarshallFunc){ 
    78         /* Get request results */ 
    79         var status, statusText, data; 
    80         try { 
    81                 status     = http.status; 
    82                 statusText = http.statusText; 
    83                 data       = http.responseText; 
    84         } 
    85         catch(ex) { 
    86                 throw ex; 
    87         } 
    88  
    89         if(status != 200){ 
    90                 // When error happens with session timeout, or internal server error. 
    91                 writeDocument(data); 
    92                 throw new Error(status, statusText); 
    93         } 
    94  
    95         /* un-marshall */ 
    96         try{ 
    97                 return unmarshallFunc(data); 
    98         } 
    99         catch(ex){ 
    100                                  
    101                 // if(ex.name == "SyntaxError" && ex.message == "parseJSON"){ 
    102                 //     alert("Error occurred!! \n" + ex.name + ": " + ex.message); 
    103                 //     throw ex; 
    104                 // } 
    105  
    106                 // For Debug.Browse() page, mostly. 
    107                 writeDocument(data); 
    108                 return; 
    109         } 
    110 } 
    111  
    112  
    113 /** 
    114  * Set Content-Type value 
    115  */ 
    116 function setContentType(http){ 
    117         var contentTypeUrlenc = 'application/json; charset=utf-8'; 
    118  
    119         if(!window.opera){ 
    120                 http.setRequestHeader('Content-Type',contentTypeUrlenc); 
    121         } 
    122         else { 
    123                 if((typeof http.setRequestHeader) == 'function'){ 
    124                         http.setRequestHeader('Content-Type',contentTypeUrlenc); 
    125                 } 
    126         } 
    127  
    128         return http; 
    129 } 
    130  
    131  
    132 /** 
    133  * Write document 
    134  */ 
    135 function writeDocument(value){ 
    136         document.write(value); 
    137         document.close(); 
    138         return; 
    139 }