Spring WebContent Resources - Access outside ServletContext - java

I have a Spring Web MVC application that I'd like to serve a large, partially generated file.
I've added that file to my WebContent directory and all works fine there. However, I'd also like to access that file from my various build/deploy scripts, which read and parse the file.
My current approach is to keep a copy of the file under the src directory as well as the WebContent directory. When serving the file from the web, it uses WebContent.
When serving the file for the build scripts, it uses the following spring config:
<bean id="ringCodeData" class="com.myapp.data.RingCodeData">
<property name="rulesInputFile" value="classpath:resources/rules_copy.xml" />
<!-- <property name="rulesInputFile" value="classpath:../WebContent/rules.xml" /> -->
<!-- <property name="rulesInputFile" value="file:/WebContent/rules.xml" /> -->
</bean>
As you can see, I've tried several different approaches to get the two to refer to the same file (without resorting to copies).
File paths don't seem to work since they're based on the current directory, that changes based on whether I call a given utility class from Eclipse or from the build scripts.
How can I get these to refer to the same file?
The only other thought I have at the moment is to try to setup Spring MVC to stream the file from the classpath directory.

Your best bet is likely placing it in /WEB-INF/classes (or, if you're using an IDE, just the project's src/source folder) and use <jsp:include> to include it.
<jsp:include page="/WEB-INF/classes/resources/rules_copy.xml" />

Related

Read properties file from included jar

I am trying to create Annotation parser that reads properties file. The structure looks like this:
- annotationParserModule
- declaration of interace
- annotationParser
now my app has structurelike this:
- main
- java
- resources
- .properties file
I am including annotationParserModule via maven, so if i a not mistaken, jar fire is inlcuded in my project.
However i need to read properties file outside of the jar provided by annotationParserModule, is somethig like that possible? If so, what is the right way to achieve this?
Thanks for help.
If the resource you want to read are included in the classpath of your application (eg. inside a jar, in the WEB-INF/lib folder, a folder passed with -cp to java command, etc..) you can read the file using the getResourceAsStream method of the Class class.
Providing an example for your case, having folders like:
- main
- java
- resources
- yourconfig.properties
In your YourAnnotationParser code you can have:
InputStream is = this.getClass().getClassLoader().getResourceAsStream("yourconfig.properties");
If the file is nested:
- main
- java
- resources
- iamafolder
- yourconfig.properties
So:
InputStream is = this.getClass().getClassLoader().getResourceAsStream("iamafolder/yourconfig.properties");
BTW this is a very simplistic response, the code works on common scenario, what it does behind the scenes is more complex than "read a file outside a jar", but to understand it fully you need to look for how the java class loader and the classpath work.
If the file is outside the java classpath you can use the File class or the URL one to read contents.
In you applicationcontext.xml you can add the bean to read the properties file from the jar
<bean id="com.mybean"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath:/resource.properties</value>
</list>
</property>
</bean>
and this id will be a reference to another bean
<bean id="com.mybean1">
class="com.dependent.jar.classname">
<property name="properties" ref="com.mybean" />
</bean>

How to load Spring beans xml configuration from different location in Debug and Release mode

I am using Spring and Hibernate with a non-web application. I am creating the sessionFactory bean in the /src/main/resources/Hibernate.xml
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
....login, password, etc
It is okay, but when I finish some changes I want to create an executable jar file and put it into another server where is different database located. The problem is that I have to open the jar file and change database configuration everytime I create that jar file to make it compatible with external database on the different server.
The solution for this problem would be to load Hibernate.xml from the outside of the jar file.
And here is the question - how to do that?
If all that is different between the two environments is the database address and credentials, I'd recommend putting those into a property file and using placeholders in your XML configuration (docs).
You can then either access the property file as classpath resource (In Spring config, use classpath: prefix for the file path) that you can configure at runtime, or let your build system copy a different version of the file into the JAR depending on target environment (in Maven, this can be done using Assembly plugin).
The solution was to add "file:" prefix.:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="file:config/hibernate.properties" />
</bean>

Spring Maven: Where to place credential properties

I'm currently developing an application which requires access to an API with credentials. I didn't want to put them hard coded in the application so I created a configuration.properties file for them.
At the moment this file is located in src/main/resources and access it with the following code.
<context:property-placeholder location="classpath:configuration.properties" ignore-unresolvable="true" />
This means that if I change something in the configuration I need to redeploy the WAR.
My question is: Where do I put this configuration file so that I don't need to redeploy in case of a change in the configuration?
I don't want to put it somewhere random on my computer so that I can share my code with other people without to much trouble with the file's location.
I solved it by placing my properties file in Tomcat "D:\Documents\workspace.metadata.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps"
And Access it with the following property-placeholder
<context:property-placeholder location="file:${catalina.base}/conf/configuration.properties" ignore-unresolvable="true" />
I think you're already close.
I agree its a good way to have one .war file and reuse it everywhere without adopting it to a specific environment. That means you cannot include it in the .war
What I would do is creating configuration zip files with the assembly plugin (if there are multiple variations). For example from /src/main/config/env1
Then use an environment variable to point to that folder.
The property placeholder configurer thing in spring then references that location through that system property instead of the classpath:
these zip files can be used to be deployed with the .war file (via ssh using the ant runner plugin or some other way)
That can also be used for the logging configuration. Spring has a resolver that will even reload the log config if you change it on the file system.

Trying to get mvc resources to serve my static resources

I'm developing locally using both jetty and tomcat.
My images, css, javascript files are in:
/src/main/webapp/assets
where the folder assets has:
/src/main/webapp//assets/images
/src/main/webapp//assets/css
/src/main/webapp//assets/images/
My spring config file has:
<mvc:resources mapping="/assets/**" location="/" />
I'm confused as to what both mapping and location mean?
I think mapping means that that spring will only try and serve the static files if it has the url with the pattern like:
www.example.com/assets/
What does location do?
My html currently has:
src="/assets/images/logo.gif"
I've tried playing with the location value, and I don't get to render the image for some reason.
Can someone clear this up for me?
If your project structure has /src/main/webapp/assets/images, then you want to use:
<mvc:resources mapping="/assets/**" location="/assets/" />
and then in your JSP reference files as
src="${pageContext.request.contextPath}/assets/images/logo.gif"
Its more common to have a project structure like /src/main/webapp/images|css|js and then use:
<mvc:resources mapping="/assets/**" location="/" />
but still keeping URLs as ${pageContext.request.contextPath}/assets/images/logo.gif

How to specify location of SQLite db file within Spring Maven WAR

I have seen several questions broaching this issue, but I haven't come across a clear answer.
I need to package a SQLite .db file into a WAR and work with that DB file within the WAR or exploded WAR.
My project is Spring, using Spring JDBC.
Everything works fine with the .db file in the classpath for testing of the non-web portion of the code. I can run unit tests against the database without problem using just
<bean id="datasource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="connectionInitSqls">
<list>
<value>PRAGMA foreign_keys = ON</value>
</list>
</property>
<property name="driverClassName" value="org.sqlite.JDBC" />
<property name="url" value="jdbc:sqlite:app2.db" />
</bean>
When I go to deploy, I'm able to pull the db into the WAR file only if I place it in the WebContent/resources directory. I can't seem to get this working with alternate URIs. (for example, jdbc:sqlite::resource:app2.db, jdbc:sqlite:WebContent:resources:app2.db, jdbc:sqlite:/resources/app2.db, etc.). I've seen answers suggesting that I tie it to tomcat's deployment directory location specifically, but I'd really rather not have the location be dependent on anything outside of the WAR.
Does anyone have a working example (using XML config for the datasource in Spring applicationContext) of a datasource mapping (includig jdbc URI string), and corresponding pom.xml maven-war-plugin specification (if applicable) to achieve the solution of letting the project work with a SQLite .db file stored with the project in its WAR?
Thanks in advance.
--EDIT (additional clarifying information in response to comments) --
I am able to get the .db into the classes subidirectory of the WAR via this directory (or through something in the WebApps subdirectory by a workaround resource mapping in the maven-war-plugin specification), but this is not the main problem.
My issue is: How do I reference the .db via relative URL/URI once it is within the WAR.
I need to point the jdbc driver to this location via a relative path so that it can be accessed regardless of deployment location.
I have options of absolute URL on the filesystem (I've gotten direct location on my computer to work with
or path within Tomcat, but again, by hard-coded URL, or best case, URL tied to CATALINA_BASE with
<property name="url" value="jdbc:sqlite:/var/lib/tomcat7/webapps/APPNAME/WEB-INF/classes/app2db.db" />
I've seen it suggested that I use
<property name="url" value="jdbc:sqlite:${catalina.base}/webapps/APPNAME/WEB-INF/classes/app2db.db" />
though this does not seem to work with my installation (and is still not an optimal solution, as it is tied to the surrounding deployment location).
jdbc:sqlite allows mapping of relative paths using no preceding forward slash, but I can't get this to work within the war with something like
<property name="url" value="jdbc:sqlite:WEB-INF/classes/app2db.db" />
This is what I'm looking for -- the relative path mapping such that I can send the .db off with the WAR and just tell someone to deploy to tomcat -- or any server, within reason, since I have the jars needed to execute mostly packaged up with the app through Maven --(even if their directory structure is unusual or they don't have path variables mapped), and have it still be able to access the database with rw access from within the exploded WAR.
When I go to deploy, I'm able to pull the db into the WAR file only if I place it in the WebContent/resources directory.
If I place my.db in Maven's default for resources <project>/src/main/resources/my.db it is packaged in /my.war/WEB-INF/classes/my.dbhere.

Categories