Spring boot - Cannot access dynamically generated external fi;es - java

I need to serve dynamically generated jar files with spring boot. What I am trying to do is access these generated files without having to restart my spring boot application.
I have added the following config class according to many forum posts :
#Configuration
public class StaticFileConfig implements WebMvcConfigurer {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations("file:<path>/");
WebMvcConfigurer.super.addResourceHandlers(registry);
}
}
While this allows me to access files located at the specified path, I can not do so until after I restart my spring boot application.
Any suggestions as to how to access dynamically generated files without restarting the application ?
Thanks

Related

How do I configure GraphQL servlet endpoint for graphql-java-servlet along with Micronaut Controllers?

I have got a requirement to implement a File Upload functionality using GraphQL. My current Micronaut project has already some Controller classes and graphql-java-servlet supports file upload, it needs a Servlet to be created. How do I configure the micronaut project for both Controllers and Servlet?
I have tried creating simple servlet from graphql-java-servlet in the micronaut project and keeping all my controllers as it is.
public class HelloServlet extends GraphQLHttpServlet {
#Override
protected GraphQLConfiguration getConfiguration() {
...
}
private GraphQLSchema createSchema() {
...
}
}```
When I start the Micronaut application. it only identifies controllers and I am able to invoke them using curl request. Unfortunately (#WebServlet) is not configured and not exposed.
Micronaut does not support the servlet API, so it is not possible to register a servlet.

Reloading CORS settings at runtime

I recently implemented a Spring Cloud Config Server. My application (client) is able to retrieve application profiles and refresh them in flight.
Unfortunately, CORS settings, which are also declared there, are not reloaded by Spring during runtime. I did a small investigation and check that in terms of refresh everything looks good - ConfigurationPropertiesRebinder rebind() method successfully destroys old bean holding CORS setup and creates a new with up-to-date settings. I also see that Environment bean is holding new settings in propertySources field.
Is there any way to force Spring to reload CORS during runtime or should I need to reload application context?
Use below code for resolve CORS issue.
#Configuration
#EnableWebMvc
class WebConfig implements WebMvcConfigurer {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}

Spring Boot run command line and terminate

I have a large Spring Boot monolithic Web Application project. This application is packaged as an executable JAR and serves all kinds of JSON REST endpoints.
Now, I sometimes want to run a piece of Java code to process or import a large file, or clean up certain database tables from the command line.
What would be good way to do this with Spring Boot?
I first looked into CommandLineRunner interface but this seems to serve a completely different use case. This is executed always when running the Spring Boot application, followed by starting the main application.
I would like to have this functionality in the same application as the main web app for various reasons:
Reuse same application configuration (DB credentials, external config files, etc.)
Reuse application context
Shared application logic and code
Difficult to split into smaller (micro) services
If you want to reuse the same jar, you could use a combination of Profiles and CommandLineRunners.
#Configuration
public class BatchConfig {
#Bean
#Profile("import")
public CommandLineRunner import() {
// ...
}
#Bean
#Profile("dbClean")
public CommandLineRunner dbClean() {
// ...
}
}
Then, when you run the jar, pass the desired profile as argument.
java -jar -Dspring.profiles.active=dbClean yourJar.jar
In this way, your command line runners are executed only when the profile matches.

Why it is necessary to extend`SpringBootServletInitializer` while deploying it to an external tomcat

Why should we extend SpringBootServletInitializer in order to run a SpringBoot application to a external tomcat?
If without extending SpringBootServletInitializer it runs on embedded tomcat then why it is necessary to extendSpringBootServletInitializer while deploying it to an external tomcat?
Older Servlet containers don’t have support for the ServletContextInitializer bootstrap process used in Servlet 3.0. You can still use Spring and Spring Boot in these containers but you are going to need to add a web.xml to your application and configure it to load an ApplicationContext via a DispatcherServlet.
Inorder to create deployable war file is to provide a SpringBootServletInitializer subclass and override its configure method. This makes use of Spring Framework’s Servlet 3.0 support and allows you to configure your application when it’s launched by the servlet container. Typically, you update your application’s main class to extend SpringBootServletInitializer.
#SpringBootApplication
public class Application extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
You can refer below link
https://docs.spring.io/spring-boot/docs/current/reference/html/howto-traditional-deployment.html
Here is some more information :
In order to deploy a Servlet based web application(like Spring) you actually need to provide traditional web.xml .
We can also do the same thing programatically using WebApplicationInitializer interface. As per the docs
Interface to be implemented in Servlet 3.0+ environments in order to
configure the ServletContext programmatically -- as opposed to (or
possibly in conjunction with) the traditional web.xml-based approach.
As SpringBoot suggests to use JavaConfiguration over xml configuration.
It uses JavaConfiguration instead of web.xml.
It has SpringBootServletInitializer class which eventually implement the WebApplicationInitializer interface and override its onStartup to configure things.

Spring boot, possible causes of View cannot be resolved issue

What could be the problem if Spring Boot cannot resolve view with specific name?
I have developed many Spring Boot applications before and have never encountered this problem.
I have following folder structure:
/src/main/java
/src/main/resources/config
/src/main/resources/static
/src/main/resources/static/partials
/src/main/resources/static/resources
Image:
/src/main/resources/static/resources folder is not making problems for having resources name. I tried renaming it and it didn't solve problem.
I am using Maven and I have parent project which has multiple children projects.
Module for the rest api contains many configuration classes, including configurations for security.
Everything is working as it should, application can be started without errors, but when I tried to add static content I encountered this problem.
From the following example (example) we can see that Spring Boot should automatically maps src/main/resources/static/index.html to the root path, but that is not happening in my application. From the log I can see that Spring didn't find mapping for /.
I am able to run that example normally, but in my application it is not working.
Because Spring didn't map automatically I created WelcomeController which should return view:
#Controller
public class WelcomeRestController {
#RequestMapping("/")
public String welcome() {
return "index.html";
}
}
After I did that, mapping is found, but Spring reports that it couldn't resolve view with name index.html even if it exists.
I tried adding static content to src/main/webapp/static folder even if it is not recommended and it also didn't work, same problem, cannot resolve view.
I also tried to configure using
#Configuration
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
#Override public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index.html");
}
}
Again, view cannot be resolved.
My application's start point:
#Import(MyRestServiceConfiguration.class)
#SpringBootApplication
public class Application extends SpringBootServletInitializer {
public static void main(final String[] args) {
SpringApplication.run(Application.class, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(Application.class);
}
}
I am using embedded Tomcat.
Is it possible that security configurations or some other configurations except WebMvcConfigurerAdapter are having influence on views?
I am trying to resolve this issue for hours but I can't find soulution. Any help would be appreciated.
EDIT:
I am not building application using Maven, just running Application.java as Java Application, so Maven should not be a problem.
EDIT:
Content of index.html:
<!DOCTYPE html>
<html >
<head lang="en">
</head>
<body>
<div>Hello</div>
</body>
</html>
I have found a solution, but I am not really sure why this makes problem. Please post your answer if you know why is this happening.
The problem was #EnableWebMvc annotation in MyRestServiceConfiguration
#Configuration
// #EnableWebMvc
#Import(MyServiceConfiguration.class)
public class MyRestServiceConfiguration {
}
After removing it, everything works as it should.
From Spring Boot guide:
Normally you would add #EnableWebMvc for a Spring MVC app, but Spring Boot adds it automatically when it sees spring-webmvc on the classpath. This flags the application as a web application and activates key behaviors such as setting up a DispatcherServlet.
It's clear that #EnableWebMvc annotation is not needed, but why does it make problems?
EDIT:
From Spring Boot reference:
The easiest way to take complete control over MVC configuration is to provide your own #Configuration with the #EnableWebMvc annotation. This will leave all MVC configuration in your hands.
From Spring's #EnableWebMvc documentation:
Adding this annotation to an #Configuration class imports the Spring MVC configuration from WebMvcConfigurationSupport, e.g.:
#Configuration
#EnableWebMvc
#ComponentScan(basePackageClasses = { MyConfiguration.class })
public class MyWebConfiguration {
}
So, the problem was that #EnableWebMvc annotation dissabled default Spring Boot's configuration and because of that Spring didn't know where to look for static resources. If I got something wrong, please correct me.

Categories

Resources