Need to create a html file in web root folder at startup - spring

I'm using spring 3.1. And I need to make a html file in my web root at spring startUp.
Of course I know JSP makes a html, but it's about request-response. I need to create a html on the startup.
And.. I hope my job is possible in pure Spring framework.
I know of Quartz.. but I don't want to use quartz. Because I'm afraid that adopting Quartz may need many changes in my Spring config.

You can create a bean that implements ApplicationListener. An ApplicationListener listens to events published by the context.
The ApplicationContext publishes certain types of events when loading
the beans. For example, a ContextStartedEvent is published when the
context is started and ContextStoppedEvent is published when the
context is stopped.
Using an application listener allows you to execute some tasks when the application is first started or the context is refreshed.
Here is an example of a basic ApplicationListener from one of my projects:
public class MyApplicationListener implements ApplicationListener<ContextRefreshedEvent> {
#Override
public void onApplicationEvent(ContextRefreshedEvent event) {
//Generate html file here, this method is called when event happens
}
}
And its configuration:
<!-- Fired when different application events occur such as context refresh or startup -->
<bean id="myListener" class="fully.qualified.MyApplicationListener" />

Related

How to register JSF ExceptionHandlerFactory programmatically in Spring Boot

I'm using Joinfaces to build a JSF + Spring Boot application and Omnifaces is packed with it.
When the View expires and I navigate I get the ViewExpiredException. When I execute Ajax, the page does nothing and the error shows in the console.
Is it possible to register the org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory programatically with Spring, without having to add a .xml (web, faces-config) to my project?
Use the following to set up a custom exception handler sans web.xml:
FactoryFinder.setFactory(FactoryFinder.EXCEPTION_HANDLER_FACTORY,"org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory");
The trick here is to make sure this line is executed as early in the startup as possible; once FactoryFinder.getFactory() has been called by the JSF runtime, it's too late to change the configured handler.
The good thing is that I actually can't find anywhere in the Mojarra codebase where the exception handler factory is being set by default, so you probably could execute this maybe in the constructor (not the #PostConstructor) of any #ApplicationScoped bean. You could also do it in a static initializer of the ame bean.
Additionally, you could do it in a FacesInitializer. So asssuming you're running Mojarra, you'll need to setup the handler very early on in the startup process of the servlet context
public class YourWebAppInitializer extends FacesInitializer implements WebApplicationInitializer {
public void onStartup(ServletContext ctxt) throws ServletException {
AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext();
root.register(YourSpringConfigClass.class);
ctxt.addListener(new ContextLoaderListener(root));
FactoryFinder.setFactory(FactoryFinder.EXCEPTION_HANDLER_FACTORY,"org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory");
}
}
The WebApplicationInitializer is a standard interface supported by Spring for bootstrapping a web application and I'm assuming you already have that in place because you don't have a web.xml - feel free to replace the contents of the onStartup method with whatever you have in your actual implementation. The key thing here is to make sure you set the factory there, which is pretty early in the startup of the application.
Also note that you can hand set the actual ExceptionHandler on any given instance of FacesContext (although I haven't tested this to see how it'll behave or whether it'll perform well)

Spring in a JavaFX application - how to property handle controller as dependency?

I have a JavaFX application that uses spring boot, exactly as described in this blog post:
http://www.greggbolinger.com/let-spring-be-your-javafx-controller-factory/
I am using the FXML loader overriding the controller factory to use spring.
The problem is that Spring loads the controller class marked as #Component on application start or later if marked with #Lazy, but keeps the bean in memory.
If I open a Stage, modify the data, close the stage and open it again, the data is still there (because the controller was kept by spring). It also gets in the way if I open two of the same Stage (window). It shares the same controller, so if I modify one, the other modifies too, and this is not the desired behavior.
How to I properly handle JavaFX controllers with spring?
Thanks!
Mark the controller as having prototype scope, so that a new instance is created on each request:
#Component
#Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class Controller {
// ...
}

Calling a Spring #Service on web application initialization

I have a web application that needs some static variables initialization as soon as I thrown the .war in the Tomcat webapp folder. This initialization needs to call a #Service to retrieve the initial set up.
I realized that the #Autowire injection only works when my GUI is calling the service
What is the best way to initialize my Spring web application after throwing the .war in the app container? I need this initialization to be executed once only.
If you need to do something after servletContext is initialized, in spring, we use ApplicationListener to do this.
public class SpringListener implements ApplicationListener<ContextRefreshedEvent>{
// this should work if other setting is right
#Autowired
XXX xxx;
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent ) {
// do things here
}
}
in application.xml
<bean id="eventListenerBean" class="package.name.SpringListener " />
http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#context-functionality-events
On the otherhand, just FYI, the traditional way is to do it using ServletContextListener.
http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContextListener.html

Spring ApplicationListener gets fired twice on webapp

I have an application listener that's supposed to execute only once per webapp startup, since it loads basic user info data.
public class DefaultUsersDataLoader implements ApplicationListener<ContextRefreshedEvent> {
#Override
#Transactional
public void onApplicationEvent(ContextRefreshedEvent e) {...}
}
Somehow, it gets executed twice: on app startup and when the first request arrives to the server. Why is this happening and how can I prevent it?
Generally in a Spring MVC application you have both a ContextLoaderListener and DispatcherServlet. Both components create their own ApplicationContext which in turn both fire a ContextRefreshedEvent.
The DispatcherServlet uses the ApplicationContext as created by the ContextLoaderListener as its parent. Events fired from child contexts are propagated to the parent context.
Now if you have an ApplicationListener<ContextRefreshedEvent> defined in the root context (the one loaded by the ContextLoaderListener) it will receive an event twice.
Do not annotated your Listener Class's method with #EventListener

Spring session handling: HttpSessionDestroyedEvent not received

I have a web app where in the web.xml I have added the HttpSessionEventPublisher as listener. The web app runs on Jetty 7.x and we are using Spring 3.1.1.
This is supposed to fire HttpSessionCreatedEvent and HttpSessionDestroyedEvent to Spring context event listeners.
I have a Bean (#Controller) that implements ApplicationListener<ApplicationEvent>. ApplicationEvent is the common parent class of HttpSessionCreatedEvent and HttpSessionDestroyedEvent. When I now login to my web application or log out from it I'd expect these events to be fired to the onApplicationEvent(ApplicationEvent event) method. I have received other events like some request handling event, but the expected event's didn't show up. I have traced the app a bit, the HttpSessionEventPublisher definitely fires the event to the context, but the listener isn't approached. what do I miss here?
The issue is that HttpSessionEventPublisher publishes events on the "Spring Root WebApplicationContext" per the javadoc, this is the application context registered through ContextLoaderListener entry in your web.xml file. Your #Controller on the other hand is probably registered through a different application context altogether - the one registered through the DispatcherServlet. So I would suggest that you create a different ApplicationListener, register it to the Root WebapplicationContext, the events should come through then.
Facing a similar problem, if it not possible to move your ApplicationListener to the root context, you can use the org.springframework.security.context.DelegatingApplicationListener.
Just autowire a DelegatingApplicationListener in your Bean and use constructor / #PostConstruct to register your listener against the DelegatingApplicationListener (one should be already in place by spring-security)

Resources