2010-06-27 14 views
3

Velocity를 사용하여 Spring의 JavaMailSender 클래스에서 메일을 보내는 전자 메일 템플리트를 만들려고합니다. 웹 애플리케이션에서 Velocity 템플릿을 찾기 위해 사용하기로 결정한 리소스 로더는 Velocity 툴 jar에있는 WebappResourceLoader입니다.Velocity의 WebappResourceLoader를 Spring과 함께 사용하기

그러나 WebappResourceLoader를 사용하는 방법에 따라 웹 응용 프로그램이 시작될 때 NPE가 표시되거나 템플릿을 찾을 수 없습니다.

스프링 애플리케이션 컨텍스트에서 Velocity 엔진의 init 속성을 지정하면 NPE를 얻는다. 다음과 같이 내 구성은 다음과 같습니다

<bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean"> 
    <property name="velocityProperties"> 
     <props> 
     <prop key="resource.loader">webapp</prop> 
     <prop key="webapp.resource.loader.class">org.apache.velocity.tools.view.WebappResourceLoader</prop> 
     <prop key="webapp.resource.loader.path">/WEB-INF/velocity/</prop> 
     </props> 
    </property> 
</bean> 

응용 프로그램이 시작되었을 때 내가 얻을 스택 추적 :

<bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean" /> 
:

java.lang.NullPointerException 
at org.apache.velocity.tools.view.WebappResourceLoader.getResourceStream(WebappResourceLoader.java:145) 
at org.apache.velocity.runtime.resource.loader.ResourceLoader.resourceExists(ResourceLoader.java:224) 
at org.apache.velocity.runtime.resource.ResourceManagerImpl.getLoaderForResource(ResourceManagerImpl.java:641) 
at org.apache.velocity.runtime.resource.ResourceManagerImpl.getLoaderNameForResource(ResourceManagerImpl.java:624) 
at org.apache.velocity.runtime.RuntimeInstance.getLoaderNameForResource(RuntimeInstance.java:1464) 
at org.apache.velocity.runtime.VelocimacroFactory.initVelocimacro(VelocimacroFactory.java:159) 
at org.apache.velocity.runtime.RuntimeInstance.init(RuntimeInstance.java:261) 
at org.apache.velocity.app.VelocityEngine.init(VelocityEngine.java:107) 
at org.springframework.ui.velocity.VelocityEngineFactory.createVelocityEngine(VelocityEngineFactory.java:251) 
at org.springframework.ui.velocity.VelocityEngineFactoryBean.afterPropertiesSet(VelocityEngineFactoryBean.java:57) 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1460) 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1398) 

내가 아래로 내 응용 프로그램 컨텍스트를 변경이 문제를 해결하려면

그리고 나서 서비스 클래스에서 응용 프로그램 데이터를 템플릿 (예 :/WEB-INF/velocity 및 regemail.vm)과 병합하는 코드 앞에 다음 코드를 추가했습니다.

velocityEngine.addProperty("resource.loader", "webapp"); 
    velocityEngine.addProperty("webapp.resource.loader.class", "org.apache.velocity.tools.view.WebappResourceLoader"); 
    velocityEngine.addProperty("webapp.resource.loader.path", "/WEB-INF/velocity/"); 
    velocityEngine.setApplicationAttribute("javax.servlet.ServletContext", "localhost:8080"); 

응용 프로그램은 잘 시작하지만 이메일이 전송 될 것입니다 때, 나는 다음과 같은 오류 얻을 : 나는 속도 버전 1.6.4 및 속도 도구 2.0을 사용하고

SEVERE: Servlet.service() for servlet default threw exception 
org.apache.velocity.exception.ResourceNotFoundException: Unable to find resource 'regmail.vm' 
at org.apache.velocity.runtime.resource.ResourceManagerImpl.loadResource(ResourceManagerImpl.java:483) 
at org.apache.velocity.runtime.resource.ResourceManagerImpl.getResource(ResourceManagerImpl.java:354) 
at org.apache.velocity.runtime.RuntimeInstance.getTemplate(RuntimeInstance.java:1400) 
at org.apache.velocity.app.VelocityEngine.mergeTemplate(VelocityEngine.java:370) 
at org.apache.velocity.app.VelocityEngine.mergeTemplate(VelocityEngine.java:345) 
at org.springframework.ui.velocity.VelocityEngineUtils.mergeTemplate(VelocityEngineUtils.java:58) 
at org.springframework.ui.velocity.VelocityEngineUtils.mergeTemplateIntoString(VelocityEngineUtils.java:122) 
at com.mywebapp.web.service.RegistrationServiceImpl$1.prepare(RegistrationServiceImpl.java:60) 
at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:353) 
at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:345) 
at com.mywebapp.web.service.RegistrationServiceImpl.sendRegEmail(RegistrationServiceImpl.java:65) 
at com.mywebapp.web.controller.SignUpController.onSubmit(SignUpController.java:97) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 

합니다. 어떤 도움을 많이 주셨습니다. 감사!

답변

1

는 당신의 ServletContext 객체를 전달해야 또 다른 옵션 대신 ClasspathResourceLoader를 사용하여 클래스 경로 내에서 템플릿을 넣는 것

velocityEngine.setApplicationAttribute("javax.servlet.ServletContext", request.getSession().getServletContext()); 

.

+0

감사 serg555 :

간단하게이 같은 VelocityConfigurer 대신 당신의 Spring 컨텍스트 파일에 VelocityEngineFactoryBean를 사용합니다. Velocity 문서에 따르면, ClasspathResouceLoader는 웹 응용 프로그램 내에서 사용될 때 피해야합니다. 답변을 주셔서 감사합니다. – richever

+0

그래서 ServletContext 전달에 성공 했습니까? – serg

+0

@serg - ServletContext가 "@Context ServletContext context"를 통해 주입되고 init()을 호출하기 전에 this *가 설정되어 있어야 함을 인정하면서 Jersey 컨텍스트에서 저에게 도움이되었습니다. 감사. – paulkmoore

1

VelocityEngineFactoryBean에 대한 설명서를 보면 'resourceLoaderPath'속성을 설정할 수 있다는 것을 알 수 있습니다. 위의 설정을 감안할 때 Velocity 템플릿을 /WEB-INF/velocity/ 아래에 두었던 것처럼 보이므로 'resourceLoaderPath'값으로 사용하면 factory bean이 템플릿을 잘로드해야합니다.

1

3 년 후, ServletContext를 Velocity Engine에 전달하기 위해 Java 코드를 조정할 필요가없는 또 다른 해결책이 있습니다.

<bean id="velocityConfig" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer"> 
    <property name="velocityPropertiesMap"> 
     <map> 
      <entry key="runtime.log.invalid.reference"><value>true</value></entry> 
      <entry key="runtime.log.logsystem.class"><value>org.apache.velocity.runtime.log.Log4JLogChute</value></entry> 
      <entry key="runtime.log.logsystem.log4j.logger"><value>velocity</value></entry> 
      <entry key="input.encoding"><value>UTF-8</value></entry> 
      <entry key="output.encoding"><value>UTF-8</value></entry> 
      <entry key="directive.include.output.errormsg.start"><value></value></entry> 
      <entry key="directive.parse.max.depth"><value>10</value></entry> 
      <entry key="directive.set.null.allowed"><value>true</value></entry> 
      <entry key="velocimacro.library.autoreload"><value>true</value></entry> 
      <entry key="velocimacro.permissions.allow.inline"><value>true</value></entry> 
      <entry key="velocimacro.permissions.allow.inline.to.replace.global"><value>false</value></entry> 
      <entry key="velocimacro.permissions.allow.inline.local.scope"><value>false</value></entry> 
      <entry key="velocimacro.context.localscope"><value>false</value></entry> 
      <entry key="runtime.interpolate.string.literals"><value>true</value></entry> 
      <entry key="resource.manager.class"><value>org.apache.velocity.runtime.resource.ResourceManagerImpl</value></entry> 
      <entry key="resource.manager.cache.class"><value>org.apache.velocity.runtime.resource.ResourceCacheImpl</value></entry> 
      <entry key="resource.loader"><value>webapp, class, ds</value></entry> 
      <entry key="class.resource.loader.description"><value>Velocity Classpath Resource Loader</value></entry> 
      <entry key="class.resource.loader.class"><value>org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader</value></entry> 
      <entry key="webapp.resource.loader.class"><value>org.apache.velocity.tools.view.WebappResourceLoader</value></entry> 
      <entry key="webapp.resource.loader.path"><value>/WEB-INF/views/</value></entry> 
      <entry key="webapp.resource.loader.cache"><value>false</value></entry> 
      <entry key="webapp.resource.loader.modificationCheckInterval"><value>2</value></entry> 
      <entry key="ds.resource.loader.instance"><ref bean="templateLoader"/></entry> 
      <entry key="ds.resource.loader.resource.table"><value>templates</value></entry> 
      <entry key="ds.resource.loader.resource.keycolumn"><value>code</value></entry> 
      <entry key="ds.resource.loader.resource.templatecolumn"><value>content</value></entry> 
      <entry key="ds.resource.loader.resource.timestampcolumn"><value>updated</value></entry> 
      <entry key="ds.resource.loader.cache"><value>false</value></entry> 
     </map> 
    </property> 
</bean> 

<bean id="templateLoader" 
    class="org.apache.velocity.runtime.resource.loader.DataSourceResourceLoader"> 
    <property name="dataSource" ref="yourDataSource"></property> 
</bean> 
관련 문제