2017-09-09 77 views
0

我創建了一個類來管理髮送郵件,我想通過屬性文件注入smtp配置。但我一直在我的領域屬性爲空。 這是我的代碼:@Inject屬性在Tomcat上返回null

public class EmailUtils { 
    @Inject 
    @PropertiesFromFile("smtp.properties") 
    Properties properties; 

    public void sendEmail(String destinator, String subject, String body) { 
     final String username = properties.getProperty("smtp.email"); 
     final String password = properties.getProperty("smtp.password"); 

     Session session = Session.getInstance(properties, 
      new javax.mail.Authenticator() { 
      protected PasswordAuthentication getPasswordAuthentication() { 
       return new PasswordAuthentication(username, password); 
      } 
      }); 

     try { 

      Message message = new MimeMessage(session); 
      message.setFrom(new InternetAddress(properties.getProperty("smtp.from"))); 
      message.setRecipients(Message.RecipientType.TO, 
       InternetAddress.parse(destinator)); 
      message.setSubject(subject); 
      message.setText(body); 

      Transport.send(message); 

      System.out.println("Done"); 

     } catch (MessagingException e) { 
      throw new RuntimeException(e); 
     } 
    } 
} 

public class PropertyReader { 

    @Produces 
    @PropertiesFromFile 
    public Properties provideServerProperties(InjectionPoint ip) { 
    //get filename from annotation 
    String filename = ip.getAnnotated().getAnnotation(PropertiesFromFile.class).value(); 
    return readProperties(filename); 
} 

    private Properties readProperties(String fileInClasspath) { 
     InputStream is = this.getClass().getClassLoader().getResourceAsStream(fileInClasspath); 

     try { 
      Properties properties = new Properties(); 
      properties.load(is); 
      return properties; 
     } catch (IOException e) { 
      System.err.println("Could not read properties from file " + fileInClasspath + " in classpath. " + e); 
     } catch (Exception e) { 
      System.err.println("Exception catched:"+ e.getMessage()); 
     } 

     return null; 
    } 
} 

@Qualifier 
@Target({METHOD, FIELD}) 
@Retention(RUNTIME) 
public @interface PropertiesFromFile { 
    @Nonbinding 
    String value() default "application.properties"; 
} 

我測試的代碼用一個簡單的主力,但它不工作。 我用tomcat測試了它,並且仍然在Properties對象上獲得了NPE。 我錯過了什麼? 請幫助:)

+0

您的兩個類都是託管的bean嗎?注入和生產者只能在受管理的環境中工作。 –

+0

嗨Dimpre,我應該註釋他們嗎?我讀過的教程沒有註釋。 – Khairy

+0

Tomcat與EE技術的正式發佈,TomEE,存在幾個版本。非常好,並且與'classic'Tomcat兼容 –

回答

3

請考慮這樣做的Java EE方式:

  1. 如果使用Tomcat然後確保你已經設置了一個CDI實現爲How to install and use CDI on Tomcat?Application servers and environments supported by Weld描述。

  2. 將JavaMail實施jar從應用程序的WEB-INF/lib移動到Tomcat lib目錄。

  3. 配置通過添加以下到它的config/Context.xml文件在Tomcat中的郵件會話:

    <Context> 
        ... 
        <Resource name="mail/Session" auth="Container" 
         type="javax.mail.Session" 
         mail.smtp.host="your mail host here" 
         mail.smtp.user="your user name here" 
         password="your password" 
         mail.from="[email protected]" /> 
        ... 
    </Context> 
    

    還有其他地方把這個配置,但是這是最簡單的解釋這裏。有關更多信息,請參閱Tomcat JNDI documentation

  4. 簡化代碼:

    @Resource(name="mail/Session") 
        private Session session; 
    
        public void sendEmail(String destinator, String subject, String body) { 
         try { 
    
          Message message = new MimeMessage(session); 
          message.setRecipients(Message.RecipientType.TO, 
            InternetAddress.parse(destinator)); 
          message.setSubject(subject); 
          message.setText(body); 
    
          Transport.send(message); 
    
          System.out.println("Done"); 
    
         } catch (MessagingException e) { 
          throw new RuntimeException(e); 
         } 
        } 
    

    您的服務器(Tomcat的在這種情況下)配置郵件會話和身份驗證後,你看。

類似的機制適用於設置JDBC DataSource對象FWIW。

+0

謝謝Steve,我使用maven3來管理依賴關係,還有另一種解決問題的方法嗎? – Khairy

+1

至少你需要讓CDI在Tomcat中工作。第1步爲您提供了指針。如果您使用Tomee,WildFly或Payara服務器,生活對您來說會更容易。然後您可以忽略第1步。 –

2

@Named@ApplicationScoped註釋您的PropertyReader類,以使CDI容器知道它,以便它可以被管理。在班級路徑中有空白beans.xml