Reputation: 4057
I have a JAX-RS REST web app that is used to store and retrieve files for a desktop client. I will be deploying this in two different environments on two different servers, so I would like the path where the files will be stored to be configured outside of the code.
I know how to read initialization parameters (in web.xml) from a Servlet. Can I do something similar for a REST resource class? If I could read from some other file inside the WEB-INF directory, that should work fine too.
Here is the code I'm working with:
import javax.ws.rs.*;
import java.io.*;
@Path("/upload")
public class UploadSchedule {
static String path = "/home/proctor/data/schoolData/";
//I would like to store the path value in web.xml
@PUT
@Path("/pxml/{id}/")
@Consumes("text/xml") @Produces("text/plain")
public String receiveSchedule(@PathParam("id") final Integer schoolID, String content) {
if (saveFile(schoolID, "schedule.pxml", content))
return schoolID + " saved assignment schedule."
else
return "Error writing schedule. ("+content.length()+" Bytes)";
}
/**
* Receives and stores the CSV file faculty list. The location on the server
* is not directly associated with the request URI.
* @param schoolID
* @param content
* @return a String confirmation message.
*/
@POST
@Path("/faculty/{id}/")
@Consumes("text/plain") @Produces("text/plain")
public String receiveFaculty(@PathParam("id") final Integer schoolID, String content) {
if (saveFile(schoolID, "faculty.csv", content))
return schoolID + " saved faculty.";
else
return "Error writing faculty file.(" +content.length()+ " Bytes)";
}
//more methods like these
/**
* Saves content sent from the user to the specified filename.
* The directory is determined by the static field in this class and
* by the school id.
* @param id SchoolID
* @param filename location to save content
*/
private boolean saveFile(int id, String filename, String content) {
File saveDirectory = (new File(path + id));
if (!saveDirectory.exists()) {
//create the directory since it isn't there yet.
if (!saveDirectory.mkdir())
return false;
}
File saveFile = new File(saveDirectory, filename);
try(FileWriter writer = new FileWriter(saveFile)) {
writer.write(content);
return true;
} catch (IOException ioe) {
return false;
}
}
}
Upvotes: 0
Views: 3450
Reputation: 4057
While obtaining init parameters from web.xml seems like a common task, it took me quite some time to get to the bottom of this and find a solution that worked. To save others from my frustration, let me post my solution. I am using the Jersey implementation, namely
com.sun.jersey.spi.container.servlet.ServletContainer
Perhaps other REST implementations can access web.xml init params using ServletContext
but in spite of documentation leading me to believe this would work, it did not.
I needed to use the following instead: @Context ResourceConfig context;
This is listed as one of the fields in my Resource class. Then within one of my resource methods, I was able to access the web.xml init parameter with the following:
String uploadDirectory = (String) context.getProperty("dataStoragePath");
Where the property refers to the web.xml file :
<init-param>
<param-name>dataStoragePath</param-name>
<param-value>C:/ztestServer</param-value>
</init-param>
Surprisingly, when I used @Context ServletContext context;
I discovered that the context object really referenced an ApplicationContextFacade. I could see no way to get through that Facade and access the information I cared about. I printed out the parameter map and it showed me that the only parameters this object was aware of:
java.util.Enumeration<String> params = context.getInitParameterNames();
while(params.hasMoreElements())
System.out.println(params.nextElement());
output:
com.sun.faces.forceLoadConfiguration
com.sun.faces.validateXml
Upvotes: 3
Reputation: 5184
First you have to get the servlet context using
@Context
ServletContext context;
Then inside your rest resource
context.getInitParameter("praram-name")
Upvotes: 0