001/* 002 * Copyright (c) 2009 The openGion Project. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 013 * either express or implied. See the License for the specific language 014 * governing permissions and limitations under the License. 015 */ 016package org.opengion.fukurou.util; 017 018import java.io.BufferedInputStream; 019import java.io.BufferedReader; 020import java.io.File; 021import java.io.IOException; 022import java.io.InputStream; 023import java.io.InputStreamReader; 024import java.io.OutputStream; 025import java.io.PrintStream; 026import java.io.PrintWriter; 027import java.io.UnsupportedEncodingException; 028import java.net.HttpURLConnection; 029import java.net.InetSocketAddress; 030import java.net.Proxy; 031import java.net.SocketAddress; 032import java.net.URL; 033import java.net.URLConnection; 034 035import org.apache.commons.codec.binary.Base64; 036 037/** 038 * URLConnect は、指定のURL にアクセスして、情報/データを取得します。 039 * URL へのアクセスにより、エンジンでは各種処理を実行させることが可能になります。 040 * 例えば、帳票デーモンの起動や、長時間かかる処理の実行などです。 041 * なお、URLに引数が付く場合は、ダブルコーテーションで括って下さい。 042 * - 付き引数は、指定順番は、関係ありません。- 無し引数(url,user:passwd)は、 043 * 順番があります。 044 * 045 * Usage: java org.opengion.fukurou.util.URLConnect [-info/-data] … url [user:passwd] 046 * 047 * args[*] : [-info/-data] 情報の取得か、データの取得かを指定します(初期値:-data)。 048 * args[*] : [-post=ファイル名] POSTメソッドを指定して、ファイルデータを送信します(初期値:-get)。 049 * args[*] : [-encode=UTF-8] エンコードを指定します(通常は接続先のencodeを使用)。 050 * args[*] : [-out=ファイル名] 結果を指定されたファイルエンコードでファイルに出力します。 051 * args[*] : [-errEx=true/false] trueの場合、レスポンスコードが、4XX,5XX の時に RuntimeException を投げます(初期値:false)。 052 * args[A] : url URLを指定します。GETの場合、パラメータは ?KEY=VALです。 053 * args[B] : [user:passwd] BASIC認証のエリアへのアクセス時に指定します。 054 * 055 * ※ プロキシ設定の3つの方法 056 * プロキシ設定には、3つの方法があります。 057 * 1. 058 * URL url = URL( "http",proxyHost,proxyPort, url ); 059 * URLConnection urlConn = url.openConnection(); 060 * 2. 061 * SocketAddress scaddr = new InetSocketAddress( proxyHost, proxyPort ); 062 * Proxy proxy = new Proxy( Proxy.Type.HTTP, scaddr ); 063 * URL url = new Url( url ); 064 * URLConnection urlConn = url.openConnection( proxy ); 065 * 3. 066 * System.setProperty( "http.proxyHost",host ); 067 * System.setProperty( "http.proxyPort",String.valueOf( port ) ); 068 * URL url = new Url( url ); 069 * URLConnection urlConn = url.openConnection(); 070 * System.clearProperty( "http.proxyHost" ); 071 * System.clearProperty( "http.proxyPort" ); 072 * 073 * 1. 、2. の方法は、urlConn.getContentType() を実行すると、エラーになります。(原因不明) 074 * 3. の方法では、マルチスレッドで実行する場合に、問題が発生します。 075 * 本クラスでは、方法2 を使用しています。 076 * 077 * @version 4.0 078 * @author Kazuhiko Hasegawa 079 * @since JDK5.0, 080 */ 081public class URLConnect { 082 private static final String CR = System.getProperty("line.separator"); 083 084// private static final String ENCODE = "UTF-8"; 085 086 private final String urlStr ; 087 private final String userPass ; 088 089 private int rpsCode = -1; 090 private String rpsMethod = null; 091 private String rpsMessage = null; 092 private String type = null; 093 private String charset = null; 094 private String postData = null; 095 private int timeout = -1; // 5.8.8.1 (2015/06/12) timeout属性追加 096 private long length = -1; 097 private long date = -1; 098 private long modified = -1; 099 private boolean isPost = false; 100 private URLConnection conn = null; 101 private Proxy proxy = Proxy.NO_PROXY; 102 103 // 5.8.3.0 (2015/01/09) 追加 104 private String[] propKeys; 105 private String[] propVals; 106 107 /** 108 * コンストラクター 109 * 110 * @param url 接続するアドレスを指定します。(http://server:port/dir/file.html) 111 * @param pass ユーザー:パスワード(認証接続が必要な場合) 112 */ 113 public URLConnect( final String url, final String pass ) { 114 urlStr = url; 115 userPass = pass; 116 } 117 118 /** 119 * 指定のURLに対して、コネクトするのに使用するプロキシ設定を行います。 120 * このときに、ヘッダー情報を内部変数に設定しておきます。 121 * 122 * @param host 接続するプロキシのホスト名 123 * @param port 接続するプロキシのポート番号 124 */ 125 public void setProxy( final String host,final int port ) { 126 // 方法2. 127 SocketAddress scaddr = new InetSocketAddress( host, port ); 128 proxy = new Proxy( Proxy.Type.HTTP, scaddr ); 129 } 130 131 /** 132 * 指定のURLに対して、コネクトします。 133 * このときに、ヘッダー情報を内部変数に設定しておきます。 134 * 135 * @og.rev 4.0.1.0 (2007/12/12) Postで複数キーを使えるように修正 136 * @og.rev 5.1.6.0 (2010/05/01) charsetを指定できるようにする 137 * @throws IOException 入出力エラーが発生したとき 138 */ 139 public void connect() throws IOException { 140 conn = getConnection(); 141 142 if( isPost ) { 143 conn.setDoOutput( true ); // POST可能にする 144 145 OutputStream os = null; // POST用のOutputStream 146 PrintStream ps = null; 147 try { 148 os = conn.getOutputStream(); // POST用のOutputStreamを取得 149 // 5.1.6.0 (2010/05/01) 150 if( charset != null ) { 151 ps = new PrintStream( os, false, charset ); 152 } 153 else { 154 ps = new PrintStream( os ); 155 } 156 ps.print( postData ); // 4.1.0.0 (2007/12/22) 157 } 158 finally { 159 Closer.ioClose( ps ); // close 処理時の IOException を無視 160 Closer.ioClose( os ); // close 処理時の IOException を無視 161 } 162 } 163 else { 164 // GET 時のコネクション接続 165 conn.connect(); 166 } 167 168 setInfo( conn ); 169 } 170 171 /** 172 * U接続先のデータを取得します。 173 * 174 * この処理の前に、connect() 処理を実行しておく必要があります。 175 * 取得したデータは、指定のURL へのアクセスのみです。 176 * 通常のWebブラウザは、イメージや、JavaScriptファイル、CSSファイルなど、 177 * 各種ファイル毎にHTTP接続を行い、取得して、レンダリングします。 178 * このメソッドでの処理では、それらのファイル内に指定されているURLの 179 * 再帰的な取得は行いません。 180 * よって、フレーム処理なども行いません。 181 * 本来は、Stream のまま処理することで、バイナリデータも扱えますが、ここでは、 182 * テキストデータ(String)に変換して使用できるデータのみ扱えます。 183 * 184 * @return 接続結果 185 * @throws IOException 入出力エラーが発生したとき 186 */ 187 public String readData() throws IOException { 188 if( conn == null ) { 189 String errMsg = "connect() されていません。データ取得前にconnect()してください。"; 190 throw new RuntimeException( errMsg ); 191 } 192 193 BufferedReader reader = null; 194 StringBuilder buf = new StringBuilder(); 195 try { 196 reader = getReader(); 197 198 String line ; 199 while( (line = reader.readLine()) != null ) { 200 buf.append( line ).append( CR ); 201 } 202 } 203 catch( UnsupportedEncodingException ex ) { 204 String errMsg = "指定された文字エンコーディングがサポートされていません。" + CR 205 + " url=[" + urlStr + "]" 206 + " charset=[" + charset + "]" ; 207 throw new RuntimeException( errMsg,ex ); 208 } 209 finally { 210 Closer.ioClose( reader ); 211 disconnect(); 212 } 213 214 return buf.toString(); 215 } 216 217 /** 218 * サーバへのほかの要求が今後発生しそうにないことを示します。 219 * 220 */ 221 public void disconnect() { 222 if( conn instanceof HttpURLConnection ) { 223 ((HttpURLConnection)conn).disconnect() ; 224 } 225 } 226 227 /** 228 * URL と ユーザー:パスワードを与えて、URLConnectionを返します。 229 * 230 * ユーザー:パスワード が null でない場合は、BASCI認証エリアへのアクセスの為、 231 * BASE64Encoder を行って、Authorization プロパティーを設定します。 232 * ここで返す URLConnection は、すでに、connect() メソッド実行済みの 233 * リモート接続が完了した状態のオブジェクトです。 234 * 235 * @og.rev 5.8.3.0 (2015/01/09) ヘッダ等指定のためにsetRequestPropertyの値を指定できるようにします。 236 * @og.rev 5.8.8.1 (2015/06/12) 237 * 238 * @return URLConnectionオブジェクト 239 * @throws IOException 入出力エラーが発生したとき 240 */ 241 // 5.1.5.0 (2010/04/01) SOAP対応により、PROTECTED化 242 protected URLConnection getConnection() throws IOException { 243// private URLConnection getConnection() throws IOException { 244 final URL url = new URL( urlStr ); 245 246 // 方法2. 247 URLConnection urlConn = url.openConnection( proxy ); 248 249 if( userPass != null ) { 250// byte[] encoded = Base64.encodeBase64( userPass.getBytes() ); 251// String userPassEnc = new String( encoded ); 252 byte[] encoded = Base64.encodeBase64( userPass.getBytes( StringUtil.DEFAULT_CHARSET ) ); // 5.5.2.6 (2012/05/25) findbugs対応 253 String userPassEnc = new String( encoded,StringUtil.DEFAULT_CHARSET ); // 5.5.2.6 (2012/05/25) findbugs対応 254 urlConn.setRequestProperty( "Authorization","Basic " + userPassEnc ); 255 } 256 257 // 5.8.3.0 (2015/01/09) RequestPropertyのセット 258 if( propKeys != null && propKeys.length > 0 ){ 259 for(int i = 0; i < propKeys.length; i++){ 260 urlConn.setRequestProperty( propKeys[i], propVals[i] ); 261 } 262 } 263 264 // 5.8.8.1 (2015/06/12) timeout属性追加 265 if( timeout >= 0 ) { 266 urlConn.setConnectTimeout( timeout * 1000 ); // 引数は(秒)、設定は(ミリ秒) 267 } 268 269 return urlConn ; 270 } 271 272 /** 273 * 接続先の情報を内部変数に設定します。 274 * 275 * ここでは、タイプ,エンコード,レスポンスコード,レスポンスメッセージ を設定します。 276 * レスポンスコード,レスポンスメッセージは、接続コネクションが、HttpURLConnection の 277 * 場合のみセットされます。 278 * 途中でエラーが発生した場合でも、継続処理できるようにします。これは、プロキシ 279 * 設定の方法により、conn.getContentType() でエラーが発生する場合があるためです。 280 * 281 * @og.rev 5.5.9.1 (2012/12/07) charsetは、null の場合のみ設定します。 282 * 283 * @param conn 接続先のコネクション 284 */ 285 private void setInfo( final URLConnection conn ) { 286 try { 287 // 5.5.9.1 (2012/12/07) charsetは、null の場合のみ設定します。 288 if( charset == null ) { charset = conn.getContentEncoding(); } 289 type = conn.getContentType() ; 290 length = conn.getContentLength(); 291 date = conn.getDate(); 292 modified= conn.getLastModified(); 293 294 if( charset == null && type != null ) { 295 int adrs = type.indexOf( "charset" ); 296 int adrs2 = type.indexOf( '=',adrs ); 297 if( adrs > 0 && adrs2 > adrs ) { 298 charset = type.substring( adrs2+1 ).trim(); 299 } 300 } 301 302 if( conn instanceof HttpURLConnection ) { 303 HttpURLConnection httpConn = (HttpURLConnection) conn; 304 rpsCode = httpConn.getResponseCode(); 305 rpsMethod = httpConn.getRequestMethod(); 306 rpsMessage = httpConn.getResponseMessage() + code2Message( rpsCode ); 307 } 308 } 309 // 4.0.0.0 (2007/11/29) Exception から、IOException と RuntimeException に変更 310 catch( IOException ex ) { 311 System.out.println( ex.getMessage() ); 312 } 313 catch( RuntimeException ex ) { 314 System.out.println( ex.getMessage() ); 315 } 316 } 317 318 /** 319 * URL 情報を取得します。 320 * 321 * @og.rev 4.3.4.4 (2009/01/01) メソッド名変更 322 * 323 * @return URL情報 324 */ 325 public String getUrl() { return urlStr; } 326 327 /** 328 * setRequestPropertyでセットするデータを設定します。 329 * 330 * keys,vals各々、カンマ区切りで分解します。 331 * 332 * @og.rev 5.8.3.0 (2007/12/22) 追加 333 * @param keys パラメータキー(カンマ区切り) 334 * @param vals パラメータ(カンマ区切り) 335 */ 336 public void setRequestProperty( final String keys, final String vals ) { 337 if( keys != null && keys.length() > 0 && vals != null && vals.length() > 0 ){ 338 propKeys = StringUtil.csv2Array( keys ); 339 propVals = StringUtil.csv2Array( vals ); 340 341 if( propKeys.length != propVals.length ) { 342 final String errMsg = "パラメータのキーと、値の数が一致しません。" + CR 343 + " key=[" + keys + "]" + CR 344 + " val=[" + vals + "]" ; 345 throw new IllegalArgumentException( errMsg ); 346 } 347 } 348 } 349 350 /** 351 * POSTするデータを設定します。 352 * 353 * POSTする場合は、connect() 処理を行う前に、データを設定しておく必要があります。 354 * 355 * @og.rev 4.1.0.0 (2007/12/22) キーと値のセットを取得するよう変更 356 * @param data POSTデータ 357 */ 358 public void setPostData( final String data ) { 359 postData = data; 360 if( postData != null && "?".indexOf( postData ) == 0 ) { // 先頭の?を抜く 361 postData = postData.substring(1); 362 } 363 if( postData != null ) { isPost = true; } 364 } 365 366 /** 367 * タイプ 情報を取得します。 368 * 369 * @return タイプ 情報 370 */ 371 public String getType() { return type; } 372 373 /** 374 * データ量 情報を取得します。 375 * 376 * @return データ量 情報 377 */ 378 public long getLength() { return length; } 379 380 /** 381 * 作成日時 情報を取得します。 382 * 383 * @return 作成日時 384 */ 385 public long getDate() { return date; } 386 387 /** 388 * 更新日時 情報を取得します。 389 * 390 * @return 更新日時 391 */ 392 public long getModified() { return modified; } 393 394 /** 395 * 結果コード 情報(HttpURLConnection)を取得します。 396 * 397 * @return 結果コード 情報 398 */ 399 public int getCode() { return rpsCode; } 400 401 /** 402 * メソッド 情報(HttpURLConnection)を取得します。 403 * 404 * @return メソッド 情報 405 */ 406 public String getMethod() { return rpsMethod; } 407 408 /** 409 * メッセージ 情報(HttpURLConnection)を取得します。 410 * 411 * @return メッセージ 情報 412 */ 413 public String getMessage() { return rpsMessage; } 414 415 /** 416 * キャラクタ 情報を取得します。 417 * 418 * @return キャラクタ 情報 419 */ 420 public String getCharset() { return charset; } 421 422 /** 423 * キャラクタ 情報を設定します。 424 * 425 * @param chset キャラクタ 情報 426 */ 427 public void setCharset( final String chset ) { charset = chset; } 428 429 /** 430 * 接続タイムアウト時間を(秒)で指定します 431 * 432 * 実際には、java.net.URLConnection#setConnectTimeout(int) に 1000倍して設定されます。 433 * 0 は、無限のタイムアウト、マイナスは、設定しません。(つまりJavaの初期値のまま) 434 * 435 * @og.rev 5.8.8.1 (2015/06/12) timeout属性追加 436 * 437 * @param tout タイムアウト時間(秒) (ゼロは、無制限) 438 * @see java.net.URLConnection#setConnectTimeout(int) 439 */ 440 public void setTimeout( final int tout ) { 441 timeout = tout; 442 } 443 444 /** 445 * 接続先のデータのリーダーを取得します。 446 * 447 * この処理の前に、connect() 処理を実行しておく必要があります。 448 * 取得したデータは、指定のURL へのアクセスのみです。 449 * 通常のWebブラウザは、イメージや、JavaScriptファイル、CSSファイルなど、 450 * 各種ファイル毎にHTTP接続を行い、取得して、レンダリングします。 451 * このメソッドでの処理では、それらのファイル内に指定されているURLの 452 * 再帰的な取得は行いません。 453 * よって、フレーム処理なども行いません。 454 * 455 * @return 接続結果のリーダー 456 * @throws IOException 入出力エラーが発生したとき 457 */ 458 public BufferedReader getReader() throws IOException { 459 InputStream in = conn.getInputStream(); 460 461 final BufferedReader reader ; 462 if( charset != null ) { 463 reader = new BufferedReader( new InputStreamReader( in,charset ) ); 464 } 465 else { 466// reader = new BufferedReader( new InputStreamReader( in ) ); 467 reader = new BufferedReader( new InputStreamReader( in,StringUtil.DEFAULT_CHARSET ) ); // 5.5.2.6 (2012/05/25) findbugs対応 468 } 469 470 return reader; 471 } 472 473 /** 474 * 接続先のデータの入力ストリームを取得します。 475 * 476 * この処理の前に、connect() 処理を実行しておく必要があります。 477 * 取得したデータは、指定のURL へのアクセスのみです。 478 * 通常のWebブラウザは、イメージや、JavaScriptファイル、CSSファイルなど、 479 * 各種ファイル毎にHTTP接続を行い、取得して、レンダリングします。 480 * このメソッドでの処理では、それらのファイル内に指定されているURLの 481 * 再帰的な取得は行いません。 482 * よって、フレーム処理なども行いません。 483 * 484 * @og.rev 5.4.2.0 (2011/12/01) 新規追加 485 * 486 * @return 接続結果の入力を出力します。 487 * @throws IOException 入出力エラーが発生したとき 488 */ 489 public InputStream getInputStream() throws IOException { 490// InputStream in = new BufferedInputStream( conn.getInputStream() ); 491// return in; 492 return new BufferedInputStream( conn.getInputStream() ); // 5.5.2.4 (2012/05/16) 493 } 494 495 /** 496 * HttpURLConnection のレスポンスコードに対応するメッセージ文字列を返します。 497 * 498 * HttpURLConnection の getResponseCode() メソッドにより取得された、HTTPレスポンスコード 499 * に対応する文字列を返します。この文字列は、HttpURLConnection で定義された 500 * static 定数のコメントを、定義しています。 501 * 502 * @og.rev 5.6.7.0 (2013/07/27) レスポンスコード例 追加 503 * 504 * @param code HTTPレスポンスコード 505 * 506 * @return レスポンスコードに対応する文字列 507 * @see HttpURLConnection#HTTP_ACCEPTED 508 */ 509 public static String code2Message( final int code ) { 510 final String msg ; 511 switch( code ) { 512 case 100 : msg = "100: 要求は続行可能です。" ; break; // 5.6.7.0 (2013/07/27) 513 case 101 : msg = "101: プロトコルを切り替えます。" ; break; // 5.6.7.0 (2013/07/27) 514 case HttpURLConnection.HTTP_OK : msg = "200: OK です。" ; break; 515 case HttpURLConnection.HTTP_CREATED : msg = "201: 作成されました。" ; break; 516 case HttpURLConnection.HTTP_ACCEPTED : msg = "202: 許可されました。" ; break; 517 case HttpURLConnection.HTTP_NOT_AUTHORITATIVE : msg = "203: 不当な情報です。" ; break; 518 case HttpURLConnection.HTTP_NO_CONTENT : msg = "204: コンテンツがありません。" ; break; 519 case HttpURLConnection.HTTP_RESET : msg = "205: コンテンツをリセットします。" ; break; 520 case HttpURLConnection.HTTP_PARTIAL : msg = "206: 部分的なコンテンツです。" ; break; 521 case HttpURLConnection.HTTP_MULT_CHOICE : msg = "300: 複数選択されています。" ; break; 522 case HttpURLConnection.HTTP_MOVED_PERM : msg = "301: 永続的に移動されました。" ; break; 523 case HttpURLConnection.HTTP_MOVED_TEMP : msg = "302: 一時的に切り替えます。" ; break; 524 case HttpURLConnection.HTTP_SEE_OTHER : msg = "303: 他を参照してください。" ; break; 525 case HttpURLConnection.HTTP_NOT_MODIFIED : msg = "304: 修正されませんでした。" ; break; 526 case HttpURLConnection.HTTP_USE_PROXY : msg = "305: プロキシを使用してください。" ; break; 527 case 306 : msg = "306: 仕様の拡張案です。" ; break; // 5.6.7.0 (2013/07/27) 528 case 307 : msg = "307: 一時的なリダイレクトです。" ; break; // 5.6.7.0 (2013/07/27) 529 case HttpURLConnection.HTTP_BAD_REQUEST : msg = "400: 不当な要求です。" ; break; 530 case HttpURLConnection.HTTP_UNAUTHORIZED : msg = "401: 認証されませんでした。" ; break; 531 case HttpURLConnection.HTTP_PAYMENT_REQUIRED : msg = "402: 支払いが必要です。" ; break; 532 case HttpURLConnection.HTTP_FORBIDDEN : msg = "403: 禁止されています。" ; break; 533 case HttpURLConnection.HTTP_NOT_FOUND : msg = "404: 見つかりませんでした。" ; break; 534 case HttpURLConnection.HTTP_BAD_METHOD : msg = "405: メソッドは許可されません。" ; break; 535 case HttpURLConnection.HTTP_NOT_ACCEPTABLE : msg = "406: 許容されません。" ; break; 536 case HttpURLConnection.HTTP_PROXY_AUTH : msg = "407: プロキシの認証が必要です。" ; break; 537 case HttpURLConnection.HTTP_CLIENT_TIMEOUT : msg = "408: 要求が時間切れです。" ; break; 538 case HttpURLConnection.HTTP_CONFLICT : msg = "409: 重複しています。" ; break; 539 case HttpURLConnection.HTTP_GONE : msg = "410: 存在しません。" ; break; 540 case HttpURLConnection.HTTP_LENGTH_REQUIRED : msg = "411: 長さが必要です。" ; break; 541 case HttpURLConnection.HTTP_PRECON_FAILED : msg = "412: 前提条件が正しくありません。" ; break; 542 case HttpURLConnection.HTTP_ENTITY_TOO_LARGE : msg = "413: 要求エンティティが長すぎます。" ; break; 543 case HttpURLConnection.HTTP_REQ_TOO_LONG : msg = "414: 要求 URL が長すぎます。" ; break; 544 case HttpURLConnection.HTTP_UNSUPPORTED_TYPE : msg = "415: サポートされないメディアタイプです。" ; break; 545 case 416 : msg = "416: 要求された範囲は不十分です。" ; break; // 5.6.7.0 (2013/07/27) 546 case 417 : msg = "417: 要求どおりの処理が不可能です。" ; break; // 5.6.7.0 (2013/07/27) 547 case HttpURLConnection.HTTP_INTERNAL_ERROR : msg = "500: 内部サーバエラーです。" ; break; 548 case HttpURLConnection.HTTP_NOT_IMPLEMENTED : msg = "501: 実装されていません。" ; break; 549 case HttpURLConnection.HTTP_BAD_GATEWAY : msg = "502: 誤ったゲートウェイです。" ; break; 550 case HttpURLConnection.HTTP_UNAVAILABLE : msg = "503: サービスが利用できません。" ; break; 551 case HttpURLConnection.HTTP_GATEWAY_TIMEOUT : msg = "504: ゲートウェイが時間切れです。" ; break; 552 case HttpURLConnection.HTTP_VERSION : msg = "505: HTTP バージョンがサポートされていません。"; break; 553// default : msg = "-1: 未定義" ; 554 default : msg = code + ": 未定義" ; // 5.6.7.0 (2013/07/27) 555 } 556 return msg ; 557 } 558 559 /** 560 * サンプル実行用のメインメソッド 561 * 562 * Usage: java org.opengion.fukurou.util.URLConnect [-info/-data] … url [user:passwd] 563 * 564 * args[*] : [-info/-data] 情報の取得か、データの取得かを指定します(初期値:-data)。 565 * args[*] : [-post=ファイル名] POSTメソッドを指定して、ファイルデータを送信します(初期値:-get)。 566 * args[*] : [-encode=UTF-8] エンコードを指定します(通常は接続先のencodeを使用) 567 * args[*] : [-out=ファイル名] 結果をファイルに出力します。ファイルエンコードも指定します。 568 * args[*] : [-errEx=true/false] trueの場合、レスポンスコードが、4XX,5XX の時に RuntimeException を投げます(初期値:false)。 569 * args[A] : url URLを指定します。GETの場合、パラメータは ?KEY=VALです。 570 * args[B] : [user:passwd] BASIC認証のエリアへのアクセス時に指定します。 571 * 572 * @og.rev 5.6.7.0 (2013/07/27) -errEx 追加 573 * 574 * @param args コマンド引数配列 575 * @throws IOException 入出力エラーが発生したとき 576 */ 577 public static void main( final String[] args ) throws IOException { 578 if( args.length < 3 ) { 579 LogWriter.log( "Usage: java org.opengion.fukurou.util.URLConnect [-info/-data] … url [user:passwd]" ); 580 LogWriter.log( " args[*] : [-info/-data] 情報の取得か、データの取得かを指定します(初期値:-data)" ); 581 LogWriter.log( " args[*] : [-post=ファイル名] POSTメソッドを指定して、ファイルデータを送信します(初期値:-get)" ); 582 LogWriter.log( " args[*] : [-encode=UTF-8] エンコードを指定します。(通常は接続先のencodeを使用)" ); 583 LogWriter.log( " args[*] : [-out=ファイル名] 結果をファイルに出力します。ファイルエンコードも指定します" ); 584 LogWriter.log( " args[*] : [-errEx=true/false] trueの場合、レスポンスコードが、4XX,5XX の時に RuntimeException を投げます(初期値:false)" ); 585 LogWriter.log( " args[A] : url URLを指定します。GETの場合、パラメータは ?KEY=VALです" ); 586 LogWriter.log( " args[B] : [user:passwd] BASIC認証のエリアへのアクセス時に指定します" ); 587 return; 588 } 589 590 boolean isInfo = false ; 591 boolean isPost = false ; 592 String postKey = null ; 593 String postFile = null ; 594 String encode = null ; 595 String outFile = null ; 596 boolean isEx = false ; // 5.6.7.0 (2013/07/27) 追加 597 String[] vals = new String[2]; // url,userPass の順に引数設定 598 599 int adrs = 0; 600 for( int i=0; i<args.length; i++ ) { 601 String arg = args[i]; 602 if( arg.equalsIgnoreCase( "-info" ) ) { 603 isInfo = true; 604 } 605 else if( arg.equalsIgnoreCase( "-data" ) ) { 606 isInfo = false; 607 } 608 else if( arg.startsWith( "-post=" ) ) { 609 isPost = true; 610 int sepAdrs = arg.indexOf( ':',6 ); 611 postKey = arg.substring( 6,sepAdrs ); 612 postFile = arg.substring( sepAdrs+1 ); 613 } 614 else if( arg.startsWith( "-encode=" ) ) { 615 encode = arg.substring( 8 ); 616 } 617 else if( arg.startsWith( "-out=" ) ) { 618 outFile = arg.substring( 5 ); 619 } 620 else if( arg.startsWith( "-errEx=" ) ) { // 5.6.7.0 (2013/07/27) 追加 621 isEx = "true".equalsIgnoreCase( arg.substring( 7 ) ); 622 } 623 else if( arg.startsWith( "-" ) ) { 624 System.out.println( "Error Argment:" + arg ); 625 } 626 else { 627 vals[adrs++] = arg; 628 } 629 } 630 631 String urlStr = vals[0] ; 632 String userPass = vals[1] ; 633 634 URLConnect conn = new URLConnect( urlStr,userPass ); 635 636 // POST データは、connect() する前に、設定します。 637 if( isPost ) { 638 FileString file = new FileString(); 639 file.setFilename( postFile ); 640 String postData = file.getValue(); 641 642 conn.setPostData( XHTMLTag.urlEncode(postKey, postData) ); 643 } 644 645 conn.connect(); 646 if( encode != null ) { 647 conn.setCharset( encode ); // encode 指定 648 } 649 else { 650 encode = conn.getCharset(); // 指定がなければ、接続先の charset を使用 651 } 652 653 final PrintWriter writer ; 654 if( outFile != null ) { 655 writer = FileUtil.getPrintWriter( new File( outFile ),encode ); 656 } 657 else { 658 writer = FileUtil.getLogWriter( "System.out" ); 659 } 660 661 int code = conn.getCode(); // 5.6.7.0 (2013/07/27) レスポンスコードは、常に拾っておきます。 662 if( isInfo ) { 663 writer.println( "URL :" + conn.getUrl() ); 664 writer.println( "Type :" + conn.getType() ); 665// writer.println( "Code :" + conn.getCode() ); 666 writer.println( "Code :" + code ); // 5.6.7.0 (2013/07/27) 取得済みの値を利用。 667 writer.println( "Message:" + conn.getMessage() ); 668 writer.println( "Charset:" + conn.getCharset() ); 669 } 670 else { 671 writer.println( conn.readData() ); 672 } 673 674 conn.disconnect(); 675 676 Closer.ioClose( writer ); 677 678 // 5.6.7.0 (2013/07/27) trueの場合、レスポンスコードが、4XX,5XX の時に RuntimeException を投げます 679 if( isEx && code >= 400 ) { 680 String errMsg = URLConnect.code2Message( code ); 681 throw new RuntimeException( errMsg ); 682 } 683 } 684}