如何在 Spring 中使用速度 1.7
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9562177/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use velocity 1.7 with Spring
提问by ashishjmeshram
I am using velocity 1.7 withe spring 3.1 framework for sending email. velocity is used for email templates.
我正在使用带有 spring 3.1 框架的velocity 1.7 来发送电子邮件。速度用于电子邮件模板。
Below is the configuration
下面是配置
<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>
and below is my code
下面是我的代码
@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();
}
}
}
When I run the application I get following error.
当我运行应用程序时,出现以下错误。
java.lang.NullPointerException
at org.springframework.ui.velocity.VelocityEngineUtils.mergeTemplate(VelocityEngineUtils.java:58)
as the velocity engine is null.
因为速度引擎为空。
<?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>
Please help me. Is there any other configuration that I need to do?
请帮我。我需要做任何其他配置吗?
回答by ndtreviv
I had the same issue when using . I could have solved it in the following way:
我在使用时遇到了同样的问题。我可以通过以下方式解决它:
@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();
}
}
But instead - because I was using velocity templates for my views and had already declared a VelocityConfigurer, so I instead Autowired in my declaration of VelocityConfigurer and called getVelocityEngine() on that.
但是相反 - 因为我为我的视图使用了速度模板并且已经声明了一个 VelocityConfigurer,所以我在我的 VelocityConfigurer 声明中改为 Autowired 并在其上调用 getVelocityEngine() 。
I did discover that, if it's being autowired into @Service-s or @Component-s and you've declared in a shared applicationContext.xml file, then the xml declaration had to be in that shared applicationContext.xml as well rather than the xxx-servlet.xml config.
我确实发现,如果它被自动连接到 @Service-s 或 @Component-s 并且您已经在共享的 applicationContext.xml 文件中声明,那么 xml 声明也必须在该共享的 applicationContext.xml 中,而不是xxx-servlet.xml 配置。
I think this is because applicationContext.xml is shared amongst all servlets in the application, so it has to be fully processed before the xxx-servlet.xml files are.
我认为这是因为 applicationContext.xml 在应用程序中的所有 servlet 之间共享,因此必须在 xxx-servlet.xml 文件之前对其进行完全处理。
Alternatively, you could enable spring bean factory debugging and see if it's having any issues instantiating it:
或者,您可以启用 spring bean 工厂调试,看看它在实例化它时是否有任何问题:
log4j.category.org.springframework.beans.factory=DEBUG
回答by mrembisz
I think you cannot use @Autowiredwith a static field. You can work around this with a non-static setter:
我认为您不能@Autowired与静态字段一起使用。您可以使用非静态 setter 解决此问题:
@Autowired
public void setVelocityEngine(VelocityEngine ve) {
EmailUtils.velocityEngine = ve;
}
or in another way but I would strongly recommend turning EmailUtilsinto a non-static bean. Spring handles non-static components much better (no ugly hacks needed), it will be possible to swap implementations and your code will stick to DI philosphy.
或者以另一种方式,但我强烈建议EmailUtils变成非静态 bean。Spring 可以更好地处理非静态组件(不需要丑陋的 hack),可以交换实现并且您的代码将坚持 DI 哲学。
回答by oraclesoon
This is my attempt, I initialize the "velocityEngine" bean manually via ClassPathXmlApplicationContext:
这是我的尝试,我通过 ClassPathXmlApplicationContext 手动初始化“velocityEngine”bean:
Spring application-context.xml
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>
This is my template_text.vm, put it in the classpath, same level as application-context.xml.
这是我的template_text.vm,放在classpath中,和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,
This is the Java code:
这是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);
}
The output:
输出:
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,

