Hi All,
Thanks to everyone who keeps answering my questions on the forum. The
support is excellent.
My current question is how to serve binary content i.e. a file out through
my RESTful services.
I have managed to accept a file through my REST implementation with the
following method (it uses apache.commons upload) which is a nice combo in my
view (particularly streaming capabilities).
@POST
@Path("user/{userId}/artifacts/{artifactId}/content")
@Consumes("multipart/form-data")
//_at_Consumes("multipart/mixed")
public void setArtifactBinaryContent(@PathParam("userId") long userId
, @PathParam("artifactId") long
artifactId
, @javax.ws.rs.core.Context
HttpServletRequest request)
throws Exception {
// First write the file to disk
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List items = null;
try {
items = upload.parseRequest(request);
Iterator iter = items.iterator();
while (iter.hasNext()) {
FileItem item = (FileItem)iter.next();
if (!item.isFormField()) {
File fileLocator = new File("/fileshare/filedata/" +
artifactId + ".dat");
item.write(fileLocator);
}
}
// Assuming success we now update the link and set to
enabled
dA.updateArtifactLink(0, userId, artifactId,
"/fileshare/filedata/" + artifactId + ".dat");
dA.updateArtifactEnabled(0, userId, artifactId, true);
}
catch (Exception e) {
e.printStackTrace();
}
}
This works a treat... The problem I am having is now serving the file. I am
trying the following:
@GET
@Path("user/{userId}/artifacts/{artifactId}/content")
@Produces("application/octet-stream")
public void getArtifactBinaryContent(@PathParam("userId") long userId
, @PathParam("artifactId") long
artifactId
, @javax.ws.rs.core.Context
HttpServletResponse response)
throws Exception {
try {
// Get an internal representation of an artifact
InternalArtifact ia = dA.getInternalArtifact(0, userId,
artifactId);
// Get the file from disk
File f = new File(ia.getLink());
int fLength = (int)f.length();
// Set the response header header
response.setContentType("application/octet-stream");
response.setContentLength(fLength);
response.setHeader( "Content-Disposition", "attachment;
filename=\"" + artifactId + "\"" );
ServletOutputStream sos = response.getOutputStream();
// Output the file stream
byte[] bbuf = new byte[100];
DataInputStream in = new DataInputStream(new
FileInputStream(f));
int length = 0;
while ((in != null) && ((length = in.read(bbuf)) != -1))
{
sos.write(bbuf,0,length);
}
in.close();
sos.flush();
sos.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
When deploying it moans with the following error:
SEVERE: Servlet /ACMERest threw load() exception
com.sun.jersey.api.container.ContainerException: Method, public void
com.acme.rest.MainService.getArtifactBinaryContent(long,long,javax.servlet.http.HttpServletResponse)
throws java.lang.Exception, annotated with GET of resource, class
com.acme.rest.MainService, is not recognized as valid Java method annotated
with @HttpMethod.
Does anyone know what the issue is here. Is it incorrect to be using
@Context to access the HttpServletResponse object?
Is there another way to serve a file perhaps?
Thanks,
James