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