Reputation: 135
I am working on a small RESTFul-project with Maven and Tomcat. Inside my implementation I have to read a txt file. Currently I am testing the implementation in Eclipse. When using the absolute path I can execute my code without any problem. Since I have to generate a war file, I need to encapsulate the txt file in it. Using Maven and
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
my war file contains the txt file stored in the highest level. What is your recommendation to read from that txt file inside the war file? I have found several threads here, but all tries failed. I need a specification where I can read the file when testing in Eclipse and when executing it directly in Tomcat.
This code doesn't work when executing the implementation in Eclipse as the text file is not found. The file is in the WebContent folder and after genereting the snapshot/war, you find the file in the war-file.
InputStreamFactory isf = new InputStreamFactory() {
public InputStream createInputStream() throws IOException {
return new FileInputStream("/text_de.txt");
}
};
I also tried the following when executing the implementation in Eclipse without access (I know, that would lead to an error when executing the war file):
return new FileInputStream("/WebContent/text_de.txt");
UPDATE:
Now I can execute the implementation within Eclipse with success. I first tried it with the annotation @Resource, but changed to @Context
@Context
ServletContext servletContext;
Then, I added this row:
String fileLocation = System.getProperty("com.example.resourceLocation",servletContext.getRealPath("/text_de.txt"));
Thanks
Upvotes: 1
Views: 920
Reputation: 54
I am not sure if this helps in your case, but could you, using the HttpServletRequest request
from your doGet() (doPost(), or one of the others), try:
return new FileInputStream(request.getServletContext().getRealPath("/text_de.txt"));
If you extract your .war file using an unzip program, you can determine the path needed, if "/text_de.txt" might not be correct, but a lot of times the contents of /WebContent/ ends up in the root of the .war file...
Hopes this helps,
note: The HttpServletRequest it self has a method with the same name, but that one is deprecated, so you'll know it the wrong one.
after discussion in the comments:
You need a different location during development,
find the file: tomcat/conf/catalina.properties of the instance of tomcat that is actually running. I am not sure if Eclipse is running this, or you point Eclipse to a tomcat-home folder
add a line like com.example.resourceLocation=/full/path/to/eclipse/project/text_de.txt
than use something like:
String fileLocation = System.getProperty(
"com.example.resourceLocation",
request.getServletContext().getRealPath("/text_de.txt"));
//this second parameter is a default value you can provide yourself
//if the property does not exists it chooses the second as return value
in response to the non-servlet question:
I am using Jersey link, here I use something like this
@Context
private HttpServletRequest httpRequest;
@GET
@Path("file")
@Produces(MediaType.APPLICATION_JSON)
public Response getFile () {
String fileLocation = System.getProperty(
"com.example.resourceLocation",
this.httpRequest.getServletContext().getRealPath("/text_de.txt"));
//this second parameter is a default value you can provide yourself
//if the property does not exists it chooses the second as return value
// do something with fileLocation
FileInputStream fi = new FileInputStream(fileLocation);
return Response.status(Response.Status.OK)
.entity("body")
.build();
}
within the class where the responding @POST or @GET etc. functions are located
a few years back in a SOAP service I used a servlet filter and retrieved the request object from the doFilter() function,
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
this.context = request.getServletContext( );
Eclipse can create Filters using the context-menu of your project...
in both cases you have the servletRequest object or servletContext object, so you can fit that into the file reader location solution
kind regards
Upvotes: 2