How to change thymeleaf static content default path in spring boot - spring-boot

I want to change CSS and JS default path from the resource to something else for thymeleaf.
I am using JSP as a view instead of thymeleaf but for email template, I decided to go with thymeleaf, in every search I saw spring boot by default looks into resource /static folder is there any way to force spring boot to look into another folder outside resource.

If you have multiple resource folder you can add those in your classpath by extending WebMvcConfigurerAdapter class like below. have a try
#Configuration
#EnableWebMvc
#ComponentScan
public class WebConfig extends WebMvcConfigurerAdapter {
public ResourceBundleMessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
String[] strBaseNames = {
"ca.gc.myproject.global.myResources", //full class path of your folder
"ca.gc.myproject.user.yourResources",
};
return messageSource;
}
}
source :https://spring.io/blog/2013/12/19/serving-static-web-content-with-spring-boot

Related

SpringBoot does not resolve #Value properties without PropertySource annotation

I have a bunch of #Value annotated fields in a SpringBoot configuration file, with the matching values in the standard application.properties . If I don't annotate the configuration file with #PropertySource("classpath:application.properties") it will just copy the "${prop1}" string into the actual variable.
I tried adding #EnableAutoConfiguration to the #Configuration class (instead of the PropertySource annotation), but all it does is to break when a requested property is not found.
SpringBoot is supposed to resolve the properties automatically from the standard application.properties file, why this behaviour? Using version 2.2.2.RELEASE
Update:
The answers are correct, the reason it was not working was that I was calling these properties in a test. Annotating the test with #SpringBootTest fixes the issue. In fact when the application is running it is #SpringBootApplication that does the magic
As you can read in this article (chapter 5), SpringBoot manage automatically the application.properties file.
I don't know if this is your problem because I've not seen the code, but in Spring Boot the Application class should be annotated with #SpringBootApplication.
#SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
Take a look at this starting example.
You can then inject the value for example in a controller class in this way:
#RestController
public class HelloController {
#Value("${test}")
private String test;
#RequestMapping("/test")
String hello() {
return test;
}
}

application.properties not read with #EnableAutoConfiguration and custom spring boot starter

I try to create a simple custom spring boot starter that read property in application.properties :
#EnableConfigurationProperties({ CustomStarterProperties.class })
#Configuration
public class CustomStarterAutoConfiguration {
#Autowired
private CustomStarterProperties properties;
#Bean
public String customStarterMessage() {
return properties.getMessage();
}
}
with its ConfigurationProperties :
#ConfigurationProperties(prefix = "custom.starter")
public class CustomStarterProperties {
private String message;
/* getter and setter */
...
}
There is also the corresponding application.properties and META-INF/spring.factories to enable the autoconfiguration.
I have another project that declares this starter as a dependency and in which I write a test to see if the customStarterMessage Bean is created :
#RunWith(SpringRunner.class)
#EnableAutoConfiguration
public class TotoTest {
#Autowired
String customStarterMessage;
#Test
public void loadContext() {
assertThat(customStarterMessage).isNotNull();
}
}
This test fails (even with the appropriate application.properties file in the project) because the application.properties seems to not be read.
It works well with a #SpringBootTest annotation instead of the #EnableAutoConfiguration but I would like to understand why EnableAutoConfiguration is not using my application.properties file whereas from my understanding all the Spring AutoConfiguration are based on properties.
Thanks
#EnableAutoConfiguration on test classes don't prepare required test context for you.
Whereas #SpringBootTest does default test context setup for you based on default specification like scanning from root package, loading from default resources. To load from custom packages which are not part of root package hierarchy, loading from custom resource directories you have define that even in test context configuration. All your configurations will be automatically done in your actual starter project based on #EnableAutoConfiguration you defined.

#EnableAutoConfiguration annotation with class prameter is not initializing properties object

i have following #CongfigurationProperties class
//#Component
#ConfigurationProperties
#PropertySource("classpath:typesofcharge.properties")
public class ChargeProperties {
private HashMap<String,String> charge=new HashMap<>();
public HashMap<String,String> getCharge()
{
return this.charge;
}
}
And this is my Configuration file
#SpringBootApplication
#ComponentScan({"com.vehiclemanagement.config,com.vehiclemanagement.client,"
+ "com.vehiclemanagement.controller,"
+ "com.vehiclemanagement.exception,"
+ "com.vehiclemanagement.model,"
+ "com.vehiclemanagement.service"})
#EnableConfigurationProperties(ChargeProperties.class)
public class VehicleManagementConfig {
public static void main(String[] args) {
SpringApplication.run(VehicleManagementConfig.class, args);
}
}
If i use #Component annotation in ChargeProperties and remove ChargeProperties.class annotation in Configuration class the charge HashMap is initialized properly
If i remove #Component and pass ChargeProperties.class as argument like this
#EnableConfigurationProperties(ChargeProperties.class) like how document says the charge HashMap is empty when i run
I am using spring boot 2.0.2 release .But i am following latest docs. Can anyone explain why this are not working as document suggest
content of property file is as follows
UPDATE the content of property files are as shown
#DO NOT MODIFY THIS FILE
charge.peak=Double_rate;
charge.lateNight=duration_based_charge;
charge.earlyMorning=special_offers;
When specifying ChargeProperies.class on the #EnableConfigurationProperties annotation it will be registered as a bean through the EnableConfigurationPropertiesImportSelector class inside #EnableConfigurationProperties.
So in the example, if you have only annotated the ChargeProperties class with #ConfigurationProperties it will create a chargeProperties bean with an empty charge HashMap because it defaulted back to application.properties as the source.
A custom source can be specified by using #PropertySource.
#PropertySource annotation providing a convenient and declarative mechanism for adding
a PropertySource to Spring's Environment. To be used in conjunction
with #Configuration classes.
As per documentation above, to use #PropertySource to load the custom source, one has to use the #Configuration annotation.
#Configuration
#PropertySource("classpath:typesofcharge.properties")
Under the hood a #Configuration class is a #Component.
#Target(value=TYPE)
#Retention(value=RUNTIME)
#Documented
#Component
public #interface Configuration
So to your question. By specifying a custom #PropertySource without #Configuration, spring did not load the properties in the #PropertySource annotation and defaulted back to the application.properties.
If we use #PropertySource we have to use component otherwise the properties will not be read
since we added the #ComponentScan We don't have to mention #EnableConfiguationProperties annotation at all The propety class object can be autowired as Bean

trigger component scan from a application for an included spring boot jar using extra annotations

I need to publish a Spring boot based jar which should be consumed in other Spring/Spring boot based applications.
In my reuse jar I have a class(BusinessConfig) annotated with #Configuration and it gives out two beans. This class is in the base package of the reuse jar.
#Configuration
public class BusinessConfig {
#Bean(name = "BusinessRepoManager")
public BusinessRepoManager businessRepoManager(){
return BusinessRepoManager.getInstance();
}
#Autowired
#Bean(name = "CustomerManager")
#Scope("request")
public CustomerManager customerManager(BusinessRepoManager busrepoManager){
return CustomerManager.getInstance();
}
}
In the second application, I have added the dependency and in the application class I have the statement
#ComponentScan(basePackageClasses = {BusinessConfig.class})
to inform Spring context to look for beans provided in BusinessConfig class as well.
This works well, as I could see the beans getting created.
Is there any possibility to simplify this, should all consuming applications know the class name in which my configuration exists/package name.
I tried creating a custom annotation in the jar project and used that in the consuming application.
#ComponentScan(basePackageClasses = {BusinessConfig.class})
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.TYPE)
#Component
public #interface EnableDemoBusiness {
}
Then in my consuming application I just added
#EnableDemoBusiness
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Is there any way to get this work ?
Thanks in advance !
You have a couple of options:
Option 1
You can turn your class into "auto-configuration", by creating a META-INF/spring.factories file in your jar with the following content:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.your.package.BusinessConfig
Now in applications using your jar if #EnableAutoConfiguration or #SpringBootApplication annotations are used, your configuration will be processed and the beans created.
You might want to annotate your configuration with some #ConditionalXXX annotations if required to give applications that use your jar more control.
Refer to the documentation for more information.
Options 2
You can create a custom #EnableXXX annotation like you attempted.
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.TYPE)
#Import(com.your.package.BusinessConfig.class)
public #interface EnableDemoBusiness {
}

How to get properties in JSP files using spring mvc 3

I am very new to spring mvc 3 annotation based application. I have two properties files -
WEB-INF\resources\general.properties,
WEB-INF\resources\jdbc_config.properties
Now I want to configure them through spring-servlet.xml. How I can achieve this?
In general.properties,
label.username = User Name:
label.password = Password:
label.address = Address:
...etc
jdbc_config.properties,
app.jdbc.driverClassName=com.mysql.jdbc.Driver
app.jdbc.url=jdbc:mysql://localhost:[port_number]/
app.jdbc.username=root
app.jdbc.password=pass
---etc
If I want to get label.username and app.jdbc.driverClassName in my jsp page, how do I code for them?
I also want to access these properties values from my service. How to get these property values using respective keys in method level in service class or controller class?
You need to distinguish between application properties (configuration) and localisation messages. Both use JAVA properties files, but they serve different purpose and are handled differently.
Note: I am using Java based Spring configuration in the examples bellow. The configuration can be easily made in XML as well. Just check Spring's JavaDoc and reference documentation.
Application Properties
Application properties should be loaded as property sources within your application context. This can be done via #PropertySource annotation on your #Configuration class:
#Configuration
#PropertySource("classpath:default-config.properties")
public class MyConfig {
#Bean
public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
Then you can inject properties using #Value annotation:
#Value("${my.config.property}")
private String myProperty;
Localisation Messages
Localisation messages is a little bit different story. Messages are loaded as resource bundles and a special resolution process is in place for getting correct translation message for a specified locale.
In Spring, these messages are handled by MessageSources. You can define your own for example via ReloadableResourceBundleMessageSource:
#Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename("/WEB-INF/messages/messages");
return messageSource;
}
You can access these messages from beans if you let Spring inject MessageSource:
#Autowired
private MessageSource messageSource;
public void myMethod() {
messageSource.getMessage("my.translation.code", null, LocaleContextHolder.getLocale());
}
And you can translate messages in your JSPs by using <spring:message> tag:
<spring:message code="my.translation.code" />
I ended up using Environment
Add these lines to config
#PropertySource("classpath:/configs/env.properties")
public class WebConfig extends WebMvcConfigurerAdapter{...}
You can get the properties from controller using autowired Environment
public class BaseController {
protected final Logger LOG = LoggerFactory.getLogger(this.getClass());
#Autowired
public Environment env;
#RequestMapping("/")
public String rootPage(ModelAndView modelAndView, HttpServletRequest request, HttpServletResponse response) {
LOG.debug(env.getProperty("download.path"));
return "main";
}
}
Firstly import spring tag lib:
<%# taglib prefix="security" uri="http://www.springframework.org/security/tags" %>
Than import property from your application.properties
<spring:eval var="registration_url" expression="#environment.getProperty('service.registration.url')"/>
Than use your variable
test

Resources