장면 설명:
사서함 구성을 저장할 때 사서함 구성 매개변수가 올바른지 자동으로 감지합니다. SMTP를 감지하면 시스템이 다음 예외를 보고합니다.
다음과 같이 코드 코드를 복사합니다 .
javax.mail.MessagingException: 501 "HELO" 명령에는 인수가 필요합니다.
com.sun.mail.smtp.SMTPTransport.issueCommand(SMTPTransport.java:1363)에서
com.sun.mail.smtp.SMTPTransport.helo(SMTPTransport.java:838)에서
com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:375)에서
javax.mail.Service.connect(Service.java:275)에서
그런데 Windows 서버로 변경해 보니 그런 문제는 없었습니다.Linux 서버에서만 재현이 가능하더군요.직감적으로 이 Linux 서버의 일부 구성에 문제가 있는 것 같았습니다.
문제 해결 단계
1. 동일한 운영 체제를 사용하는 Linux 서버를 찾아 이메일 구성을 확인한 후 Linux 운영 체제의 특수성 문제를 제거합니다.
2. Linux 서버에서 직접 텔넷을 이용하여 상대 메일 서버의 SMTP 포트에 접속합니다. 자, 서버의 네트워크 문제를 해결해 보세요.
3. HELO 명령어 설명 찾기
다음과 같이 코드 코드를 복사합니다 .
헬로
-- 메일 서버와의 대화를 시작합니다. 이 명령을 사용하면 메일 서버가 사용자를 알 수 있도록 도메인 이름을 지정할 수 있습니다(예: cf.ac.uk).
메시지 소스가 어디에 있는지 SMTP 서버에 알리려면 HELO 명령 뒤에 개시자의 호스트 이름이 와야 하는 것으로 나타났습니다.
"501 명령 "HELO"에는 인수가 필요합니다"라는 예외 메시지를 보면 프로그램이 SMTP SERVER와 상호 작용하는 동안 원본 호스트 도메인 이름을 전달하지 않았음이 분명합니다.
4. JAVA MAIL 소스코드 보기
다음과 같이 HELO 명령어를 찾습니다.
다음과 같이 코드 코드를 복사합니다 .
/**
* <code>HELO</code> 명령을 실행하세요.
*
* @param 도메인
* 우리 도메인
*
* @JavaMail 1.4.1부터
*/
protected void helo(String domain)에서 MessagingException이 발생합니다.
if (도메인 != null)
issueCommand("HELO " + 도메인, 250);
또 다른
issueCommand("HELO", 250);
}
helo 메소드가 호출되는 위치를 찾고 도메인이 어떻게 전달되는지 확인하세요.
다음과 같이 코드 코드를 복사합니다 .
if (useEhlo)
성공 = ehlo(getLocalHost());
만약 (!성공)
헬로(getLocalHost());
당연히 다음과 같이 정의된 getLocalHost() 메서드를 찾으세요.
다음과 같이 코드 코드를 복사합니다 .
/**
* EHLO 및 HELO 명령에 사용할 로컬 호스트의 이름을 가져옵니다.
* mail.smtp.localhost 속성은 mail.smtp.localaddress를 재정의합니다.
* InetAddress가 우리에게 알려주는 내용을 무시합니다.
*/
공개 동기화 문자열 getLocalHost() {
노력하다 {
// 호스트 이름을 가져와 나중에 사용할 수 있도록 캐시합니다.
if (localHostName == null || localHostName.length() <= 0)
localHostName = session.getProperty("mail." + 이름 + ".localhost");
if (localHostName == null || localHostName.length() <= 0)
localHostName = session.getProperty("mail." + name+ ".localaddress");
if (localHostName == null || localHostName.length() <= 0) {
InetAddress localHost = InetAddress.getLocalHost();
localHostName = localHost.getHostName();
// 이름을 알 수 없으면 로컬 주소 리터럴을 사용합니다.
if (localHostName == null)
// XXX - IPv6에는 올바르지 않음
localHostName = "[" + localHost.getHostAddress() + "]";
}
} 잡기(UnknownHostException uhex) {
}
localHostName을 반환합니다.
}
현재 연결의 세션 속성이나 현재 서버의 호스트 구성에서 호스트 이름을 얻을 수 있음을 알 수 있습니다. 그러나 우리 프로그램은 세션에서 호스트 이름을 설정하지 않으므로 이유는 호스트 파일에 있어야 합니다. Linux 서버의 수정으로 인해 JAVA 프로그램이 localhostName을 자동으로 얻을 수 없게 되었습니다.
5. /etc/hosts 파일을 확인합니다. 상황은 다음과 같습니다.
다음과 같이 코드 코드를 복사합니다 .
127.0.0.1 localhost.localdomain 로컬호스트
::1 localhost6.localdomain6 localhost6
다음과 같이 호스트 파일을 수정하기만 하면 됩니다.
다음과 같이 코드 코드를 복사합니다 .
127.0.0.1 로컬호스트
::1 localhost6.localdomain6 localhost6
6. 다시 테스트하면 문제가 해결됩니다.
실제로 이 상황은 프로그래밍, 즉 현재 서버의 호스트 이름 속성을 세션 연결에 추가하여 피할 수도 있습니다.
다음과 같이 코드 코드를 복사합니다 .
공개 정적 무효 메인(String[] args) {
노력하다 {
int smtpport = 25;
문자열 smtpserver = "219.147.xxx.xxx";
속성 prop = System.getProperties();
prop.put("mail.smtp.auth", "true");
prop.put("mail.smtp.localhost", "myMailServer");
세션 mailSession = Session.getInstance(prop, null);
전송 전송 = mailSession.getTransport("smtp");
Transport.connect(smtpserver,smtpport, "사용자 이름", "비밀번호");
System.out.println("연결 확인");
운송.닫기();
} catch (AuthenticationFailedException ko) {
en.printStackTrace();
System.out.println("SMTP 서버 연결에 실패했습니다. 입력한 정보가 맞는지 확인해주세요.");
} 잡기(NoSuchProviderException e) {
e.printStackTrace();
System.out.println("SMTP 서버 연결에 실패했습니다. 입력한 정보가 맞는지 확인해주세요.");
} 잡기(MessagingException e) {
e.printStackTrace();
System.out.println("SMTP 서버 연결에 실패했습니다. 입력한 정보가 맞는지 확인해주세요.");
}
}