How to access folder which is outside war file? - java

I have application which is having lots of PDF files , when I try to build a war file of my application due to pdfs its size converts to Gbz , so basically I want to remove the pdf file folder from the application ,put it some location and then build a war file and deploy it to tomcat.so ,is there any way I can read folder from my application which is outside the war file?

You can use the File class to work with files and directories on the local file system.
For example if if your pdf files are in a folder called pdf you can create a File object like so
File pdfsFolder = new File("\pdfs");

You need to have a separe folder on your server to store the pdf. You pass this folder location to your application (for example using globaresouces in server.xml, so your production path and local path are coming from the server rather than hardcoded in your app.). You access the given folder normally from java (new File(dir), Paths.get...). If there is no SecurityManager you can access any part of the filesystem from within your webapp.
For example your aplication META-INF/context.xml
<Context>
<ResourceLink global="PDFPath" name="PDFPath" type="java.lang.String"/>
</Context>
Your tomcat, inside server.xml
<GlobalNamingResources>
<Environment name="PDFPath" value="D:\\Data\\PDFs" type="java.lang.String" override="false"/>
</GlobalNamingResources>
In your code:
Context initCtx = new InitialContext();
Context envCtx = (Context)initCtx.lookup("java:comp/env");
String storagePath = (String) getContext().lookup("PDFPath");
File pdfDir = new File(storagePath);

ya its correct way but give the Tomcat user permission to access the Pdf file , which is use to avoid the file listing when the time of directly url access Ex (www.yourSite.com/pdf/ex.pdf)

Related

How to set up Tomcat to use the config file in conf/Catalina/localhost?

so my question is how can I set up a Tomcat Server to use this configuration file conf/Catalina/localhost/MyApp.xml?
It works like a charm if my application is named like this: MyApp.war so tomcat will extract the archive to MyApp.
But I want to use a name with the version inside like MyApp##1.0-SNAPSHOT.war.
Is it possible to configure the tomcat so it will use the MyApp.xml anyway?
You can set path and docBase attributes of Context element as described in the docs.
Create a directory outside $CATALINA_HOME/webapps and place war files there, let's say /opt/tomcat/wars/. Then set docBaseattribute to the full path to your war. Make user tomcat user has read permissions on that directory. If war is inside webapps directory you could end up with a double deployment depending on deployOnStartup and autoDeploy attributes of Host element.
<Context path="/MyApp" docBase="/opt/tomcat/wars/MyApp##1.0-SNAPSHOT.war">
...
</Context>
You can try also naming the xml the same as the war file.

Spring MVC - referring an uploaded image

I have implemented an image uploading functionality. The problem is that I am saving these files outside an application (so that they won't be deleted in case of redeploy), and I don't really know how to refer them from a jsp file then, as I only know how to refer to the webapp (or resources) directory.
Have you tried adding to server.xml under $CATALINA_HOME/config/server.xml
<Context docBase="/usr/local/tomcat/folder/with/images" path="/uploads/img" />
For example:If you have foo.jpg inside the
/usr/local/tomcat/folder/with/images directory
then you can access the foo.jpg file via
localhost:8081/uploads/img/foo.jpg

access tomcat alias dir from java

In Tomcat7 there is an option to use aliases from the context like this:
<Context aliases="/up=/var/tomcat/upload"></Context>
With this I can access files from outside the webapp. Now, I want to write and read from this dir from my Java code, but do not know how to.
I can do this:
servletContext.getResourcePaths("/up/")
Which shows me the content of /var/tomcat/upload.
How can I write to this dir?
What I did with the excepted answer:
add this to context.xml:
<Context aliases="/up=/var/tomcat/upload">
<Valve className="org.apache.catalina.valves.RemoteAddrValve" allow=".*" />
<Parameter name="uploadDir" value="/var/tomcat/upload"/>
and this in my java code:
String uploadDir = servletContext.getInitParameter("uploadDir") + subDir;
OutputStream bos = new FileOutputStream(uploadDir + fileName);
And this works but I could use only the parameter and skip the aliases because for java it does not help. So I'm not quite sure what the idea behind the aliases. I thought it was for uploading files because after a redeploy this dir and content will not be overwritten. But if java can only access it with an extra parameter than it only can be used for serving static content which could be inside the webapp (inside the war).
You separately tell your Java code the path to your upload folder (/var/tomcat/upload) so it can read/write files there.
Example:
<Context aliases="/up=/var/tomcat/upload">
<Parameter name="uploadDir" value="/var/tomcat/upload"/>
</Context>
Your java code can get the parameter value by calling ServletContext.getInitParameter("uploadDir").

Read common external property file in Java Webapp and java normal app

I know this question has answered many a time with most useful answer as below,
Where to place and how to read configuration resource files in servlet based application?
However, We have some special requirement as below,
Webapp will be deployed to tomcat.
Normal java app in form of .jar will be placed under folder /myapp
myappConfig.property file will be placed under /myapp
Directory Structure on client machine
/myapp
/myapp.jar
/assests/myappConfig.property
/tomcat/webapps/myapp.war
Basically myapp.jar and myapp.war will access sql db connection values for MySql database connection and db operations.
Accessing myappConfig.property from myapp.jar --> Working fine
File jarPath = new File(Myapp.class.getProtectionDomain().getCodeSource().getLocation().getPath());
String propertiesPath = jarPath.getParent();
System.out.println(" propertiesPath-" + propertiesPath);
mainProperties.load(new FileInputStream(propertiesPath + "\\assets\\myapp.property"));
Can anyone help/suggest how to implement,
Accessing myappConfig.property file from mywebapp,
provided run time change in myappConfig.property file does not required myapp.war to be redeployed
Thanks for your help in advance.
edit
Below is the steps in which we want to deliver the project to client.
Below is my app directory
/myapp
/myapp.jar
/assests/myappConfig.property
/tomcat/webapps/myapp.war
pack everything in one package with some packaging tool.
Run this package in client machine at any location and it will have same directory structure as above
Here, I do not want to hard code any location in webapp or tomcat for "/assests/myappConfig.property"
Normal Java app I can read property file but for wepapp I am not getting clear idea for how to do that?
You can add a <context> to tomcat/conf/server.xml (in this example, linux path):
<Context docBase="/home/yourusername/tomcat/assests" path="/assets" />
If you are using Windows:
<Context docBase="C:\path\to\myapp\assets" path="/assets" />
And then you can access it like any other resource within your webapp (e.g.: /assets/myappConfig.property).
If you are using JDBC for example, you could store the connection properties in a Singleton and request it from there, and that class could take care of change checks on that file.

Creating A File Resource Using Tomcat JNDI

I need to read an application.properties file from a servlet application using Tomcat container. The file can not be included in my war so it can't be under webapps or Tomcat root folder in any ways. The file has to be somewhere in the folder. I also can not use FileInputStream to read the properties file. Only option I have is to define a JNDI name for a folder / directory and look that JNDI properties during runtime to find the folder location to read the file. Is thee any working example out there?
I have chalked out a solution for myself reading the following similar posts and articles.
The Context Container
Reading a global variable from tomcat with JNDI. Example not working
java:comp/env is not bound
I have defined a Environment inside my Context for my web application under
\conf\Catalina\localhost\mywebapp.xml as follows....
<Environment name="propertiesfilelocation" value="E:\\tmp\\application.properties"
type="java.lang.String" override="false"/>
Then accessed my properties file using a JNDI lookup to get the file name.
Context ctx = new InitialContext();
Context envCtx = (Context)ctx.lookup("java:comp/env");
String propertiesFileLocation = (String) envCtx.lookup("propertiesfilelocation");
LOGGER.info("String property === " + propertiesFileLocation);
properties.load(new FileInputStream(propertiesFileLocation));
#home : Yes you are right it involved FileInputStream. However, I am happy with the solution because I am no longer hard coding my folder location inside my Java code which makes my app more portable.
I have a slightly different approach to a similar problem. I also toyed with the idea of JNDI but I found this a bit of overkill.
I found another article by BalusC. It allows you to specify folder relative to your tomcat installation and deploy all your properties files there. So you keep configuration external to your application but you don't require seperate configuration for every properties file for every app.
Here it the link:
Where to place and how to read configuration resource files in servlet based application?
and the preferred choice is as follows:
Put it in the classpath, so that you can load it by
ClassLoader#getResourceAsStream() with a classpath-relative path:
Properties properties = new Properties();
properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("filename.properties"));
Here filename.properties is supposed to be placed in one of the roots
which are covered by the default classpath of a webapp, e.g.
webapp/WEB-INF/lib, webapp/WEB-INF/classes, appserver/lib or JRE/lib.
If the properties file is webapp-specific, best is to place it in
WEB-INF/classes. If you're developing a project in an IDE, you can
also drop it in src folder (the project's source folder).
You can alternatively also put it somewhere outside the default
classpath and add its path to the classpath of the appserver. In for
example Tomcat you can configure it as shared.loader property of
tomcat/conf/catalina.properties.
I hope this helps.
Allan

Categories

Resources