2017-07-16 44 views
0

好天好,我有問題,而新用戶註冊後,把從MDB onMessage方法的電子郵件通知通過EJB消息驅動Bean發送的JavaMail

我使用的是隊列

的問題是,該消息監聽保持在隊列重新發送每封郵件,而這個結果的電子郵件地址收到不同的電子郵件通知(無論是有意和無意,新與舊,等)每當一個新的用戶註冊。

下面是客戶端代碼;

public String createAccount(String firstName, String middleName, String lastName, String username, 
     String password, String confirmPassword, String email, String confirmEmail, String Organization, 
     String address, String state, String country, String gRecaptchaResponse) { 

    boolean verified = false; 
    try { 
     verified = VerifyRecaptcha.verify(gRecaptchaResponse); 
    } catch (IOException ex) { 
     Logger.getLogger(AdminFacade.class.getName()).log(Level.SEVERE, "Captcha palava_" + ex.getMessage(), ex); 
    } 

    if (verified) { 
     Query q = em.createNamedQuery("Admin.findByUsername"); 
     q.setParameter("username", username); 

     if (q.getResultList().size() > 0) { 
      return "Username <" + username + "> already exists. Pls try a different username"; 
     } 

     if (!password.equals(confirmPassword)) { 
      return "Password Mis-match"; 
     } 

     if (!email.equals(confirmEmail)) { 
      return "E-mail Mis-match"; 
     } 

     try { 
      Admin admin = new Admin(); 

      admin.setEmail(email); 
      admin.setFirstName(firstName); 
      admin.setMiddleName(middleName); 
      admin.setLastName(lastName); 
      admin.setOrganization(Organization); 
      admin.setEmail(email); 
      admin.setAddress(address); 
      admin.setState(state); 
      admin.setCountry(country); 
      admin.setExamSessionId(UniqueValueGenerator.generate()); 
      admin.setResultDisplay(true); 

      MessageDigest md = MessageDigest.getInstance("MD5"); 
      md.update(password.getBytes()); 
      byte byteData[] = md.digest(); 

      StringBuilder sb = new StringBuilder(); 

      for (int i = 0; i < byteData.length; i++) { 
       sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1)); 
      } 

      admin.setPassword(sb.toString()); 

      admin.setUsername(username); 

      em.persist(admin); 

      //set the password back to the literal password so that email sent will show the literal password 
      admin.setPassword(password); 

      QueueConnection connection = null; 
      Session jmssession = null; 
      MessageProducer messageProducer = null; 
      try { 

       connection = connectionFactory.createQueueConnection(); 
       jmssession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); 
       messageProducer = jmssession.createProducer(queue); 

       ObjectMessage message = jmssession.createObjectMessage(); 

       message.setObject(admin); 
       System.out.println("Sending message attempt: "); 
       System.out.println(messageProducer.getDestination().toString()); 
       System.out.println(messageProducer.getDeliveryMode()); 
       System.out.println(messageProducer.getPriority()); 
       messageProducer.send(message); 

      } catch (JMSException ex) { 
       Logger.getLogger(AdminFacade.class.getName()).log(Level.SEVERE, ex.getMessage(), ex); 

       return "Account was successfully created but it looks like we were unable to notify your email. Please check your " 
         + "mail NOW for notification and if you can't find it, send us a mail at [email protected]"; 
      } finally { 
       try { 
        connection.close(); 
        jmssession.close(); 
        messageProducer.close(); 
        System.out.println("All Closed"); 
       } catch (JMSException ex) { 
        Logger.getLogger(AdminFacade.class.getName()).log(Level.SEVERE, ex.getMessage(), ex); 
       } 
      } 

      return "Success"; 

     } catch (NoSuchAlgorithmException ex) { 
      Logger.getLogger(AdminFacade.class.getName()).log(Level.SEVERE, ex.getMessage(), ex); 
      return "Something went wrong, please make sure all fields are filled correctly"; 
     } 
    } else { 
     return "You missed the Recaptcha, please retry"; 
    } 
} 

這裏是MDB代碼;

package utility; 

import entity.Admin; 
import entity.Housekeeping; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.annotation.Resource; 
import javax.ejb.ActivationConfigProperty; 
import javax.ejb.EJB; 
import javax.ejb.MessageDriven; 
import javax.ejb.MessageDrivenContext; 
import javax.jms.JMSException; 
import javax.jms.Message; 
import javax.jms.TextMessage; 
import javax.jms.MessageListener; 
import javax.jms.ObjectMessage; 
import javax.mail.MessagingException; 
import javax.persistence.EntityManager; 
import javax.persistence.PersistenceContext; 
import javax.persistence.Query; 
import session.AdminFacade; 
import session.HousekeepingFacade; 


@MessageDriven(mappedName = "jms/notificationMailer", activationConfig = { 
// @ActivationConfigProperty(propertyName = "destinationLookup",  propertyValue = "jms/notificationMailer") 
     @ActivationConfigProperty(propertyName = "acknowledgeMode",  propertyValue = "Auto-acknowledge") 
, 
     @ActivationConfigProperty(propertyName = "destinationType",  propertyValue = "javax.jms.Queue") 
}) 
public class NotificationMailer implements MessageListener { 

@Resource 
private MessageDrivenContext mdc; 

@EJB 
HousekeepingFacade housekeepingFacade; 
@PersistenceContext(unitName = "PU") 
private EntityManager em; 

public NotificationMailer() { 
} 

@Override 
public void onMessage(Message inMessage) { 
    TextMessage msg = null; 
    ObjectMessage objMsg = null; 

    try { 
     if (inMessage instanceof TextMessage) { 
      msg = (TextMessage) inMessage; 
      System.out.println("MESSAGE BEAN: Message received: " 
        + msg.getText()); 
     }else if (inMessage instanceof ObjectMessage){ 
      objMsg = (ObjectMessage) inMessage; 
      Admin admin = (Admin) objMsg.getObject(); 

       System.out.println(admin.getEmail()); 
      Query q2 = em.createNamedQuery("Admin.findByUsername"); 
      q2.setParameter("username", admin.getUsername()); 

      Admin u = (Admin) q2.getSingleResult(); 

      try { 
       String recipient = admin.getEmail(); 
       String subject = "Account Creation Confirmation"; 
       String content = "my content"; 

       Housekeeping housekeeping = housekeepingFacade.findAll().get(0); 
       EmailUtility.sendEmail(EmailUtility.HOST, EmailUtility.PORT, EmailUtility.USERNAME, housekeeping.getNoReplyPw(), recipient, subject, content, true); 
       EmailUtility.sendEmail(EmailUtility.HOST, EmailUtility.PORT, EmailUtility.USERNAME, housekeeping.getNoReplyPw(), "[email protected]", "New Admin Sign-up", "A new admin with account name: " + u.getUsername() + " and email " + u.getEmail() + " just signed up", false); 
       System.out.println("Done sending"); 
      } catch (MessagingException ex) {      
       String errMsg = "Account was successfully created but it looks like we were unable to notify your email. Please check your " 
         + "mail NOW for notification and if you can't find it, send us a mail at [email protected]"; 
       Logger.getLogger(AdminFacade.class.getName()).log(Level.SEVERE, ex.getMessage()+"___"+errMsg, ex); 
      } 

     }else { 
      System.out.println("Message of wrong type: " 
        + inMessage.getClass().getName()); 
     } 
    } catch (JMSException e) { 
     e.printStackTrace(); 
     mdc.setRollbackOnly(); 
    } catch (Throwable te) { 
     te.printStackTrace(); 
    } 

} 

}

+0

我注意到這個問題只發生在我打電話給EmailUtility.sendEmail()方法;當我註釋掉這個調用時,onMessage監聽器方法表現得很好,只是它不發送通知郵件。 NB:EmaUtility類很好。除了在MDB中調用時,它在我的應用程序中的其他任何實例中都能正常工作 –

+0

您沒有得到任何異常?它打印「完成發送」一次? EmailUtility究竟做了什麼,[JavaMail調試輸出](https://javaee.github.io/javamail/FAQ#debug)顯示了什麼? –

+0

請參閱下面的答案。非常感謝。 –

回答

0

@BillShannon

感謝您的熱心幫助,我能幾個小時後,來解決問題。我不得不打開我的圖書館,拿起一些關於EJB的平裝書,這確實很有幫助。我注意到我的應用程序的問題是所謂的「中毒消息」。

中毒消息是一種消息,因爲消息使用者拒絕確認收到消息(這不是我的情況),或者在編寫NotificationMailer類的onMessage偵聽器方法時採用的邏輯不是GlassFish JMS MOM可以接受(這是我的情況)。調用「很可能」拋出系統異常(如MessageException)的方法(例如EmailUtility.sendMail())將導致中毒消息。

我的解決辦法是:

  1. 返修的SendMail的邏輯(在EmailUtility類)的方法來處理的,而不是MessageException投擲它的。

  2. 重寫NotificationMailer類的onMessage()偵聽器方法的邏輯,以調用EmailUtility.sendMail()而不涉及try-catch塊。