2017-07-16 105 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块。