我正在使用速度1.7与spring 3.1框架发送电子邮件。 velocity用于电子邮件模板。
以下是配置
<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>
以下是我的代码
@Component
public class EmailUtils {
@Autowired
private static VelocityEngine velocityEngine;
public static void sendMail(String subject, Map data, String template,
String toName, String toAddress) {
HtmlEmail email = new HtmlEmail();
try {
email.setHostName(hostName);
email.setSmtpPort(smtpPort);
email.setSubject(subject);
System.out.println(template +" template");
System.out.println(data +" data ");
System.out.println(velocityEngine +" velocityEngine ");
String message = VelocityEngineUtils.mergeTemplateIntoString(
velocityEngine, template, data);
System.out.println(message +" message message ");
email.setMsg(message);
email.addTo(toAddress, toName);
email.setFrom(fromAddress, fromName);
email.send();
} catch (EmailException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
当我运行应用程序时,我得到以下错误。
java.lang.NullPointerException
at org.springframework.ui.velocity.VelocityEngineUtils.mergeTemplate(VelocityEngineUtils.java:58)
因速度引擎为空。
<?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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
<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>
请帮帮我。我还需要做其他任何配置吗?
答案 0 :(得分:9)
使用时遇到了同样的问题。我可以通过以下方式解决它:
@Configuration
public class ApplicationConfiguration {
@Bean
public VelocityEngine getVelocityEngine() throws VelocityException, IOException{
VelocityEngineFactory factory = new VelocityEngineFactory();
Properties props = new Properties();
props.put("resource.loader", "class");
props.put("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
factory.setVelocityProperties(props);
return factory.createVelocityEngine();
}
}
但相反 - 因为我在视图中使用了速度模板,并且已经声明了VelocityConfigurer,所以我在我的VelocityConfigurer声明中使用了Autowired,并在其上调用了getVelocityEngine()。
我确实发现,如果将它自动连接到@Service-s或@ Component-s并且您已在共享的applicationContext.xml文件中声明,那么xml声明也必须位于该共享的applicationContext.xml中而不是xxx-servlet.xml配置。
我认为这是因为applicationContext.xml在应用程序中的所有servlet之间共享,因此必须在xxx-servlet.xml文件之前完全处理它。
或者,您可以启用spring bean工厂调试,看看它是否有任何实例化问题:
log4j.category.org.springframework.beans.factory=DEBUG
答案 1 :(得分:5)
我认为您不能将@Autowired
与静态字段一起使用。您可以使用非静态setter解决此问题:
@Autowired
public void setVelocityEngine(VelocityEngine ve) {
EmailUtils.velocityEngine = ve;
}
或以其他方式,但我强烈建议将EmailUtils
转换为非静态bean。 Spring更好地处理非静态组件(不需要丑陋的黑客),可以交换实现,你的代码将坚持DI philosphy。
答案 2 :(得分:1)
这是我的尝试,我通过ClassPathXmlApplicationContext手动初始化“velocityEngine”bean:
Spring application-context.xml
<bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
<property name="velocityProperties">
<value>
resource.loader=class
class.resource.loader.class=org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
</value>
</property>
</bean>
这是我的template_text.vm,将它放在类路径中,与application-context.xml相同。
Dear $userName,
You have made the following request on $userTime.
#if( $isFileMissing )
Missing file(s) found in home directory:
#foreach( $missingFile in $missingFiles )
- $missingFile
#end
#end
Best regards,
这是Java代码:
public static void main(String[] args) throws Exception {
String[] springConfig = {"application-context.xml"};
org.springframework.context.ApplicationContext context = new org.springframework.context.support.ClassPathXmlApplicationContext(springConfig);
java.util.Map<String, Object> model = new java.util.HashMap<String, Object>();
model.put("userName", "John Low");
model.put("userTime", "2015-10-28 23:59:59");
model.put("isFileMissing", true);
model.put("missingFiles", new String[] {"line 1", "line 2", "line 3"});
String text = org.springframework.ui.velocity.VelocityEngineUtils.mergeTemplateIntoString((VelocityEngine)context.getBean("velocityEngine"), "/template_text.vm", "UTF-8", model);
System.out.println(text);
}
输出:
Dear John Low,
You have made the following request on 2015-10-28 23:59:59.
Missing file(s) found in home directory:
- file 1
- file AAA
- line 3
Best regards,
答案 3 :(得分:0)
将项目升级到Java 11 + Spring Boot 2.1.8时遇到相同的问题。我可以通过以下方式解决它:
@Configuration
public class AppConfig {
@Bean
public VelocityEngine velocityEngine() throws Exception {
Properties properties = new Properties();
properties.setProperty("input.encoding", "UTF-8");
properties.setProperty("output.encoding", "UTF-8");
properties.setProperty("resource.loader", "class");
properties.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
VelocityEngine velocityEngine = new VelocityEngine(properties);
return velocityEngine;
}
}