Hello
I am trying to build a reusable class to handle all of my file IO. The first step in this process is building the path to files. I got the code to work running in the servlet but when I break the code out into utility classes, the code no longer works.
Here is the utility class where I am building the path to an attachment.
import java.io.File;
import javax.servlet.http.HttpServlet;
public class FileIO extends HttpServlet
{
/**
* Returns the path within the context of the web site
* @param path
* @return
*/
public static String buildPath( String path )
{
FileIO fio = new FileIO();
String basePath = fio.getContextOfServlet();
return basePath + "//" + path;
}
public String getContextOfServlet()
{
System.out.println( "context = " + getServletContext().getRealPath( "/" ) );
return getServletContext().getRealPath( "/" ).toString();
}
}
If I use this code from the Servlet like below, I get a null pointer exception on getServletContext().getRealPath( “/” ).
System.out.println( "path = " + FileIO.buildPath( attachmentPath ) );
Why am I getting a null pointer exception?
If I run this code from the servlet, everything runs fine.
System.out.println( "test = " + getServletContext().getRealPath( "/" ) );
Any help would be appreciated.
Servlets are more than the normal Java Classes. They need a webContainer to execute and the output of some of the methods are purely dependent on the Web Container. Same happens with the “getServletContext().getRealPath()”, if this method is executed within the WebContainer than it would return the path but if outside it (same as what you did) it will return Null values.
In order to use this outside the servlet, than from the servlet itself set the “path” in a session object or a request object.
Thank you for the response. I was trying to keep all code needed for the FileIO in one class but since this does not seem possible since I would have to send the servlet path for the check, this FileIO class is probably not worth the effort.
You can still do this…
Just make the FileIO as a normal java class and invoke its methods from another Servlet.
By a normal class do you mean not static?
write all of your FILE operations in a normal java class and call this java class from the Servlet.
I am not trying to be difficult here, but I am not getting this.
If I run this code, everything works.
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
{
boolean exists = ( new File( getServletContext().getRealPath( "/" ) + "test.txt").exists() );
if( exists )
{
System.out.println( "exists" );
}
else
{
System.out.println( "Does not exist" );
}
}
My goal here is to make a reusable FileIO class. So I am trying to add reusable parts. Based on your suggestion, these are all normal classes. Below is the code that is made reusable. The problem is when I call the getServletContext().getRealPath( “/” ), I get a NullPointerException.
Here is the code…
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
{
FileIO fio = new FileIO();
if( fio.fileExists( "test.txt" ) )
{
System.out.println( "exists" );
}
else
{
System.out.println( "Does not exist" );
}
}
public class FileIO extends HttpServlet
{
/**
* Returns boolean value telling if the file exists
* @param relative path to file
* @return boolean indicator
*/
public boolean fileExists( String path )
{
System.out.println( "path = " + getContextOfServlet() + path );
return ( new File( getContextOfServlet() + path ) ).exists();
}
public String getContextOfServlet()
{
try
{
System.out.println( "context = " + getServletContext().getRealPath( "/" ) );
}
catch( Throwable t)
{
System.out.println( "t = " + t );
}
return getServletContext().getRealPath( "/" ).toString();
}
}
Would it be too much to ask for you to post a working example of how I could make this file existence check in a reusable way? I am obviously having a problem getting it to work.
Thanks.
When Tomcat starts a context (an HttpServlet child instance), it gives the instance the information it needs to respond to certain questions, such as getServletContext.
By simply extending HttpServlet with your FileIO class, you are not providing this information. You would have to transfer the information from the Servlet, to your FileIO class, at which point, you really have to wonder if that’s what you want. (what does being a servlet have to do with File IO?)
A reusable File IO class should know nothing about servlets, this includes knowing nothing about how to retrieve a servlet context path (which, when I put it that way, seems to be awfully specialized information, does it not? Therefore: not something one would find in a properly generalized class)
What sumit has been saying, if I’m not mistaken, is that you need to have only file IO related actions and information in your general file IO class - this will not include ‘how to get the context path of a servlet’.
Have your FileIO accept the result of the getContextPath query as a method parameter, not generate it!
Thank you for the feedback. Here is my implementation based on the suggestions.
FileIO fio = new FileIO( getServletContext().getRealPath( "/" ) );
if( fio.fileExists( "attachments/test.tx" ) )
{
System.out.println( "exists" );
}
else
{
System.out.println( "Does not exist" );
}
Here is the class.
import java.io.File;
import javax.servlet.http.HttpServlet;
public class FileIO extends HttpServlet
{
private String servletContext = "";
/**
* Constructor
*/
public FileIO( String servletContext )
{
this.servletContext = servletContext;
}
/**
* Returns boolean value telling if the file exists
* @param relative path to file
* @return boolean indicator
*/
public boolean fileExists( String path )
{
System.out.println( "path = " + servletContext + path );
return ( new File( servletContext + path ) ).exists();
}
}