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.mail; 017 018import org.opengion.fukurou.system.OgRuntimeException ; // 6.4.2.0 (2016/01/29) 019import org.opengion.fukurou.system.LogWriter; 020import static org.opengion.fukurou.system.HybsConst.CR; // 6.1.0.0 (2014/12/26) refactoring 021 022import java.io.UnsupportedEncodingException; 023import java.util.Properties; 024import java.util.Date; 025 026import javax.activation.FileDataSource; 027import javax.activation.DataHandler; 028import javax.mail.internet.InternetAddress; 029import javax.mail.internet.AddressException; 030import javax.mail.internet.MimeMessage; 031import javax.mail.internet.MimeMultipart; 032import javax.mail.internet.MimeBodyPart; 033import javax.mail.internet.MimeUtility; 034import javax.mail.Authenticator; // 6.2.4.1 (2015/05/22) SMTP_AUTH 対応 035import javax.mail.PasswordAuthentication; // 6.2.4.1 (2015/05/22) SMTP_AUTH 対応 036import javax.mail.Store; 037import javax.mail.Transport; 038import javax.mail.Session; 039import javax.mail.Message; 040import javax.mail.MessagingException; 041import javax.mail.IllegalWriteException; 042 043/** 044 * MailTX は、SMTPプロトコルによるメール送信プログラムです。 045 * 046 * E-Mail で日本語を送信する場合、ISO-2022-JP(JISコード)化して、7bit で 047 * エンコードして送信する必要がありますが、Windows系の特殊文字や、unicodeと 048 * 文字のマッピングが異なる文字などが、文字化けします。 049 * 対応方法としては、 050 * 1.Windows-31J + 8bit 送信 051 * 2.ISO-2022-JP に独自変換 + 7bit 送信 052 * の方法があります。 053 * 今回、この2つの方法について、対応いたしました。 054 * 055 * ※ 6.3.8.0 (2015/09/11) 056 * useSSL属性=true に設定すると、protocolに、smtps を使用します。 057 * 058 * @version 4.0 059 * @author Kazuhiko Hasegawa 060 * @since JDK5.0, 061 */ 062public class MailTX { 063 private static final String AUTH_PBS = "POP_BEFORE_SMTP"; // 5.4.3.2 064 private static final String AUTH_SMTPA = "SMTP_AUTH"; // 6.2.4.1 (2015/05/22) SMTP_AUTH 対応 065 066 /** メーラーの名称 {@value} */ 067 public static final String MAILER = "openGion Mail Ver 6.0"; 068 069 private final String charset ; // Windwos-31J , MS932 , UTF-8 , ISO-2022-JP 070 private String[] filename ; 071 private String message ; 072 private Session session ; 073 private MimeMultipart mmPart ; 074 private MimeMessage mimeMsg ; 075 private MailCharset mcSet ; 076 077 /** 078 * メールサーバーとデフォルト文字エンコーディングを指定して、オブジェクトを構築します。 079 * 080 * デフォルト文字エンコーディングは、ISO-2022-JP です。 081 * 082 * @param host メールサーバー 083 * @throws IllegalArgumentException 引数が null の場合。 084 */ 085 public MailTX( final String host ) { 086 this( host,"ISO-2022-JP" ); 087 } 088 089 /** 090 * メールサーバーとデフォルト文字エンコーディングを指定して、オブジェクトを構築します。 091 * 092 * 文字エンコーディングには、Windwos-31J , MS932 , UTF-8 , ISO-2022-JP を指定できます。 093 * 094 * @og.rev 5.4.3.2 (2012/01/06) 認証対応のため 095 * @og.rev 5.8.1.1 (2014/11/14) 認証ポート追加 096 * @og.rev 6.3.8.0 (2015/09/11) SSL接続するかどうかを指定するパラメータを追加します。 097 * 098 * @param host メールサーバー 099 * @param charset 文字エンコーディング 100 * @throws IllegalArgumentException 引数が null の場合。 101 */ 102 public MailTX( final String host , final String charset ) { 103// this( host,charset,null,null,null,null,null,false ); 104 this( host,charset,null,null,null,null,null,false,false ); // TSL,SSL 105 } 106 107 /** 108 * メールサーバーと文字エンコーディングを指定して、オブジェクトを構築します。 109 * 認証を行う場合は認証方法を指定します。 110 * 111 * 文字エンコーディングには、Windwos-31J , MS932 , ISO-2022-JP を指定できます。 112 * 113 * @og.rev 5.1.9.0 (2010/08/01) mail.smtp.localhostの設定追加 114 * @og.rev 5.4.3.2 (2012/01/06) 認証対応(POP Before SMTP)。引数3つ追加(将来的にはAuthentication対応?) 115 * @og.rev 5.8.1.1 (2014/11/14) 認証ポート追加 116 * @og.rev 6.2.4.1 (2015/05/22) SMTP_AUTH 対応 117 * @og.rev 6.3.8.0 (2015/09/11) SSL接続するかどうかを指定するパラメータを追加します。 118 * @og.rev 5.9.29.2 (2018/02/16) STARTTLS対応(キーワードをVer5 にあわせます) 119 * @og.rev 5.10.20.1 (2020/03/03) 添付ファイル名文字化け対策 120 * 121 * @param host メールサーバー 122 * @param charset 文字エンコーディング 123 * @param smtpPort SMTPポート 124 * @param authType 認証方法(POP_BEFORE_SMTP , SMTP_AUTH) 125 * @param authPort 認証ポート 126 * @param authUser 認証ユーザ 127 * @param authPass 認証パスワード 128 * @param useStarttls 暗号化通信設定(STARTTLS) 5.9.29.2 129 * @param useSSL SSL接続するかどうか 130 * @throws IllegalArgumentException 引数が null の場合。 131 */ 132 public MailTX( final String host , final String charset, final String smtpPort 133// ,final String authType, final String authPort, final String authUser, final String authPass, final boolean useSSL) { 134 ,final String authType, final String authPort, final String authUser, final String authPass, final boolean useStarttls, final boolean useSSL ) { 135 if( host == null ) { 136 final String errMsg = "host に null はセット出来ません。"; 137 throw new IllegalArgumentException( errMsg ); 138 } 139 140 if( charset == null ) { 141 final String errMsg = "charset に null はセット出来ません。"; 142 throw new IllegalArgumentException( errMsg ); 143 } 144 145 this.charset = charset; 146 147 mcSet = MailCharsetFactory.newInstance( charset ); 148 149 // 5.10.20.1 (2020/03/03) 添付ファイル名文字化け対策(暫定) 150 System.setProperty("mail.mime.splitlongparameters", "false"); 151 System.setProperty("mail.mime.encodeparameters", "false" ); 152 153 final Properties prop = new Properties(); 154 prop.setProperty("mail.mime.charset" , charset ); 155 prop.setProperty("mail.mime.decodetext.strict" , "false" ); 156 prop.setProperty("mail.mime.address.strict" , "false" ); 157 prop.setProperty("mail.smtp.host" , host ); 158 // 5.1.9.0 (2010/08/01) 設定追加 159 prop.setProperty("mail.smtp.localhost" , host ); 160 prop.setProperty("mail.host" , host ); // MEssage-ID の設定に利用 161 162 // 5.4.3.2 ポート追加 163 if( smtpPort != null && smtpPort.length() > 0 ){ 164 prop.setProperty("mail.smtp.port" , smtpPort); // MEssage-ID の設定に利用 165 } 166 167 // 6.2.4.1 (2015/05/22) SMTP_AUTH 対応 168 Authenticator myAuth = null; 169 if( AUTH_SMTPA.equals( authType ) ) { 170 prop.setProperty("mail.smtp.auth" , "true" ); 171 prop.setProperty("mail.transport.protocol" , "smtps" ); // 6.3.8.0 (2015/09/11) 172 // 6.3.9.0 (2015/11/06) 名前付き static 内部クラスにリファクタリング(findbugs) 173 // myAuth = new MyAuthenticator( authUser,authPass ); 174 myAuth = new Authenticator() { // 5.8.7.1 (2015/05/22) SMTP認証用クラス 175 /** 176 * パスワード認証が必要な時には呼ばれる。 177 * 178 * @return PasswordAuthenticationオブジェクト 179 */ 180 @Override 181 protected PasswordAuthentication getPasswordAuthentication() { 182 return new PasswordAuthentication( authUser,authPass ); 183 } 184 }; 185 } 186 187 // 6.3.8.0 (2015/09/11) SSL接続するかどうかを指定するパラメータを追加します。 188 // 5.9.29.2 (2018/02/16) STARTTLS対応 (キーワードをVer5 にあわせます) 189// if( useSSL ) { 190 if ( useStarttls || useSSL ) { 191 prop.setProperty("mail.smtp.starttls.enable" , "true" ); // 6.3.8.0 (2015/09/11) 192 prop.setProperty("mail.smtp.starttls.required" , "true" ); // 6.3.8.0 (2015/09/11) 193 // prop.setProperty("mail.smtp.socketFactory.class" , "javax.net.ssl.SSLSocketFactory" ); 194 // prop.setProperty("mail.smtp.socketFactory.fallback" , "false" ); 195 // prop.setProperty("mail.smtp.socketFactory.port" , String.valueOf( smtpPort ) ); // 587 196 // prop.setProperty("mail.transport.protocol" , "smtps" ); // 6.3.8.0 (2015/09/11) 197 } 198 199 // 6.9.1.0 (2018/02/26) STL/SSL 両対応 200 if ( useSSL ) { 201 prop.setProperty("mail.smtp.socketFactory.class" , "javax.net.ssl.SSLSocketFactory" ); 202 prop.setProperty("mail.smtp.socketFactory.fallback" , "false" ); 203 prop.setProperty("mail.smtp.socketFactory.port" , String.valueOf( smtpPort ) ); // 465 204 prop.setProperty("mail.transport.protocol" , "smtps" ); // 6.3.8.0 (2015/09/11) 205 } 206 207 session = Session.getInstance( prop, myAuth ); // 6.2.4.1 (2015/05/22) SMTP_AUTH 対応 208 209 // POP before SMTP認証処理 5.4.3.2 210 if( AUTH_PBS.equals( authType ) ){ 211 try{ 212 // 5.8.1.1 (2014/11/14) 認証ポート追加 213 final int aPort = authPort == null || authPort.isEmpty() || authPass == null || authPass.isEmpty() ? -1 : Integer.parseInt(authPort) ; 214 final Store store = session.getStore("pop3"); 215 store.connect( host,aPort,authUser,authPass ); // 5.8.1.1 (2014/11/14) 認証ポート追加 216 store.close(); 217 } 218 catch( final MessagingException ex ) { 219 final String errMsg = "POP3 Auth Exception: "+ host + "/" + authUser; 220 throw new OgRuntimeException( errMsg,ex ); 221 } 222 } 223 224 mimeMsg = new MimeMessage( session ); 225 } 226 227 /** 228 * メールを送信します。 229 * 230 */ 231 public void sendmail() { 232 try { 233 mimeMsg.setSentDate( new Date() ); 234 235 if( filename == null || filename.length == 0 ) { 236 mcSet.setTextContent( mimeMsg,message ); 237 } 238 else { 239 mmPart = new MimeMultipart(); 240 mimeMsg.setContent( mmPart ); 241 // テキスト本体の登録 242 addMmpText( message ); 243 244 // 添付ファイルの登録 245 for( int i=0; i<filename.length; i++ ) { 246 addMmpFile( filename[i] ); 247 } 248 } 249 250 mimeMsg.setHeader("X-Mailer", MAILER ); 251 mimeMsg.setHeader("Content-Transfer-Encoding", mcSet.getBit() ); 252 Transport.send( mimeMsg ); 253 } 254 catch( final AddressException ex ) { 255 final String errMsg = "Address Exception: " + ex.getMessage() ; 256 throw new OgRuntimeException( errMsg,ex ); 257 } 258 catch( final MessagingException mex ) { 259 final String errMsg = "MessagingException: " + mex.getMessage() ; 260 throw new OgRuntimeException( errMsg,mex ); 261 } 262 } 263 264 /** 265 * MimeMessageをリセットします。 266 * 267 * sendmail() でメールを送信後、セッションを閉じずに別のメールを送信する場合、 268 * リセットしてから、各種パラメータを再設定してください。 269 * その場合は、すべてのパラメータが初期化されていますので、もう一度 270 * 設定しなおす必要があります。 271 * 272 */ 273 public void reset() { 274 mimeMsg = new MimeMessage(session); 275 } 276 277 /** 278 * 送信元(FROM)アドレスをセットします。 279 * 280 * @param from 送信元(FROM)アドレス 281 */ 282 public void setFrom( final String from ) { 283 try { 284 if( from != null ) { 285 mimeMsg.setFrom( getAddress( from ) ); 286 } 287 } catch( final AddressException ex ) { 288 final String errMsg = "Address Exception: " + ex.getMessage() ; 289 throw new OgRuntimeException( errMsg,ex ); 290 } catch( final MessagingException mex ) { 291 final String errMsg = "MessagingException: " + mex.getMessage() ; 292 throw new OgRuntimeException( errMsg,mex ); 293 } 294 } 295 296 /** 297 * 送信先(TO)アドレス配列をセットします。 298 * 299 * @param to 送信先(TO)アドレス配列(可変長引数) 300 */ 301 public void setTo( final String... to ) { 302 try { 303 if( to != null && to.length > 0 ) { // 6.1.1.0 (2015/01/17) 可変長引数でもnullは来る。 304 mimeMsg.setRecipients( Message.RecipientType.TO, getAddress( to ) ); 305 } 306 } catch( final AddressException ex ) { 307 final String errMsg = "Address Exception: " + ex.getMessage() ; 308 throw new OgRuntimeException( errMsg,ex ); 309 } catch( final MessagingException mex ) { 310 final String errMsg = "MessagingException: " + mex.getMessage() ; 311 throw new OgRuntimeException( errMsg,mex ); 312 } 313 } 314 315 /** 316 * 送信先(CC)アドレス配列をセットします。 317 * 318 * @param cc 送信先(CC)アドレス配列(可変長引数) 319 */ 320 public void setCc( final String... cc ) { 321 try { 322 if( cc != null && cc.length > 0 ) { // 6.1.1.0 (2015/01/17) 可変長引数でもnullは来る。 323 mimeMsg.setRecipients( Message.RecipientType.CC, getAddress( cc ) ); 324 } 325 } catch( final AddressException ex ) { 326 final String errMsg = "Address Exception: " + ex.getMessage() ; 327 throw new OgRuntimeException( errMsg,ex ); 328 } catch( final MessagingException mex ) { 329 final String errMsg = "MessagingException: " + mex.getMessage() ; 330 throw new OgRuntimeException( errMsg,mex ); 331 } 332 } 333 334 /** 335 * 送信先(BCC)アドレス配列をセットします。 336 * 337 * @param bcc 送信先(BCC)アドレス配列(可変長引数) 338 */ 339 public void setBcc( final String... bcc ) { 340 try { 341 if( bcc != null && bcc.length > 0 ) { // 6.1.1.0 (2015/01/17) 可変長引数でもnullは来る。 342 mimeMsg.setRecipients( Message.RecipientType.BCC, getAddress( bcc ) ); 343 } 344 } catch( final AddressException ex ) { 345 final String errMsg = "Address Exception: " + ex.getMessage() ; 346 throw new OgRuntimeException( errMsg,ex ); 347 } catch( final MessagingException mex ) { 348 final String errMsg = "MessagingException: " + mex.getMessage() ; 349 throw new OgRuntimeException( errMsg,mex ); 350 } 351 } 352 353 /** 354 * 送信先(TO)アドレス配列をクリアします。 355 * @og.rev 4.3.6.0 (2009/04/01) 新規追加 356 * 357 */ 358 public void clearTo() { 359 try { 360 mimeMsg.setRecipients( Message.RecipientType.TO, (InternetAddress[])null ); 361 } catch( final IllegalWriteException ex ) { 362 final String errMsg = "Address Exception: " + ex.getMessage() ; 363 throw new OgRuntimeException( errMsg,ex ); 364 } catch( final IllegalStateException ex ) { 365 final String errMsg = "Address Exception: " + ex.getMessage() ; 366 throw new OgRuntimeException( errMsg,ex ); 367 } catch( final MessagingException mex ) { 368 final String errMsg = "MessagingException: " + mex.getMessage() ; 369 throw new OgRuntimeException( errMsg,mex ); 370 } 371 } 372 373 /** 374 * 送信先(CC)アドレス配列をクリアします。 375 * 376 * @og.rev 4.3.6.0 (2009/04/01) 新規追加 377 */ 378 public void clearCc() { 379 try { 380 mimeMsg.setRecipients( Message.RecipientType.CC, (InternetAddress[])null ); 381 } catch( final IllegalWriteException ex ) { 382 final String errMsg = "Address Exception: " + ex.getMessage() ; 383 throw new OgRuntimeException( errMsg,ex ); 384 } catch( final IllegalStateException ex ) { 385 final String errMsg = "Address Exception: " + ex.getMessage() ; 386 throw new OgRuntimeException( errMsg,ex ); 387 } catch( final MessagingException mex ) { 388 final String errMsg = "MessagingException: " + mex.getMessage() ; 389 throw new OgRuntimeException( errMsg,mex ); 390 } 391 } 392 393 /** 394 * 送信先(BCC)アドレス配列をクリアします。 395 * @og.rev 4.3.6.0 (2009/04/01) 新規追加 396 * 397 */ 398 public void clearBcc() { 399 try { 400 mimeMsg.setRecipients( Message.RecipientType.BCC, (InternetAddress[])null ); 401 } catch( final IllegalWriteException ex ) { 402 final String errMsg = "Address Exception: " + ex.getMessage() ; 403 throw new OgRuntimeException( errMsg,ex ); 404 } catch( final IllegalStateException ex ) { 405 final String errMsg = "Address Exception: " + ex.getMessage() ; 406 throw new OgRuntimeException( errMsg,ex ); 407 } catch( final MessagingException mex ) { 408 final String errMsg = "MessagingException: " + mex.getMessage() ; 409 throw new OgRuntimeException( errMsg,mex ); 410 } 411 } 412 413 /** 414 * 返信元(replyTo)アドレス配列をセットします。 415 * 416 * @param replyTo 返信元(replyTo)アドレス配列(可変長引数) 417 */ 418 public void setReplyTo( final String... replyTo ) { 419 try { 420 if( replyTo != null && replyTo.length > 0 ) { // 6.1.1.0 (2015/01/17) 可変長引数でもnullは来る。 421 mimeMsg.setReplyTo( getAddress( replyTo ) ); 422 } 423 } catch( final AddressException ex ) { 424 final String errMsg = "Address Exception: " + ex.getMessage() ; 425 throw new OgRuntimeException( errMsg,ex ); 426 } catch( final MessagingException mex ) { 427 final String errMsg = "MessagingException: " + mex.getMessage() ; 428 throw new OgRuntimeException( errMsg,mex ); 429 } 430 } 431 432 /** 433 * タイトルをセットします。 434 * 435 * @param subject タイトル 436 */ 437 public void setSubject( final String subject ) { 438 // Servlet からの読み込みは、iso8859_1 でエンコードされた文字が 439 // セットされるので、ユニコードに変更しておかないと文字化けする。 440 // JRun 3.0 では、問題なかったが、tomcat3.1 では問題がある。 441 try { 442 if( subject != null ) { 443 mimeMsg.setSubject( mcSet.encodeWord( subject ) ); 444 } 445 } catch( final AddressException ex ) { 446 final String errMsg = "Address Exception: " + ex.getMessage() ; 447 throw new OgRuntimeException( errMsg,ex ); 448 } catch( final MessagingException mex ) { 449 final String errMsg = "MessagingException: " + mex.getMessage() ; 450 throw new OgRuntimeException( errMsg,mex ); 451 } 452 } 453 454 /** 455 * 添付ファイル名配列をセットします。 456 * 457 * @param fname 添付ファイル名配列(可変長引数) 458 */ 459 public void setFilename( final String... fname ) { 460 if( fname != null && fname.length > 0 ) { // 6.1.1.0 (2015/01/17) 可変長引数でもnullは来る。 461 final int size = fname.length; 462 filename = new String[size]; 463 System.arraycopy( fname,0,filename,0,size ); 464 } 465 } 466 467 /** 468 * メッセージ(本文)をセットします。 469 * 470 * @param msg メッセージ(本文) 471 */ 472 public void setMessage( final String msg ) { 473 // なぜか、メッセージの最後は、<CR><LF>をセットしておく。 474 475 if( msg == null ) { message = CR; } 476 else { message = msg + CR; } 477 } 478 479 /** 480 * デバッグ情報の表示を行うかどうかをセットします。 481 * 482 * @param debug 表示有無[true/false] 483 */ 484 public void setDebug( final boolean debug ) { 485 session.setDebug( debug ); 486 } 487 488 /** 489 * 指定されたファイルをマルチパートに追加します。 490 * 491 * @param fileStr マルチパートするファイル名 492 */ 493 private void addMmpFile( final String fileStr ) { 494 try { 495 final MimeBodyPart mbp = new MimeBodyPart(); 496 final FileDataSource fds = new FileDataSource(fileStr); 497 mbp.setDataHandler(new DataHandler(fds)); 498 mbp.setFileName(MimeUtility.encodeText(fds.getName(), charset, "B")); 499 mbp.setHeader("Content-Transfer-Encoding", "base64"); 500 mmPart.addBodyPart(mbp); 501 } 502 catch( final UnsupportedEncodingException ex ) { 503 final String errMsg = "Multipart UnsupportedEncodingException: " + ex.getMessage() ; 504 throw new OgRuntimeException( errMsg,ex ); 505 } 506 catch( final MessagingException mex ) { 507 final String errMsg = "MessagingException: " + mex.getMessage() ; 508 throw new OgRuntimeException( errMsg,mex ); 509 } 510 } 511 512 /** 513 * 指定された文字列をマルチパートに追加します。 514 * 515 * @param textStr マルチパートする文字列 516 */ 517 private void addMmpText( final String textStr ) { 518 try { 519 final MimeBodyPart mbp = new MimeBodyPart(); 520 mbp.setText(textStr, charset); 521 mbp.setHeader("Content-Transfer-Encoding", mcSet.getBit()); 522 mmPart.addBodyPart(mbp, 0); 523 } 524 catch( final MessagingException mex ) { 525 final String errMsg = "MessagingException: " + mex.getMessage() ; 526 throw new OgRuntimeException( errMsg,mex ); 527 } 528 } 529 530 /** 531 * 文字エンコードを考慮した InternetAddress を作成します。 532 * 533 * @param adrs オリジナルのアドレス文字列 534 * 535 * @return 文字エンコードを考慮した InternetAddress 536 */ 537 private InternetAddress getAddress( final String adrs ) { 538 final InternetAddress rtnAdrs ; 539 final int sep = adrs.indexOf( '<' ); 540 if( sep >= 0 ) { 541 final String address = adrs.substring( sep+1,adrs.indexOf( '>' ) ).trim(); 542 final String personal = adrs.substring( 0,sep ).trim(); 543 544 rtnAdrs = mcSet.getAddress( address,personal ); 545 } 546 else { 547 try { 548 rtnAdrs = new InternetAddress( adrs ); 549 } 550 catch( final AddressException ex ) { 551 final String errMsg = "指定のアドレスをセットできません。" 552 + "adrs=" + adrs + " , msg=" + ex.getMessage() ; 553 throw new OgRuntimeException( errMsg,ex ); 554 } 555 } 556 557 return rtnAdrs ; 558 } 559 560 /** 561 * 文字エンコードを考慮した InternetAddress を作成します。 562 * これは、アドレス文字配列から、InternetAddress 配列を作成する、 563 * コンビニエンスメソッドです。 564 * 処理そのものは、#getAddress( String ) をループしているだけです。 565 * 566 * @param adrs アドレス文字配列(可変長引数) 567 * 568 * @return 文字エンコード後のInternetAddress配列 569 * @see #getAddress( String ) 570 */ 571 private InternetAddress[] getAddress( final String... adrs ) { 572 InternetAddress[] rtnAdrs = new InternetAddress[adrs.length]; 573 for( int i=0; i<adrs.length; i++ ) { 574 rtnAdrs[i] = getAddress( adrs[i] ); 575 } 576 577 return rtnAdrs ; 578 } 579 580// /** 581// * javax.mail.Authenticator クラスの名前付き static 内部クラス 582// * 583// * SMTP認証用クラスとして使用します。6.2.4.1 (2015/05/22) 584// * 585// * 名前付き static 内部クラスにリファクタリングします(findbugs)。 586// * 587// * @og.rev 6.3.9.0 (2015/11/06) 新規追加 588// * @og.rev 6.3.9.1 (2015/11/27) 修飾子を、なし → private に変更。 589// * 590// * @return Authenticatorオブジェクト 591// * @see javax.mail.Authenticator 592// */ 593// private static final class MyAuthenticator extends Authenticator { 594// private final String authUser ; // 6.3.9.1 (2015/11/27) 修飾子を、なし → private に変更。 595// private final String authPass ; // 6.3.9.1 (2015/11/27) 修飾子を、なし → private に変更。 596// 597// /** 598// * ユーザ,パスワードを指定したコンストラクター。 599// * 600// * @og.rev 6.3.9.0 (2015/11/06) 新規追加 601// * @og.rev 6.4.1.1 (2016/01/16) PMD refactoring. It is a good practice to call super() in a constructor 602// * 603// * @param authUser 認証ユーザ 604// * @param authPass 認証パスワード 605// */ 606// public MyAuthenticator( final String authUser, final String authPass ) { 607// super(); 608// this.authUser = authUser; 609// this.authPass = authPass; 610// } 611// 612// /** 613// * パスワード認証が必要な時に呼ばれます。 614// * 615// * @og.rev 6.3.9.0 (2015/11/06) 新規追加 616// * 617// * @return PasswordAuthenticationオブジェクト 618// */ 619// @Override 620// protected PasswordAuthentication getPasswordAuthentication() { 621// return new PasswordAuthentication( authUser,authPass ); 622// } 623// } 624 625 /** 626 * コマンドから実行できる、テスト用の main メソッドです。 627 * 628 * Usage: java org.opengion.fukurou.mail.MailTX <from> <to> <host> [<file> ....] 629 * で、複数の添付ファイルを送付することができます。 630 * 631 * @og.rev 6.3.6.0 (2015/08/16) System.arraycopy が使える箇所は、置き換えます。 632 * 633 * @param args コマンド引数配列 634 */ 635 public static void main( final String[] args ) { 636 if( args.length < 3 ) { 637 LogWriter.log("Usage: java org.opengion.fukurou.mail.MailTX <from> <to> <host> [<file> ....]"); 638 return ; 639 } 640 641 final String host = args[2] ; 642 final String chset = "ISO-2022-JP" ; 643 644 final MailTX sender = new MailTX( host,chset ); 645 646 sender.setFrom( args[0] ); 647 final String[] to = { args[1] }; 648 sender.setTo( to ); 649 650 if( args.length > 3 ) { 651 final String[] filename = new String[args.length-3]; 652 // 6.3.6.0 (2015/08/16) System.arraycopy が使える箇所は、置き換えます。 653 System.arraycopy( args,3,filename,0,filename.length ); // 6.3.6.0 (2015/08/16) 654 sender.setFilename( filename ); 655 } 656 657 sender.setSubject( "メール送信テスト" ); 658 final String msg = "これはテストメールです。" + CR 659 + "うまく受信できましたか?" + CR; 660 sender.setMessage( msg ); 661 662 sender.sendmail(); 663 } 664}