Email Velocity电子邮件不工作

Email Velocity电子邮件不工作,email,nullpointerexception,velocity,Email,Nullpointerexception,Velocity,我使用Velocity和Java mail sender,但我得到了一个NullPointerException,我不知道为什么。我做了很多尝试,但都没能解决问题,老实说,我不知道这个问题是靠什么解决的 下面是我使用的示例代码。 非常感谢你的帮助 SEVERE: Servlet.service() for servlet [mvc-dispatcher] in context with path [/guard_weblayer] threw exception [Request process

我使用Velocity和Java mail sender,但我得到了一个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) 严重:路径为[/guard\u weblayer]的上下文中Servlet[mvc dispatcher]的Servlet.service()引发了异常[Request processing failed;嵌套异常为java.lang.NullPointerException],其根本原因是 java.lang.NullPointerException 在se.guards.mail.VelocityEmailService.sendLostPasswordEmail上(VelocityEmailService.java:49) 在se.guards.lostpassword.LostPasswordController.processSubmit(LostPasswordController.java:71)
公共接口VelocityMailRepository
{
public void sendLostPasswordEmail(最终用户,最终字符串操作);
}
公共类VelocityEmailService实现VelocityMail存储库
{
私有静态最终记录器Logger=LoggerFactory.getLogger(VelocityEmailService.class);
@自动连线
私人速度发动机速度;
@自动连线
私有JavaMailSenderImpl JavaMailSenderImpl;
@自动连线
私有JavaMailSender;
public void sendLostPasswordEmail(最终用户,最终字符串操作)
{
debug(“将丢失的密码电子邮件发送到:{}”,user.getUsername());
MimeMessagePreparator preparator=新的MimeMessagePreparator(){
public void prepare(MimeMessage MimeMessage)引发异常{
mimessagehelper message=新的mimessagehelper(mimessage);
message.setTo(user.getEmail());
message.setFrom(“否-reply@sziebert.net");
message.setSubject(“您的密码”);
映射模型=新的HashMap();
model.put(“用户”,user);
模型放置(“url”,动作);
String text=mergeTemplateIntoString(velocity,“email/lost password.vm”,“password”,model);
message.setText(text,true);
}
};
本.发送方.发送方(制单人);
}       

公共类LostPasswordFormValidator实现验证程序{
私有静态最终记录器Logger=LoggerFactory.getLogger(LostPasswordFormValidator.class);
公共布尔支持(类clazz){
返回LostPasswordForm.class.equals(clazz);
}
公共无效验证(对象对象,错误){
debug(“验证丢失的密码表单”);
LostPasswordForm=(LostPasswordForm)obj;
//确保具有指定值的值。
rejectIfEmptyOrWhitespace(错误,“username”,“error.username.empty”);
//确保输入不包含任何非法字符。
如果(!isAlphanumeric(form.getUsername()))
errors.rejectValue(“username”、“error.username.invalize.chars”);
if(isNotBlank(form.getUsername())&&form.getUsername().length()<4)
errors.rejectValue(“username”、“error.username.too.short”);
}
}
@控制器
公共类LostPasswordController
{
私有静态最终记录器Logger=LoggerFactory.getLogger(LostPasswordController.class);
VelocityEmailService发送者=新的VelocityEmailService();
UserService=newuserservice();
@InitBinder
公共绑定器(WebDataBinder绑定器)
{
binder.setAllowedFields(新字符串[]{“captcha”,“username”});
}
@模型属性(“形式”)
public LostPasswordForm populateForm()
{
返回新的LostPasswordForm();
}
@RequestMapping(value=“/lostPassword”,method=RequestMethod.GET)
公共字符串lostPassword()
{
debug(“呈现丢失的密码表单”);
返回“lostPassword”;
}
@RequestMapping(value=“/lostPassword”,method=RequestMethod.POST)
公共字符串processSubmit(@modeldattribute(“form”)LostPasswordForm表单、HttpServletResponse响应、BindingResult结果)
{
debug(“处理丢失的密码表单”);
新的LostPasswordFormValidator()。验证(表单、结果);
如果(!result.hasErrors())
{
User User=service.findUserByUsername(form.getUsername());
System.out.println(用户);
如果(用户!=null)
{
字符串frob=BCrypt.hashpw(user.getUsername()+“3m4il”,BCrypt.gensalt());
字符串链接=createLostPasswordLink(用户,frob);
sender.sendLostPasswordEmail(用户,链接);
addCookie(persistFrob(frob));
返回“丢失密码成功”;
}
result.rejectValue(“username”、“error.username.invalid”);
}
返回“lostPassword”;
}
私有字符串createLostPasswordLink(最终用户,最终字符串frob)
{
StringBuilder链接=新建StringBuilder();
link.append(“http://localhost:8080/password/reset.do?frob=");
附加链接(frob);
link.append(“&username=”);
link.append(user.getUsername());
返回link.toString();
}
私有Cookie持久化frob(最终字符串frob)
{
Cookie Cookie=新Cookie(“frob”,frob);
cookie.setMaxAge(60*60);//1小时
返回cookie;
}
}  


找不到页面
数据访问失败
数据访问失败


${mail.smtp.auth}
5000
${mail.smtp.sendpartial}
${mail.smtp.userset}
UTF-8
${mail.smtp.isSecure}
${mail.smtp.RequireAuthentication}
${mail.smtps.auth}
${mail.port}
javax.net.ssl.SSLSocketFactory
${mail.smtp.s
   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("no-reply@sziebert.net");
            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>   
VelocityEmailService sender= new VelocityEmailService(); 
UserService service= new UserService(); 
VelocityEmailService sender; 
UserService service;
<?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>