Auto reloading properties file after updating it in Spring. How to achieve this? - spring

Instead of restarting the sever every time i make any change i want my properties file to be auto refreshed. My properties file in the src/main/resources

You can use the Actuator, basically you put your configuration beans inside a refresh scope :
#SpringBootApplication
public class ExampleServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ExampleServiceApplication.class, args);
}
#RestController
#RefreshScope
class ExampleController {
#Value("${foo.bar}")
private String value;
#RequestMapping
public String sayValue() {
return value;
}
}
}
Then when you change the configuration. you call the refresh endpoint for the actuator.
curl -X POST http://localhost:8080/refresh

Related

Issue loading external properties(which is added to classpath) in springboot

I need to load the application properties externally into my Springboot application. In my production system; we are adding the properties to classpath; so to replicate that I am adding the properties file to my class path and trying to load the properties using the #PropertyResource in SpringBoot but it is not loading
Using eclipse; I have added the properties file to my classpath(added the file to buildpath)
With Springboot and using #PropertyResource; the application is failing to load the properties.
#SpringbootApplication
#PropertySource(ignoreResourceNotFoind=true,value="classpath:myapp.properties")
public class MyApp {
public static void main(String[] args) {
springApplication.run(MyApp.class,args);
}
}
#Service
public class myService{
#Value("${name}")
private String name;
private void printName() {
System.out.println(" Name:"+name);
}
}
In order for #PropertySource to work you have to configure a PropertySourcesPlaceholderConfigurer. Add this to your MyApp class:
#Bean
public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfig() {
return new PropertySourcesPlaceholderConfigurer();
}
Also of note - ignoreResourceNotFoind is misspelled in your example (foind -> found)

Spring Boot url mappings order for controllers and static pages

I have a Spring Boot web application which is meant to serve both static and controller based (ModelAndView) pages. Problem is that a controller can serve something like /{string} and a static page must be served with /test.
The problem is that the controller mapping takes precedence, and I need to avoid that. If the user hits /test, he must be forwarded to the test.html static page.
I tried to use the order property of ViewControllerRegistry in this way, with no success:
#Configuration
public class MyWebMvcConfig extends WebMvcConfigurerAdapter {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/test").setViewName("forward:/test.html");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE); // but I tried with 0 and -1 as well: annotated controllers should have order equals to 0
}
}
This is my SpringBootApplication class:
#SpringBootApplication
public class VipApplication {
public static void main(String[] args) {
SpringApplication.run(VipApplication.class, args);
}
}
And this is the controller code:
#Controller
public class VipController {
#RequestMapping(value = "/{string}")
public ModelAndView vip(#PathVariable("string") String string) {
ModelAndView mv = new ModelAndView("mypage");
return mv;
}
}
How can I reorder the mappings to make sure static pages are considered before annotated controllers?
(I'm not sure, but) I suggest to override WebMvcConfigurerAdapter.addResourceHandlers() method and configure order of resource handler by invoking ResourceHandlerRegistry.setOrder()

Spring Boot not using application.properties for spring.groovy.template.cache

I have a very simple Spring Boot application with classes detailed below.
My problem is with the application.properties file and how they get auto-configured. I'm trying to get Groovy Templates to update in dev by setting 'spring.groovy.template.cache: false', however this is not working. I added two more properties to see if the application.properties file was being read. The 'logging.level.org.springframework.web: ERROR' still results in INFO level messages printed to the console. However, some.prop is read correctly into the MyBean class on application start.
Is there a configuration declaration I'm missing for these properties?
src/main/resources/application.properties:
spring.groovy.template.cache: false
logging.level.org.springframework.web: ERROR
some.prop: bob
src/main/java/sample/MyBean.java:
#Component
public class MyBean {
#Value("${some.prop}")
private String prop;
public MyBean() {}
#PostConstruct
public void init() {
System.out.println("================== " + prop + "================== ");
}
}
and src/main/java/sample/Application.java:
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
and src/main/java/sample/com/example/MainController.java
#Controller
public class MainController {
#RequestMapping(value="/login", method = RequestMethod.GET)
public ModelAndView risk(#RequestParam Optional<String> error) {
return new ModelAndView("views/login", "error", error);
}
}
It seems you missing scanned your package "sample". Please make sure that you have scanned it.
#ComponentScan({
"sample" })
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Also, your application.properties is right. No problem with it.
It appears the solution was much simpler than I thought:
gradle bootRun
should be used to hot reload templates
gradle run does not work (all compiled classes are just built in build/ )

How to configure Spring Data REST to return the representation of the resource created for a POST request?

I am following the spring-data-rest guide Accessing JPA Data with REST. When I http post a new record it is inserted (and the response is a 201). That is great, but is there a way to configure the REST MVC code to return the newly created object? I'd rather not have to send a search request to find the new instance.
You don't have to search for the created entity. As the HTTP spec suggests, POST requests returning a status code of 201 Created are supposed to contain a Location header which contains the URI of the resource just created.
Thus all you need to do is effectively issuing a GET request to that particular URI. Spring Data REST also has two methods on RepositoryRestConfiguration.setReturnBodyOnCreate(…) and ….setReturnBodyOnUpdate(…) which you can use to configure the framework to immediately return the representation of the resource just created.
Example with Spring Boot:
#Configuration
#EnableMongoRepositories
#Import(RepositoryRestMvcConfiguration.class)
#EnableAutoConfiguration
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext ctx = SpringApplication.run(Application.class, args);
RepositoryRestConfiguration restConfiguration = ctx.getBean(RepositoryRestConfiguration.class);
restConfiguration.setReturnBodyOnCreate(true);
}
}
or
#Configuration
#EnableMongoRepositories
#EnableAutoConfiguration
public class Application extends RepositoryRestMvcConfiguration {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Override
protected void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
super.configureRepositoryRestConfiguration(config);
config.setReturnBodyOnCreate(true);
}
}
Good Luck!
If you are using Spring Boot, you can add the following lines to your application.properties file for POST (create) and PUT (update) respectively
spring.data.rest.return-body-on-create=true
spring.data.rest.return-body-on-update=true
Here's another variant that uses DI rather than extending RepositoryRestMvcConfiguration or using the ConfigurableApplicationContext.
#SpringBootApplication
#EnableConfigurationProperties
#Configuration
#ComponentScan
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Autowired private RepositoryRestConfiguration repositoryRestConfiguration;
#PostConstruct
public void exposeIds() {
this.repositoryRestConfiguration.setReturnBodyForPutAndPost(true);
}
}

META-INF/resources not works properly with #EnableWebMVC in Spring Boot

1.
I'm working with Spring Boot. My Main class very simple
#ComponentScan
#EnableAutoConfiguration
#Configuration
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
#2. Now I would like to make my static content externalised into a jar file. So, below is the jar project
/pom.xml
/src/main/resources/META-INF/resources/hello.json // here is my resource
I do maven install and put the dependency into the main app, run the app normally. Now I can invoke http://localhost:8080/hello.json to get my hello.json file
#3. Then, the next step is using the Apache Tiles for my main web project, so I create a #EnableWebMvc class to configure the tilesViewResolver
#Configuration
#EnableWebMvc
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
public #Bean TilesViewResolver tilesViewResolver() {
return new TilesViewResolver();
}
public #Bean TilesConfigurer tilesConfigurer() {
TilesConfigurer ret = new TilesConfigurer();
ret.setDefinitions(new String[] { "classpath:tiles.xml" });
return ret;
}
}
Then I started again the application and try the hello.json to ensure everything still works properly. But, the 404 page appear. Delete the WebMvcConfiguration give back my hello.json.
What configuration I should do to resolve this issue?
Thanks a lot.
In Spring MVC, using XML configuration, you have to have a tag like the following to service static content:
<mvc:resources mapping="/js/**" location="/js/"/>
This insinuates that Spring Boot is doing something to automatically guess that you have static content and properly setup the above example in META-INF/resources. It's not really "magic", but rather that they have a default Java Configuration using #EnableWebMvc that has some pretty reliable default values.
When you provide your own #EnableWebMvc, my guess is you are over-writting their "default" one. In order to add back a resource handler, you would do something like this:
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/js/**").addResourceLocations("/js/").setCachePeriod(31556926);
}
This is equivalent to the XML above.

Resources