I imagine it's incredibly simple but I've been unsuccessful in my googling of how-to's, reading of documentation, and perusing of Spring classes.
Spring's doc on their websocket api has been useful and I can see that the project I'm familiarizing myself with uses what it describes to start a server:
#Configuration
#EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
#Autowired
private MyWebSocketHandler webSocketHandler;
#Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(webSocketHandler, "/");
}
}
So it's easy enough to start, but I have no idea how to make it stop or pause. I'd like to add a feature to the application that takes down the server (and re-establishes it later) with a click of a button. But I have no ideas about how to stop or pause the server and the documentation doesn't seem to offer anything.
the initialization/management/shutdown of websocket/http connections are handled by spring and tomcat (default). I don't think it's a good idea to deal with it on your own.
a solution would be to decouple (with two springboot apps) the websocket service (which can be started/stopped manually) from the one (which is always up and running) with the "click of a button" page.
Related
I started to learn the Websocket from the guide on the spring website, and there was such a code in the websocket config class
#Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/gs-guide-websocket").withSockJS();
}
Specifically, I did not understand what endPoint is and why it is needed, I did not find any clear explanations on the Internet, or I am very stupid to understand them.
More questions about the methods setApplicationDestinationPrefixes and
enableSimpleBroker.
As I understand it, the first one is needed in order to be able to send messages only to an address with the prefix "/topic". And the second method is for #MessageMapping to process only those messages that have the prefix "/app". I would like to know if I understood everything correctly. And can I also change the value of "/app" to any other ? because when I changed it, the application stopped working. Thanks in advance to everyone who will help! :)
In my understanding registerStompEndpoints is where you specify your primary route for WebSocket communication to be listened by the server (You can think of this as a servlet context that we provide for your application in Spring context )
ConfigureMessageBroker is where you define your prefix for the topic but people keep it as "/topics" to make more sense out of it (In a spring MVC context you can string as the root path of a controller)
I created an example some time ago, it will help you clear up some confusion, if you want to have a look it's here:
https://github.com/sydkaz/films/blob/master/client/src/film/FilmList.js
I have a short lived process to read a simple file from a classpath into a memory, I chose ApplicationListener<ApplicationReadyEvent> to let spring trigger a task:
#Component
#Priority(1)
class MyLoader implements ApplicationListener<ApplicationReadyEvent> {
#Override
public void onApplicationEvent(ApplicationReadyEvent event) {
doStuff();
}
}
I realised not that few HTTP requests that I offer in this app depend on that data in memory. How can I force MyLoader class to execute before Web Server is ready to serve request? I have no idea how to define that dependency?
You should listen for an event before the ApplicationReadyEvent, because it is the final one, marking that the application is ready to serve requests.
For example, you can listen to ApplicationStartingEvent. See a list of the available ApplicationEvents here.
I have a Spring 4 mvc application and I would like to make a GET request to another node.js service when the web application is available.
The client is build with React.js and served by Spring.
I already tried the following Spring Listeners:
ServletContextListener
ApplicationListener
ContextLoaderListener
The node application when receives the call takes a screenshot of the homepage. The result is a white page because the event fires too soon.
I suppose that the problem could be the react js bundle taking more time to load.
Is there a away to solve this? Maybe I miss the right Listener.
Thank you
Sorry, this is for spring boot not simply spring-web.
You need the ApplicationReadyEvent as documented here: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-spring-application.html#boot-features-application-events-and-listeners
If your spring boot app is defined as follows, here's a possible implementation:
#SpringBootApplication
public class YourMainClass {
public static void main(String[] args) throws Exception {
SpringApplication.run(YourMainClass.class, args);
}
#EventListener(ApplicationReadyEvent.class)
public void EventListenerExecute(){
System.out.println("App is ready for requests");
}
}
I have a custom WebServerFactoryCustomizer but its not available for management port. What's the best way to make the customization available to server on management port? The regular server is on port =8080 and management server is on port = 8082.
I tried playing around with ServletManagementWebServerFactoryCustomizer but it didn't work. Any pointers will be appreciated.
here is the customizer (to disable TRACE for Undertow)
public class UndertowCustomizer implements
WebServerFactoryCustomizer<ConfigurableUndertowWebServerFactory> {
#Override
public void customize(final ConfigurableUndertowWebServerFactory undertowWebServerFactory) {
undertowWebServerFactory.addDeploymentInfoCustomizers(deploymentInfo ->
deploymentInfo.addInitialHandlerChainWrapper(handler ->
new DisallowedMethodsHandler(handler, HttpString.tryFromString(HttpMethod.TRACE.name())))
);
}
}
A sample reproducible service is at https://github.com/ranarula/WebServerCustomizer
Indeed I feel lack of information regarding this topic as well but I was able to get it working by following the documentation Adding custom endpoints
what you can do is just put the customizer in spring.factories
org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration=UndertowCustomizer
javadocs of this class might be helpful as well ManagementContextConfiguration
Can I write a module/filter that gets put into the processing pipleline in Tomcat BEFORE the web application even gets run?
Something that I could turn on/off for each web application that tomcat is handling.
is this possible?
So basically it would be a re-usable filter that hooks into the web pipeline that could alter the requests behavior or perform/modify the requests. One example would be to log all ip's, or redirect based on the url, block the request, etc.
If you are using Servlet 3.0 you can. What you do is implement either a ServletContextListener or a ServletContainerInitializer. The code below shows withServletContextListener
#WebListener("auto config listeners")
public class MyListenerConfigurator implements ServletContextListener {
public void contextInitialized(ServletContextEvent scEvt) {
ServletContext ctx = scEvt.getServletContext();
FilterRegistration.Dynamic reg = ctx.addFilter("myFilter", "my.listener.class.MyListener");
...
}
See EE6 docs here. Perhaps the only drawback is that you can add but you cannot remove. And you can only at when the application starts up.
Note: code not tested
Have you considered a ServletContextListener in web.xml?