Reading from properties file in spring - java

I have a web application in which I'm using spring MVC. I have defined few constants in sample.properties file. spring-servlet is the servlet that gets initialized for all urls in my app. spring-servlet:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<context:property-placeholder location="classpath:sample.properties"/>
</beans>
In one of my java classes I access the value of one of the properties like this:
package com.sample;
import com.google.gson.JsonArray;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
#Component
public class Validator {
#Value("${credit}")
String credits;
private static final Logger LOG = Logger.getLogger(Validator.class);
public void checkRating() {
LOG.debug(credits);
}
}
sample.properties:
credit=[{"duration":15,"credit":10},{"duration":30,"credit":20}]
When Validator is called from a controller, it just logs it as ${credit} in my log file. I dont get its value. Similarly, if I put an integer / floating point number in the properties file, I get an error saying it cannot be cast into integer / float. Am I missing any configuration?

The reason for this is because propertyplaceholder configurer is a BeanFactoryPostProcessor and it processess only the beans defined in the context in which the propertyplaceholder is configured. In a web application typically there is a heirarchy of context as explained here. Hence you need to declare this at appropriate place.

Related

Invoke annotated aspect on all methods with a specific annotation

I have an application based on MVC and I want to log inputs/outputs from all my controllers.
Also, each of my controller methods is annotated with some specific annotation (eg: #MyControllerMethod).
I wrote an Annotated Aspect which works fine when I use the annotation (eg: LogRequestReply) from the aspect on my controller methods.
#Around("#annotation(com.xyz.LogRequestReply)")
public Object logRequestResponse(ProceedingJoinPoint pjp) throws Throwable {
#MyControllerMethod
#LogRequestReply /* It invokes my logRequestResponse method */
public ResponseEntity controllerMethodA(...) {}
However, I have a lot of controller methods and each with annotation MyControllerMethod.
Is there a way I can make my aspect annotation make work on all controller methods by default, such that each of the methods automatically calls my aspect logger and I can log the inputs/outputs?
Note:
I also looked into writing an interceptor extending from HandlerInterceptorAdapter. But it has its own complexity of being able to log request/response where the stream can only be read once.
Please suggest.
One option is to let the #Around definition less restrictive, add a restriction by package or something like that.
Internally you can check if this is a Controller by this check bellow and then print the request/response:
#Pointcut("within(com.mypackage.controller..*)")
private void inControllerPackage() {
}
#Around("inControllerPackage()")
public Object logRequestResponse(ProceedingJoinPoint pjp) throws Throwable {
if (pjp.getSignature().getDeclaringType().isAnnotationPresent(RestController.class)) {
...
}
Perhaps you should include the AOP in your controller-config
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:oxm="http://www.springframework.org/schema/oxm"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-4.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd">
<mvc:default-servlet-handler />
<context:component-scan base-package="com.xyz.controller" />
<aop:aspectj-autoproxy proxy-target-class="true" />
<bean id="whatever" class="com.xyz.controller.MyRestController"/>
</bean>
and in your Aspect you can also include the within combined with annotation:
#Around(value = "#within(com.xyz.server.annotation.MyAnnotationForController) || #annotation(com.xyz.server.annotation.MyAnnotationForController)")
public Object ownersTimeZone(ProceedingJoinPoint joinPoint) throws Throwable {
//whatever you need before
Object obj = joinPoint.proceed();
//whatever you need after
return obj;
}

Java : How to load content of .properties file into Properties using spring annotation?

I am using Java 8 on spring framework. I have a properties file which has "=" separated values in it. I am trying to load the values of the properties file into a Property directly using spring annotation.
For example :
my Application.properites has:
cat=250
dog=560
lama=1000
donkey=650
And I have declared this properties file in my context.xml as :
<util:properties id="app_props"
location="classpath*:/application.properties" />
Now in my main class I am trying to load all of the values in Application.properites into
private Properties properties;
So that properties.getProperty("cat") will return "250"
Not sure how to do it. May I get any help on that?
Register your properties file as follows
XML Config
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<context:property-placeholder location="classpath:foo.properties" />
</beans>
Java Config
#Configuration
#PropertySource("classpath:foo.properties")
public class PropertiesWithJavaConfig {
//...
}
Using your properties as follows
#Value( "${jdbc.url}" )
private String jdbcUrl;
You can find a complete working solution in my GitHub repository
https://github.com/mirmdasif/springmvc/tree/master/springproperties

Java Spring Scheduled job not working

I have a web application which is supposed to run a scheduled code:
package com.myproject.daemon.jobs;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
#Component
public class MyDaemonJob {
private static final Logger log = LoggerFactory.getLogger(MyDaemonJob.class);
#PostConstruct
public void init() {
log.info("MyDaemonJob is intialized " );
}
#Scheduled(fixedDelay = 1000)
public void startDaemon() {
try {
log.info("MyDaemonJob is running ...");
} catch (Exception e) {
log.error("Encountered error running scheduled job: " + e.getMessage());
}
}
}
It surely is recognized as a Spring bean and initialized, as I can see from the PostConstruct log. However the method with the #Scheduled annotation never runs although it is supposed to run every 1 second.
Here is app context xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<context:component-scan base-package="
com.myproject.daemon.jobs,
com.myproject.product" />
</beans>
Thank you ALL for quick help. This is really helpful.
The code started working, once I added config class with annotations as shown below --
package com.myproject;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
#Configuration
#EnableScheduling
public class AppConfig {
// various #Bean definitions
}
To use the #scheduled annotation it is necessary to include the spring task name space in spring bean configuration xml file. You can update the following namespac e in your xml configuration file.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-4.1.xsd">
Otherwise if you use the spring-boot application you can include the #EnableScheduling in your configuration file

spring java xml configuration

im using spring for my java web app. the site has got bigger and i would like to set some configurations.
i have been researching and came across things like document builder factory, replacing spring xml with java config and others. i dunno where to start.
im thinking of implementing the configurations in xml (WEB/newConfig.xml) and have it read by the java beans. basically i wanna input my cofiguration values into xml and have it load by a java bean so that i can use it in controllers and jstl.
im just giving some examples here. for example xml configurations:
<property name="numberOfCars" value="3" />
<property name="webSiteName" value="New Spring Web App" />
....
and i read it in my java class:
class Config {
public getNumberOfCars() {
return numOfCars;
}
public getWebSiteName() {
return webSiteName;
}
}
where should i start and what online materials can i read?
==============================
update
here is what i have created.
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<context:property-placeholder location="/WEB-INF/your_prop_file.properties" />
<bean id="ConfigMgr" class="org.domain.class.ConfigMgr">
<property name="username" value="${username}">
</bean>
</beans>
you_prop_file.properties
username=hello world name
ConfigMgr.java
public class ConfigMgr {
private String username;
...getter
...setter
}
in my controller, here is what i did:
ConfigMgr config = new ConfigMgr();
sysout.out.println(config.getUsername());
i am getting null and i am sure im missing something here. where should i set the username value to the ConfigMgr class?
Spring Java configuration is a newer feature that allows you to configure your Spring application using Java classes instead of XML files. Its just an alternative for XML configuration. XML way is equally feature rich.
From what I could figure out from your problem, you want to move the hardcoded values of params (numberOfCars,webSiteName.. ) outisde your configuration file.
If that is the case, you don't have to go that far.
Just use :-
<context:property-placeholder location="classpath:your_prop_file.properties" />
in your spring xml file and replace the param values like:-
<property name="webSiteName" value="${website.name}" />
You need to have a your_prop_file.properties file in your classpath with enteries like:-
website.name=New Spring Web App
You are not injecting the ConfigMgr bean that you created in XML file.
What you are doing is you are creating a new Object in controller which does not have a clue about properties file.
Now you can inject it using either #Autowired inside your controller or through xml configuration.
There are plenty of examples available in google on basic spring dependency injection.

Getting null value from applicationcontext.xml

I am working on struts2 application with spring for back end.
We are using database.properties file and the entries are as follows:
jdbc.url=jdbc:mysql://localhost:3306/myDb
jdbc.username=root
jdbc.password=rooooot
jdbc.csvlocation=C:\myCSV
I added the following new entry in database.properties
enhancePerf.Flag=true
In applicationcontext.xml I am fetching the value like this :-
<bean id="userLogin" scope="prototype"
class="com.hello.something.actions.UserLoginAction">
<property name="perfEnhance" value="${enhancePerf.Flag}"/>
</bean>
After declaring a global variable perfEnhance in UserLoginAction, and forming the setters and getters method of the same, I'm still not getting the value.
I followed the following link:-
http://www.roseindia.net/tutorial/spring/spring3/web/applicationcontext.xml-properties-file.html
Please advise.
Instead of your PropertyPlaceholderConfigurer bean, put:
<context:property-placeholder location="classpath:path/to/database.properties"
ignore-unresolvable="false"/>
This way if the property is not found, it will complain. Otherwise it seems that you may have another "database.properties" file in your classpath, that simply does not have such a property.
Make sure that "path/to/database.properties" is in your classpath. If database.properties itself is your class path, then no "path/to" is needed => just classpath:database.properties
You also have to configure Spring to manage your Actions as beans, using the ContextLoaderPlugin, as well as you have to use bean names in Struts config. If you have the following in your struts-config.xml file:
<action path="/users" .../>
You must define that Action's bean with the "/users" name in action-servlet.xml:
<bean name="/users" .../>
Please take a look at Spring Struts Integration from official Spring's docs.
EDIT to answer the comment:
context is an XML namespace that should be defined in the XML file where it is used:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">

Categories