2013-11-20 84 views
1

我使用Velocity和Java郵件發件人,但我得到一個NullPointerException,我不知道爲什麼。我嘗試了很多,但無法解決問題,說實話,我不知道問題依賴於什麼。速度電子郵件不工作

以下是我使用的示例代碼。 感謝您的幫助。

 
SEVERE: Servlet.service() for servlet [mvc-dispatcher] in context with path [/guard_weblayer] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause 
java.lang.NullPointerException 
    at se.guards.mail.VelocityEmailService.sendLostPasswordEmail(VelocityEmailService.java:49) 
    at se.guards.lostpassword.LostPasswordController.processSubmit(LostPasswordController.java:71) 

public interface VelocityMailRepository 
    { 
public void sendLostPasswordEmail(final User user, final String action); 
    } 


    public class VelocityEmailService implements VelocityMailRepository 
    { 
private static final Logger logger= LoggerFactory.getLogger(VelocityEmailService.class); 

@Autowired 
private VelocityEngine velocity; 

@Autowired 
private JavaMailSenderImpl javaMailSenderImpl; 

@Autowired 
private JavaMailSender sender; 

public void sendLostPasswordEmail(final User user, final String action) 
{ 
    logger.debug("Sending lost password email to: {}", user.getUsername()); 
    MimeMessagePreparator preparator = new MimeMessagePreparator() { 
     public void prepare(MimeMessage mimeMessage) throws Exception { 
      MimeMessageHelper message = new MimeMessageHelper(mimeMessage); 
      message.setTo(user.getEmail()); 
      message.setFrom("[email protected]"); 
      message.setSubject("Your Password"); 
      Map<String, Object> model = new HashMap<String, Object>(); 
      model.put("user", user); 
      model.put("url", action); 
      String text = mergeTemplateIntoString(velocity, "email/lost-password.vm","password", model); 
      message.setText(text, true); 
     } 
    }; 
    this.sender.send(preparator); 

}  

public class LostPasswordFormValidator implements Validator { 

    private static final Logger logger = LoggerFactory.getLogger(LostPasswordFormValidator.class); 

    public boolean supports(Class clazz) { 
     return LostPasswordForm.class.equals(clazz); 
    } 

    public void validate(Object obj, Errors errors) { 
     logger.debug("Validating lost password form."); 
     LostPasswordForm form = (LostPasswordForm) obj; 
     // Insure that a value with specified. 
     rejectIfEmptyOrWhitespace(errors, "username", "error.username.empty"); 
     // Insure the inputs don't contain any illegal characters. 
     if (!isAlphanumeric(form.getUsername())) 
      errors.rejectValue("username", "error.username.illegal.chars"); 
     if (isNotBlank(form.getUsername()) && form.getUsername().length() < 4) 
      errors.rejectValue("username", "error.username.too.short"); 
    } 
} 



    @Controller 
public class LostPasswordController 
{ 

    private static final Logger logger = LoggerFactory.getLogger(LostPasswordController.class); 
    VelocityEmailService sender= new VelocityEmailService(); 
    UserService service= new UserService(); 



    @InitBinder 
    public void initBinder(WebDataBinder binder) 
    { 
     binder.setAllowedFields(new String[] { "captcha", "username" }); 
    } 

    @ModelAttribute("form") 
    public LostPasswordForm populateForm() 
    { 
     return new LostPasswordForm(); 
    } 

    @RequestMapping(value = "/lostPassword", method = RequestMethod.GET) 
    public String lostPassword() 
    { 
     logger.debug("Rendering lost password form."); 
     return "lostPassword"; 
    } 

    @RequestMapping(value = "/lostPassword", method = RequestMethod.POST) 
    public String processSubmit(@ModelAttribute("form") LostPasswordForm form,HttpServletResponse response, BindingResult result) 
    { 
     logger.debug("Processing lost password form."); 

     new LostPasswordFormValidator().validate(form, result); 
     if (!result.hasErrors()) 
     { 

      User user = service.findUserByUsername(form.getUsername()); 
      System.out.println(user); 
      if (user != null) 
      { 
       String frob = BCrypt.hashpw(user.getUsername() + "3m4il", BCrypt.gensalt()); 
       String link = createLostPasswordLink(user, frob); 
       sender.sendLostPasswordEmail(user, link); 
       response.addCookie(persistFrob(frob)); 
       return "lost-password-success"; 
      } 
      result.rejectValue("username", "error.username.invalid"); 
     } 
     return "lostPassword"; 
    } 

    private String createLostPasswordLink(final User user, final String frob) 
    { 
     StringBuilder link = new StringBuilder(); 
     link.append("http://localhost:8080/password/reset.do?frob="); 
     link.append(frob); 
     link.append("&username="); 
     link.append(user.getUsername()); 
     return link.toString(); 
    } 

    private Cookie persistFrob(final String frob) 
    { 
     Cookie cookie = new Cookie("frob", frob); 
     cookie.setMaxAge(60 * 60); // 1 hour 
     return cookie; 
    } 
} 

<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:mvc="http://www.springframework.org/schema/mvc" 
    xmlns:p="http://www.springframework.org/schema/p" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
     http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 
     http://www.springframework.org/schema/mvc 
     http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd 
     http://www.springframework.org/schema/context 
     http://www.springframework.org/schema/context/spring-context-3.1.xsd"> 

    <context:component-scan base-package=".........weblayer" /> 


    <mvc:annotation-driven /> 
    <context:annotation-config /> 

    <mvc:resources mapping="/resources/**" location="/resources/" /> 

    <context:property-placeholder location="classpath*:*.properties" /> 


    <bean id="messageTemplate" class="org.springframework.mail.SimpleMailMessage" 
     scope="prototype"> 
     <property name="from" value="myemailaddress" /> 
    </bean> 

    <!-- - This bean resolves specific types of exceptions to corresponding 
     logical - view names for error views. The default behaviour of DispatcherServlet 
     - is to propagate all exceptions to the servlet container: this will happen 
     - here with all other types of exceptions. --> 
    <bean 
     class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> 
     <property name="exceptionMappings"> 
      <props> 
       <prop key="org.springframework.web.servlet.PageNotFound">pageNotFound</prop> 
       <prop key="org.springframework.dao.DataAccessException">dataAccessFailure</prop> 
       <prop key="org.springframework.transaction.TransactionException">dataAccessFailure</prop> 
      </props> 
     </property> 
    </bean> 

    <bean 
     class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
     <property name="prefix" value="/WEB-INF/views/users/" /> 
     <property name="suffix" value=".jsp" /> 
    </bean> 


    <bean id="messageSource" 
     class="org.springframework.context.support.ResourceBundleMessageSource"> 
     <property name="basenames" value="mymessages"></property> 
    </bean> 

    <bean id="multipartResolver" 
     class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> 
     <!-- max upload size in bytes --> 
     <property name="maxUploadSize" value="50242880" /> 
     <!-- max size of file in memory (in bytes) --> 
     <property name="maxInMemorySize" value="1048576" /> <!-- 1MB --> 
    </bean> 
    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" /> 
    <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" /> 

</beans> 

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> 

    <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl"> 
     <property name="host" value="${mail.host}" /> 
     <property name="username" value="${mail.username}" /> 
     <property name="password" value="${mail.password}" /> 
     <property name="port" value="${mail.port}" /> 
     <property name="protocol" value="smtp" /> 

     <property name="javaMailProperties"> 
      <props> 
       <prop key="mail.smtp.auth">${mail.smtp.auth}</prop> 
       <prop key="mail.smtp.connectiontimeout">5000</prop> 
       <prop key="mail.smtp.sendpartial">${mail.smtp.sendpartial}</prop> 
       <prop key="mail.smtp.userset">${mail.smtp.userset}</prop> 
       <prop key="mail.mime.charset">UTF-8</prop> 
       <prop key="mail.smtp.isSecure">${mail.smtp.isSecure}</prop> 
       <prop key="mail.smtp.requiresAuthentication">${mail.smtp.requiresAuthentication}</prop> 
       <prop key="mail.smtps.auth">${mail.smtps.auth}</prop> 
       <prop key="mail.smtp.port">${mail.port}</prop> 
       <prop key="mail.smtp.socketFactory.class">javax.net.ssl.SSLSocketFactory</prop> 
       <prop key="mail.smtp.socketFactory.fallback">${mail.smtp.socketFactory.fallback}</prop> 
       <prop key="mail.smtp.starttls.enable">${mail.smtp.starttls.enable}</prop> 
       <prop key="mail.debug">${mail.debug}</prop> 
      </props> 
     </property> 
    </bean> 

    <bean id="messageTemplate" class="org.springframework.mail.SimpleMailMessage" 
     scope="prototype"> 
     <property name="from" value="${mail.username}" /> 
    </bean> 
    <!-- Mail sender configured for using Gmail --> 
    <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl" 
     p:host="smtp.gmail.com" p:username="${mail.username}" p:password="${mail.password}"> 
     <property name="javaMailProperties"> 
      <props> 
       <prop key="mail.smtp.auth">true</prop> 
       <prop key="mail.smtp.starttls.enable">true</prop> 
      </props> 
     </property> 
    </bean> 

    <bean id="velocityEngine" 
     class="org.springframework.ui.velocity.VelocityEngineFactoryBean"> 
     <property name="velocityProperties"> 
      <props> 
       <prop key="resource.loader">class</prop> 
       <prop key="class.resource.loader.class">org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader 
       </prop> 
      </props> 
     </property> 
    </bean> 

</beans> 
+0

解決 只是改變 VelocityEmailService發件人=新VelocityEmailService(); UserService service = new UserService(); 至 VelocityEmailService sender; UserService服務; 不需要啓動 – user1067665

回答

0

解決

只要改變

VelocityEmailService sender= new VelocityEmailService(); 
UserService service= new UserService(); 

VelocityEmailService sender; 
UserService service; 

沒有任何需要啓動的。

而emailConfig.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:p="http://www.springframework.org/schema/p" 
xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans.xsd 
http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context.xsd 
http://www.springframework.org/schema/mvc 
http://www.springframework.org/schema/mvc/spring-mvc.xsd"> 

<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl"> 
    <property name="host" value="${mail.host}" /> 
    <property name="port" value="${mail.port}" /> 
    <property name="username" value="${mail.username}" /> 
    <property name="password" value="${mail.password}" /> 

    <property name="javaMailProperties"> 
     <props> 
      <prop key="mail.smtp.auth">true</prop> 
      <prop key="mail.smtp.starttls.enable">true</prop> 
      <prop key="mail.smtp.debug">true</prop> 
     </props> 
    </property> 
</bean> 


<bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean"> 
<property name="resourceLoaderPath" value="/WEB-INF/velocity/"/> 
</bean>  
</beans>