I have a multi-module Spring Boot Gradle project. I have properties in each module yml file that point to database: user, pass, url.
It's working solution, but it's difficult to change project database. Every time I want switch database user or url, I must change 10+ yml files.
How to avoid this?
You could bind the properties in a class (see here: https://www.baeldung.com/configuration-properties-in-spring-boot) and inject the class where needed.
Related
I explain my problem;
I have a web app developed using Vue.js and Spring Boot, this application working a PDF sheet and saves the file that is generated by Java, I use two lines of code to separate my development part from the production part (I leave you the 2 lines of code like this you understand the concept well)
FileReader leggoFile = new FileReader(System.getProperty("user.dir") + "/temp/webapps/foolder/foolder/file.pdf");
// FileReader leggoFile = new FileReader(System.getProperty("catalina.base") + "/temp/webapps/foolder/foolder/file.pdf");
This whole application is built using the "bootWar gradle plugin" which returns me a .war which I will then upload to a Tomcat server;
My goal is this:
I would like to set a single environment variable so that if I want to build the project I don't have to comment/uncomment that line for example:
FileReader leggoFile = new FileReader({{variableEnvironment}} + "/temp/webapps/foolder/foolder/file.pdf")
my question is this:
How dp Gradle and Spring Boot handle environments? Is there a way to separate environments? Is this possible or should I start thinking differently?
I tried to search on something but unfortunately I was tied to the problem that I don't understand how the .war file is generated through the BootWar Gradle plugin, also searching on the internet I understood that environment Gradle and environment Spring are two separate things but in general even if I know the line of code is wrong in the beginning my question is always the same:
How are environment variables handled in Spring and Gradle?
With Spring Boot, you can add properties to your application by adding an file named application.yaml to your resources folder (src/resources/). In addition you can add properties through application-{profile}.yaml to add properties only for given Spring profiles. For instance application-test.yaml would only be read if "test" is an active profile. When booting up the application, Spring will first read application.yaml, then any profile-specific YAML-files, such that any overlapping properties are replaced.
There are several approaches to injecting the property. A simple solution is to add a field to your component annotated with #Value("${PATH}) and replace PATH with the property's path in the YAML.
I have a setup like this:
Main SpringBoot project with application-default.properties which on our deployment server are partially overwritten by a deployment specific properties.
Shared SpringBoot library project which has its own properties.
And when I run my main project with the library project attached (via gradle sourceControl gitRepository) I can see that the properties in the library project are empty.
How can I make the library project use the properties passed down from the main application ?
If you want to merge properties, please consider this official page.
Option 1 - default properties in library
As I found previously (probably, it is fixed), if you have jar1 and jar2 (sorted alphabetically) and both of them have application.properties file, only first will be used. They aren't merged. So please be carefully there.
However you can use #PropertySource in your library, e.g. put default properties there into the custom file name (for example - defaults-for-jar2.properties or something like this, to avoid automatic loading by Spring).
In this case:
Property load logic outside of your library will be the same with current.
Your library will load file from #PropertySource and next they will be overridden (if you have this) by your application.
Option 2 - configuration properties
If you use Kotlin and Spring, you can use ConfigurationProperties. And you can define the default values there. Moreover, IntelliJ Idea will highlight the default and possible values (according to the type, because you can use not only String, but any custom enum class, Duration class, etc.).
Just from that link:
#ConstructorBinding
#ConfigurationProperties("blog")
data class BlogProperties(var title: String, val banner: Banner) {
data class Banner(val title: String? = null, val content: String)
}
#SpringBootApplication
#EnableConfigurationProperties(BlogProperties::class)
class BlogApplication {
// ...
}
Please note:
You should mention your settings data class in the library configuration.
You should configure kapt properly to have Intelli Sence in IDEs.
I have two spring boot projects, Project A and Project B, each with its own application.properties.
When the project is run individually the values from application.properties are injected properly. But when I am using one of the Project B as a dependency in Project A, the default values defined in application.properties of B are not being injected and I have to define the same properties again in the .properties file of A which is kind of redundant.
How do I avoid this? I want the default values in the properties file of B to be injected and I would only want to define the properties for B when I want to override the default values. Sorry for my english
AFAIK, there is no out-of-box solution for this. I would recommend two solutions and you can go with one more feasible for you:
Take out all properties common for all projects and put them in a seperate properties file, use them with #PropertySource.
Use spring cloud config to store common(or all) properties. You can also have some custom logic there to pick the correct property among multiple property files.
It's hard to say without your code provided. I guess you can try to use multiple .properties files for Project A application like following:
#PropertySources({
#PropertySource(name = "propsA", value = "classpath:propsA.properties"),
#PropertySource(name = "propsB", value = "classpath:propsB.properties")
})
public class ApplicationA {
I am working to a project made in Maven with Spring and i want to start the structure fine from the beginning.
I need help from you to know if is ok what i did until now. So, in have the structure:
src/main/java/com/fabbydesign/controller
src/main/java/com/fabbydesign/model
src/main/java/com/fabbydesign/util
and i have another file in:
src/main/webapp/WEB-INF/appConfigs.xml
in this file i store the configurations of the project, like database login, etc
In the directory utils, i will store utils class for the project. for example, i will make a class that will read the appConfigs.xml to get configurations stored there
Is ok what i did until now?
In the model directory, i have to store the beans for the database, or i can add other types there? Like, the bean for the xml with configs?
Thanks!
I'm learning to make Java MVC project using Spring Tool Suite tool.
The path to make new project is:
File->New->SpringLegacyProject->Spring MVC Project.
My question is: which directory I have to use to add additional not-Spring files and where and what do I have to type for Spring files to see them?
For example:
css files - where to put and how to make jsp views see them, will 'link rel="" 'tag be enough?
properties files used to specify database connection or to specify messages for ReloadableResourceBundleMessageSource. In this case, do I have to create bean for this class in root-context.xml?
Thanks.
You should probably use Spring Boot (i.e. use File->New->Spring Starter Project and select Web as a starter. Place your web resources under src/main/resources/static folder. They are picked up automatically from that folder.
You should try an example project: File -> New -> Import Spring Getting Started Content and then pick "Serving Web Content" from the list.
Try some DB getting started content example to get the answer for the second part of your question.