Access to WEB-INF in a Java REST WebService - java

I'm creating a Java REST WebService which obtains data from a local SQLite database allocated in WEB-INF/data directory (This design is a requirement).
The problem is that I can not reach the WEB-INF directory.
I think I need to get the absolute path but I don't know how. I'm not able to get the Application context to get the app root path.
I'm using jdbc to connect the database:
conn = DriverManager.getConnection("jdbc:sqlite:" + dbPath);
So I need to assign a value to dbPath variable.
How to get the absolute path in a Java Rest WebService??

If I get your answer well, try to use:
getServletContext().getRealPath("/WEB-INF/data/filename");
Or
getServletContext().getResourceAsStream(...);

Related

apache tomcat creating new instance of sqlite database in java

I am using an sqlite database in java using xerial sqlite jdbc driver in order to store some data, 1 connection at a time.
It worked fine until I decided to use Apache tomcat on my server instead of java sockets (used for testing) and I noticed my queries yielded null results despite data being on the database.
I searched this issue and apparently tomcat creates a new instance of this database, which has the same tables but has no data.
I tried moving my database into the resource folder but this did not help.
public static Connection getConn() throws SQLException {
if(c == null){
c = DriverManager.getConnection("jdbc:sqlite:database.db");
}
return c;
}
this is how the code connects to the database. I believe moving the database and changing the address should solve the issue but I dont know where to.
thanks!
You should be able to use the full path to your existing database file in your JDBC URL - so, something like:
"jdbc:sqlite:/path/to/your/mysqlite.db"
If you are on Windows, then it might look like this:
"jdbc:sqlite:C:/path/to/your/mysqlite.db"
These are examples of absolute paths.
In your case, the database location in your JDBC URL is simply mysqlite.db, with no additional path information. This is a relative path, because it does not start with a slash or a drive letter.
This means the location of the DB file is relative to the working directory of the Java program (where the program was started). In the case of Tomcat, that is typically the CATALINA_HOME/bin directory - where CATALINA_HOME is typically the location where Tomcat was installed. (This may vary depending on how Tomcat was installed and launched.)
I would recommend you keep the database file in a separate location from Tomcat.
(SQLite will create a new, empty database in the specified location, if one does not already exist - so it's not Tomcat which is creating it, but rather the SQLite driver).

Java DB path for GitHub distribution

I have a project assignment in which I have to create a Java application. The program must be uploaded to my GitHub repository so my professor can see it and interact with it.
I have the following problem: For the purposes of the application I have to use a database. I decided to work with a Java Derby embedded database. So here an example of my code where I connect with the database:
String Table_click = (jTable1.getModel().getValueAt(row, 0).toString());
Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
java.sql.Connection con=DriverManager.getConnection("jdbc:derby:C:\\Users\\themi\\OneDrive\\Desktop\\HRCompanion\\databases\\Login", "root", "1234");
As you can see, my database is stored inside the project folder on my computer. But if I upload this code to GitHub, then my professor will not be able to run the application properly, as the database path does not exist. Is there a way to change the path to make the application work properly to a different computer?
You can use a relative path in your JDBC Connection URL.
So, for example, jdbc:derby:db means that Derby will look for the database in the db folder in the current directory.
Then you won't have such a problem with system-specific pathnames.

How to store the data within java application?

I am using H2 database which is embedded in my java application. I'm creating the connection to the server as:
jdbc:h2:file:/mydata
Where mydata is the database name. This seemed to tell the database connection caller to find the database within the same directory as of the application running from. But it cant find it on client computers. Why? What to do? Where to save the database so as to I don't lose data when I distribute my application?
According to documentation you do not need / before mydata you you need to look up for a file in the same directory
The database URL for connecting to a local database is jdbc:h2:[file:][path]. The prefix file: is optional. If no or only a relative path is used, then the current working directory is used as a starting point. The case sensitivity of the path and database name depend on the operating system, however it is recommended to use lowercase letters only. The database name must be at least three characters long (a limitation of File.createTempFile).
http://www.h2database.com/html/features.html#embedded_databases
So in your example you are trying to connect to file named mydata in the root folder. Looks like you forgot a dot (.) before /mydata. Try with the following jdbc:h2:file:./mydata

Best way to access a sqlite database file in a web service

First question from me on stack overflow.
I have created a java web application containing a web service using netbeans (I hope a web application were the correct choice). I use the web application as is with no extra frameworks. This web service use a sqlite JDBC driver for accessing a sqlite database file.
My problem is that the file path end up incorrect when I try to form the JDBC connection string. Also, the working directory is different when deploying and when running JUnit tests. I read somewhere about including the file as a resource, but examples of this were nowhere to be seen.
In any case, what is the best way to open the sqlite database, both when the web service is deployed and when I test it "locally"?
I don't know much about web services, I just need it to work, so please, help me with the technicalities.
Update
To put this a litle bit in context, some "println" code gives this:
Printing the work directory from a simple JUnit test gives
C:\MinaFiler\Work\SOA\BusTimetableWS
Invoking a similar web servic method returns
C:\Program Files\sges-v3\glassfish\domains\domain1
The connection string is formed from prepending "jdbc:sqlite:" to the path which at the moment is absolute:
C:\MinaFiler\Work\SOA\BusTimetableWS\src\java\miun\bustimetable\database\sqlit\BusTimetableWS.db
However, this fails because my tests throws exceptions stating database tables doesn't exist although they really do, I can see them with sqlite3.exe .
One way would be to use a config file that you can read and fetch your connection string from there.
I'm sure the framework you are using has some kind of standard way of saving configurations.
Another option would be to place the db in a known relative path from your main execution files. Then when executed fetch your current directory, and look for the db from that path.
In any case, what is the best way to open the sqlite database, both when the web service is deployed and when I test it "locally"?
The web service should use a DataSource to retrieve a connection from a connection pool configured at the application server level. In your unit test, use whatever you want (a standalone connection pool, a direct JDBC connection).
But in both cases, why don't you use an absolute path to the database file in your jdbc url? From How to Specify Database Files:
jdbc:sqlite:C:/work/mydatabase.db
The working directory wouldn't matter if you do so.

How to store a file on a server(web container) through a Java EE web application?

I have developed a Java EE web application. This application allows a user to upload a file with the help of a browser. Once the user has uploaded his file, this application first stores the uploaded file on the server (on which it is running) and then processes it.
At present, I am storing the file on the server as follows:
try {
// formFile represents the uploaded file
FormFile formFile = programForm.getTheFile();
String path = getServlet().getServletContext().getRealPath("") + "/"
+ formFile.getFileName();
System.out.println(path);
file = new File(path);
outputStream = new FileOutputStream(file);
outputStream.write(formFile.getFileData());
}
where, the formFile represents the uploaded file.
Now, the problem is that it is running fine on some servers but on some servers the getServlet().getServletContext().getRealPath("") is returning null so the final path that I am getting is null/filename and the file doesn't store on the server.
When I checked the API for ServletContext.getRealPath() method, I found the following:
public java.lang.String getRealPath(java.lang.String path)
Returns a String containing the real path for a given virtual path. For example, the path "/index.html" returns the absolute file path on the server's filesystem would be served by a request for "http://host/contextPath/index.html", where contextPath is the context path of this ServletContext.
The real path returned will be in a form appropriate to the computer and operating system on which the servlet container is running, including the proper path separators. This method returns null if the servlet container cannot translate the virtual path to a real path for any reason (such as when the content is being made available from a .war archive).
So, Is there any other way by which I can store files on those servers also which is returning null for getServlet().getServletContext().getRealPath("")
By spec, the only "real" path you are guaranteed to get form a servlet container is a temp directory.
You can get that via the ServletContext.gerAttribute("javax.servlet.context.tempdir"). However, these files are not visible to the web context (i.e. you can not publish a simple URL to deliver those files), and the files are not guaranteed in any way to survive a web app or server restart.
If you simply need a place to store a working file for a short time, then this will work fine for you.
If you really need a directory, you can make it a configuration parameter (either an environment variable, a Java property (i.e. java -Dyour.file.here=/tmp/files ...), a context parameter set in the web.xml, a configuration parameter stored in your database via a web form, etc.). Then it's up to the deployer to set up this directory for you.
However, if you need to actually later serve up that file, you will either need a container specific mechanism to "mount" external directories in to your web app (Glassfish as "alternate doc roots", others have similar concepts), or you will need to write a servlet/filter to serve up file store outside of your web app. This FileServlet is quite complete, and as you can see, creating your own, while not difficult, isn't trivial to do it right.
Edit:
The basic gist is the same, but rather than using "getRealPath", simply use "getInitParameter".
So:
String filePath = getServletContext().getInitParameter("storedFilePath") + "/" + fileName;
And be on your way.
Edit again:
As for the contents of the path, I'd give it an absolute path. Otherwise, you would need to KNOW where the app server sets its default path to during exeuction, and each app server may well use different directories. For example, I believe the working directory for Glassfish is the config directory of the running domain. Not a particularly obvious choice.
So, use an absolute path, most definitely. That way you KNOW where the files will go, and you can control the access permissions at the OS level for that directory, if that's necessary.
Writing to the file system from a Java EE container is not really recommended, especially if you need to process the written data:
it is not transactional
it harms the portability (what if you are in a clustered environment)
it requires to setup external parameters for the target location
If this is an option, I would store the files in database or use a JCR repository (like Jackrabbit).

Categories

Resources