I am a newbie to adding Freemarker to Spring and Spring Mail. I am not using Spring Boot, but I am using the latest Spring 4.x, and though we have an application context XML file, we do use annotations.
So, ultimately I want to read the templates out of a database, because we may have many of them for many clients. We will not be loading templates from a filename or from disk.
We have our Spring Application as a maven multi-module project:
entity.jar - module
dao.jar - module
services.jar - module
ws.jar - module
Under services we have an application context file that defines Freemarker as follow:
<bean id="freemarkerConfiguration"
class="org.springframework.ui.freemarker.FreeMarkerConfigurationFactoryBean">
<property name="preTemplateLoaders">
<list>
<ref bean="databaseTemplateLoader" />
</list>
</property>
</bean>
<bean name="databaseTemplateLoader"
class="com.myapp.server.util.DatabaseToFreeMarkerTemplateLoader" />
I have a new class called:
public class DatabaseToFreeMarkerTemplateLoader extends StringTemplateLoader
{
// todo: add code here
}
But I am not sure what else I need in here. I am looking on the internet for some examples, but I can't find too much.
If someone can point me to an example, or refer me to another link here, I'll do my best to see if I can literally fill in the blanks.
Thanks!
BTW: I am surprised I had to include spring-web in my services layer in order to make this work. I just wanted to format an email and not html pages. So if there a better formatting tool that works seamlessly with Spring, let me know.
I don't know this part of Spring much, but I don't think you need spring-web. You could just use the FreeMarker API directly both for configuring (i.e., create a freemarker.template.Configuration singleton bean) and generating the output (template = configuration.getTemplate(...), template.process(...)). Finally you simply use message.setText(theOutputFromTemplateDotProcess, true); (where message is the Spring MimeMessageHelper). So there's no much to integrate with Spring here, I believe. (Even if someone needs to load templates from Spring resources, they can use an org.springframework.ui.freemarker.SpringTemplateLoader via Configuration.setTemplateLoader.)
As of using FreeMarker API directly (not related to Spring), see this example: http://freemarker.org/docs/pgui_quickstart_all.html
Related
Is there a decent way to read a spring application context from xml without initializing the beans right away, so they can be mocked or not, before they are actually created?
Yes, I know about lazy-init, but the actual applicationContext.xml is taboo for me.
The situation is that I have to create some JUnit tests on an application which has been created in a way that puts some difficulties in the way:
the configuration file must not be altered, nor the code that is to be tested
there are a lot of beans, some of them rather complex and hard to mock
part of the test is to use as many of the beans un-mocked as possible
some of the beans implement InitializingBean, verifying the environment on initialization and throw errors when Jenkins tries to build.
new FileSystemXmlApplicationContext("config.xml") immediately initializes the beans and throws errors if not in an appropriate environment.
What I have tried:
I have tried Powermock whenNew to mock the offending beans but to do that I would have to know the class which actually creates the beans. As this class belongs to the spring framework, it may change with future versions. When using #PrepareEverythingForTest it results in an StackOverflow exception. The application is real life, not a small piece of code from some tutorial.
I also searched for something like ForceLazyFileSystemXmlApplicationContext but didn't find anything.
Pleas don't start nagging about bad design, I know about that.
You can write your own applicationContext for your testing purpose. There you need to write your own BeanFactory. In that factory you can replace some of beans with mocks.
I just remembered about an option. Evaluate if you can use spring profiles. It will allow to choose a different implementation based on profiles.
Example:
<!-- This is the default myBean -->
<beans>
<bean id="myBean" class="mypackage.MyBean" />
</beans>
<!-- This is the mocked myBean for testing purposes, it will take place when testingProfile is active -->
<beans profile="testingProfile">
<bean id="myBean" class="mypackage.MyBeanMock" />
</beans>
You can indicate which profile to use via properties or environment variables. Example, if you are using maven in your project you could run the tests as:
mvn test -Dspring.profiles.active="testingProfile"
Take a look at:
http://www.baeldung.com/spring-profiles
https://spring.io/blog/2011/02/11/spring-framework-3-1-m1-released/
I have a web application running on tomcat and using spring framework. I also have jackrabbit oak libraries embedded in project.
I can get jackrabbit repository with java code like this:
new Jcr(new Oak(ns)).createRepository();
but I want to define my repository in a repository.xml file and then put it somewhere and instantiate it with spring xml files, so I can customize various things like ExternalIdentityProvider in my repository.
Something like this I think:
<bean id="repository" class="org.apache.jackrabbit.oak.jcr.repository.RepositoryImpl"
references="repository.xml"/>
but I don't know how I should define this repository in spring. any suggestion?
just use it like any other library:
put some variables in your application.properties
use Java config (XML config is not the most robust one)
access those variables using your favourite way
build your ns object using those variables
register the outcome of new Jcr(new Oak(ns)).createRepository() as a Bean that uses the newly created ns object - this should help you
and that should do the trick :)
I'm a newbie with Spring MVC but now i've been moved to a new project which uses Spring Integration to turn in channel some service. Example in the context.xml
<int:channel id="example-channel" />
<int:service-activator input-channel="example-channel" ref="exampleServiceFacade" />
For every servicefacade i have to bind the service to a channel.
I was wandering, what if I could map the classes to be turned into channels as i could map the beans with component-scan?
<context:component-scan base-package="com.package" />
so i ended up with this tutorial which speaks about some annotation:
#IntegrationComponentScan
But i cannot understand how it's related to the xml tag service activator and channel.. So i'm quite confused. Does anyone with more experience have an idea if what i'm trying to do can be done?
I just want to scan con the classes which defines channels in integration without having to declare every class.
Thanks.
Your question is a bit unclear. Any Spring Integration custom XML tag is parsed by infrastructure and registered as beans in the application context. Like you'd do that via raw <bean>.
#ComponentScan, #Configuration, #Bean and so on are marker annotations to say application context which classes treat as beans.
So, using both techniques for application context configuration you don't lose anything and can continue to mark you class with #Service and use its bean name from <service-activator ref="">.
From other side now you can fully build Spring Integration without any XML! Please, read the mentioned doc in its entirety.
I read a big part of spring documentation, and I think that I missed this part.
Do I need requestMapping for each page in my webapp? Even for those static ones? For example if I have a page with few sites:
home
about me
contact
articles
SomeStaticPage
Do i need requestMapping in my controller for all of those pages?
For example if I want to go to the contact page, I have to add requestMapping for path /contact in my controller ? Or if I will have contact.jsp in my /WEB-INF/views, Spring will detect it automaticly without defining RequestMapping for it?
Or maybe in href property I should just add static path to /contact.jsp ?
Also, I am aware of that, if for example for articles page, I will want to have articles taken from database, I will have to add request mapping which will put that article list object in Model object.
I'm asking mainly for static pages.
Or if I will have contact.jsp in my /WEB-INF/views, Spring will detect it automaticly without defining RequestMapping for it
I don't think that Spring can do that for you. And you can't access anything that is in WEB-INF directly via URL either.
What you could do is this:
1: Place the pages (HTML, JSP, ...) you want to access directly (without creating controllers for them) for example in src/main/webapp/pages (this location assumes that you are using Maven) and configure Spring to serve these pages directly.
You could do this using this XML configuration:
<mvc:resources mapping="*.html" location="/pages/" />
2: you could use <mvc:view-controller /> tag in your Spring configuration to define mappings for your views. In this case you would still have to define mappings for each view as with #RequestMapping, but in this case it is just a single line of code.
Additional benefit of this solution is that you could keep your URLs consistent with the rest of the application.
<mvc:view-controller path="/" view-name="home" />
Java configuration alternatives to both examples are in the documentation mentioned below.
Sources and additional information
Configuring view controllers
Configuring static resources
In case of supporting both XML and annotation, when spring framework do the annotation scan and how to process it?
Could someone give detail scenario?
For XmlWebApplicationContext, it use loadBeanDefinations() via Xml file. But when it do the annotation scan and use which class to process it?
Could explain the detail for ?
Thanks.
Franklin
In an XML based Application Context, annotations are only registered if you explicitly configure that:
<!-- register default annotations (e.g. #Required) -->
<context:annotation-config />
<!-- scan for components in selected package -->
<context:component-scan base-package="org.example"/>
Reference:
Annotation-based container
configuration
Classpath scanning and managed
components
And if you want to check the inner workings, see:
CommonAnnotationBeanPostProcessor
JavaDoc, Source Code
ComponentScanBeanDefinitionParser
JavaDoc, Source Code
I guess u could dig in the sources starting with AnnotationConfigWebApplicationContext.
http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/context/support/AnnotationConfigWebApplicationContext.html