Web App with Spring - Using properties in Service - java

I want to load few values from a proporties files that is in the /WEB-INF/ folder.
I usually use this in my xml file when I develop a software using WebServices
<util:properties id="configProperties" location="classpath:/WEB-INF/config.properties" />
and then access to the value in Java using:
#Value("#{configProperties['clientURL']}")
private String clientURL;
public String urlClient() {
return clientURL;
}
But it doesn't work on my webapp, it's always returning the null value.

WEB-INF is not on the classpath. The classpath starts from WEB-INF/classes/. So I would advise to place the properties file there (and change the location property accordingly). The service layer should not know that it serves a web application (which has WEB-INF)

I found the solution to my problem here:
http://codingbone.wordpress.com/2010/02/28/how-to-load-properties-files-into-spring-and-expose-to-the-java-classes/

Related

How to pass deployment dependant parameters to webapp

In projects I work(ed) on, deployment parameters - such as storage path or DB login - are usually given through a parameter file, which is stored in the war file.
I find that unsuitable because those values needs to be changed each time the webapp is packaged for a different deployment (dev vs prod, change of executing computer). The source code being versioned, this makes it even more bothering.
Is there some better option to pass parameters such as listed above?
By better, I mean:
practical: simple to setup, change and explain to others
separated from the war
as independent as possible to the web container (if dependent, I'm using tomcat in prod)
Edit
I chose the answer of #aksappy to reward the work done in the answer and because it provided several methods using standard tools. However, depending on the context I could go for any other solutions:
method of #Necreaux has best simplicity
method of #Luiggi Mendoza has a good design and is still simple
method of #OldCurmudgeon would be a really good one if the code covered other cases.
You can use a multitude of things based on your environment. Here are somethings which may be considered
Use datasources
The datasources defined in the server context removes the hard wired dependency of managing db configurations and connection pool from the web application. In Tomcat, this can be done as below in the context.xml
<Context>
...
<Resource name="jdbc/EmployeeDB" auth="Container"
type="javax.sql.DataSource"
description="Employees Database for HR Applications"/>
</Context>
Use Contexts
You can configure named values that will be made visible to the web application as environment entry resources, by nesting entries inside this element. For example, you can create an environment entry like this: (Source here). This can be set as context parameters or environment entries. They are equivalent to the entries made in a web.xml or a properties file except that they are available from the server's context.
Use database configurations and load those configuration at ServletContextListener
Another approach which I tend to follow is to create a relational schema of properties in a database. Instead of loading the properties file during server startup, load the properties from the database during start up.
public class ContextInitialize implements ServletContextListener {
private static Properties props;
public void contextInitialized(ServletContextEvent servletContextEvent) {
// connect to DB
// Load all the key values pairs as required
//put this into a Properties object, or create a hashtable, hashmap ..
}
//Getter
public String getProperty(String key){
// get value of key
}
//Setter
public void setProperty(String key, String value){
// set value to a key
}
}
Note: above is just an example.
Use environment variables or classpath variables
Use classpath / path variables in Environment variables and use System.getenv() in your java code to get these values as necessary.
We normally put our web app properties files in the Tomcat home folder. POJOS look on the launch folder. There will be other standard locations for other web servers.
final String tomcatHome = System.getProperty("catalina.home");
if (tomcatHome == null) {
// POJOs look in "."
searchPaths.add(".");
} else {
searchPaths.add(tomcatHome);
webApp = true;
}
An strategy is to pack all the properties and configuration files in an external jar and make this jar a dependency for your application(s): war, ear, etc. Then, you can deploy this jar in a common folder where the application server will load it and make it available for all the applications deployed there. This means that you will deploy the jar with the values for each environment once (or every time you need to change it, but its changes must be slow compared to the changes made to your main artifacts) and you can deploy and redeploy your war or any other project in your application server without problems.
In case of Tomcat, you may deploy this jar inside %CATALINA_HOME%/lib as explained in Tomcat Tutorial. Class Loader Definitions
To consume (read) these files in my application, I just load them like any other resource in my application.
Two strategies I've used:
JVM Parameters -- Custom JVM parameters can be set by the container at startup. This can get a bit verbose though if you have a lot of settings.
Configuration Files -- These can be read by the application. Either the location is hardcoded, put inside the container path, or to get the best of both worlds, specify the location via a JVM parameter.

Get the CATALINA_BASE property from inside a Java Web Service

Dear fellow Developers,
I am working on improving my Java Web Services, and I am trying to use a more delicate way of getting the directory path of properties files in a Java Web Service.
In order to make my Java Web Application easier to be deployed on an Apache Tomcat Server, I add the following line to the web.xml file:
<env-entry>
<env-entry-name>loggerPropertyFile</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>/Some/Long/Directory/File/Path/Which/May/Change/conf/LoggerInfo.properties</env-entry-value>
</env-entry>
As the above xml code depicts, I have placed a Properties file somewhere in the local Filesystem, and I want my Web Service to initialize its logger class, based on that configuration. As you can realize this path changes every time I deploy my web service to another server.
Thus, I figured out that I may be able to use the $CATALINA_BASE property, in order to make the environment entry path smaller. How can I retrieve the CATALINA_BASE value from inside my Java Web Service's Code (how is done on Linux and how is done on Windows)??
Thank you.
try System.getProperty("catalina.base");

Working with properties files outside war with Spring

I am working on a Spring 3.0.5 web application that accesses LDAP and two databases. I have a properties with configuration information for the LDAP server and that databases, in applicationContext-security.xml and dispatcher-servlet.xml, but I would like to make it so each server can have different data properties without changing a file in the WAR. Can I somehow put a file somewhere else on the server and still access it from within my application?
Add this to your context
<context:property-placeholder location="${envfile}"/>
This will load the properties file located at ${envfile}, a variable you can set with Java's startup paramater like this
-Denvfile="file:/var/server/environment.properties"
Or maybe in Tomcat's startup script
CATALINA_OPTS=" -Denvfile=file:/var/server/environment.properties"
Values can be retrieved in your controllers using Springs Value annotation like this:
#Values("${myvalue}")
private String myValue;
Please note that these features require Spring 3.1, more information here
Good luck!
Try
<util:properties id="props" location="file:///path/to/server.properties"/>

Accessing filesystem from java within Spring and tomcat

I am attempting to do some xml marshalling from with spring/tomcat ... my app is deployed as normal as a war file. The file is indeed copied to the correct location WEB-INF/classes/myData.xml but I am unsure how to access this from with Java and specifically my spring service layer. As normally I access files from with the app context itself.
I want to do this :
final File xml = new File("WEB-INF/classes/myData.xml");
but in my dev build it goes to F:\eclipse\WEB-INF\classes\myData.xml and not the deployment directory inside tomcat
In Spring, a clean way to do this with Java is using ClasspathResource:
Resource myData = new ClasspathResource("myData.xml"):
Alternatively, if this is a Spring bean doing the work, then you can inject it from XML, e.g.
<property name="myResource" value="classpath:myData.xml"/>
... assuming that myResource is a javabean property on your Spring bean of type Resource.
The WEB-INF/classes directory is automatically on the server's classpath, you don't need to (not should you) specify that in the path explicitly.
The Spring Resource interface offers various ways to get hold of the data itself (e.g. getInputStream())
If you are determined to get the path leading to your resource, you can retrieve its URL and then parse it, like this:
URL url = getClass().getResource("/WEB-INF/web.xml");
String path = url.toString();
if (path.startsWith("file:/")) {
path = path.substring("file:/".length());
File file = new File(path);
...do something with the file...
}
There is, however, a caveat: your resource may be read directly from the JAR archive, not from a flat file in your filesystem, and thus not really accessible via a File object. The above snipped worked in JBoss (which includes Tomcat), but JBoss explodes a WAR archive before deploying it - not sure if a pure Tomcat will do this as well.
The main question is: why would you really want to get the resource in the form of a File object? Maybe getting its URL is enough for you? Or maybe you just need read access?
If all you need is read access, the simplest way to get any resource on your classpath (like the above web.xml) is by simply calling:
InputStream in = getClass().getResourceAsStream("/WEB-INF/web.xml")
If you want write access to the file, a much better solution would be to pre-configure a directory (for example, via the web.xml), unpack all your needed files there (for example, via the above getResourceAsStream method) and then edit and access them from your predefined directory which is independent from your application server.

Passing parameters to AXIS web service

I have an AXIS servlet which deployed on an apache tomcat server on windows.
I wrote a web service which I want to run on AXIS.
When I want to deploy my web service, I make a jar file from the classes, and then I copy them to "axis\WEB-INF\lib" directory. Then I deploy the web service using a wsdd file.
My question is - how can I pass parameters to the web service, and how can I read them?
The only web.xml file that I have, is the AXIS web.xml file. Should I put them there?
I came across with exactly same issue. I have a not so perfect solution. I am using a properties file to store params and access this properties file in the service classes. I am facing problem when I put all my classes in to a jar file. I am able to access properties file in my service class if I place properties file inside the jar file. I am unable to access properties file (without hardcoding the path) when I place it outside jar file. For maintainance point of view it is good practice to keep properties file accessible easyly.
-Rao

Categories

Resources