Reputation: 3076
I'll lay down my code first: Note: I also have log output at the bottom of the question.
Server Side:
@Post
@Consumes("application/octet-stream")
public Representation post(InputStream zip, @HeaderParam(value = "Content-Disposition") HttpHeaders headers) throws Throwable {
System.out.println(headers); //Prints null - want the header to not be null here
String uploadedFileLocation = getStartingDir() + "/" + "abc.zip";
writeToFile(zip, uploadedFileLocation);
return new StringRepresentation("Uploaded!");
}
Client Side:
public static void main(String[] args) throws Exception {
final String BASE_URI = "http://localhost:8080/server/upload";
Client client = Client.create();
WebResource service = client.resource(BASE_URI);
client.setChunkedEncodingSize(1024);
client.addFilter(new LoggingFilter());
File zip = new File("C:/Users/sdery/Desktop/abc.zip");
InputStream fileInStream = new FileInputStream(zip);
String sContentDisposition = "attachment; filename=\"" + zip.getName()+"\"";
ClientResponse response = service.header("Authorization", "Basic xxx=").header("Content-Disposition", (Object)sContentDisposition).type(MediaType.APPLICATION_OCTET_STREAM).post(ClientResponse.class, fileInStream);
System.out.println("Response Status : " + response.getEntity(String.class));
}
First off, the file transfer works, I'm happy. However, I would like to get the headers on the server side so I don't have to hard code the file name. Any ideas as to why it is comin' up null? Does it have to do with me using ClientResponse
instead of ClientRequest
?
Jul 31, 2013 8:44:12 AM com.sun.jersey.api.client.filter.LoggingFilter log
INFO: 1 * Client out-bound request
1 > POST http://localhost:8080/server/upload
1 > Content-Disposition: attachment; filename="abc.zip"
1 > Authorization: Basic xxx=
1 > Content-Type: application/octet-stream
(zip bytes)
INFO: 1 * Client in-bound response
1 < 200
1 < Date: Wed, 31 Jul 2013 12:44:12 GMT
1 < Date: Wed, 31 Jul 2013 12:44:12 GMT
1 < Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept
1 < Content-Length: 88
1 < Set-Cookie: rememberMe=deleteMe; Path=/server; Max-Age=0; Expires=Tue, 30-Jul-2013 12:44:12 GMT
1 < Content-Type: text/plain; charset=UTF-8
1 < Accept-Ranges: bytes
1 < Server: Restlet-Framework/2.0.4
1 < Real-Token: bar
1 <
Uploaded!
From the log output, it seems that the header containing Content-Disposition
is there. Does this mean I should be able to retrieve the value from the server side code?
Upvotes: 0
Views: 3515
Reputation: 3974
First off, I apologize that my solution is from a JavaScript/PHP reference and not Java, but I believe your solution may be similar.
Add a new header named 'X-FILENAME' and set the name of your file as the header data. I believe your code would look something like this:
ClientResponse response = service.header("X-FILENAME", "abc.zip");
Then, on your server, you should be able to retrieve that header param (In PHP it is the $_SERVER
global, it looks like in yours it may be @HeaderParam
).
Also, for reference just in case this applies to you, in PHP when you retrieve the header param you need to use a modified param name by adding 'HTTP_' to the front and changing all dashes to underscores like this 'HTTP_X_FILENAME'. So on the client you sent 'X-FILENAME' while on the server you retrieve that same value with 'HTTP_X_FILENAME'.
I hope this leads you in the right direction.
Upvotes: 0
Reputation: 2656
You're parameter is of the wrong type. You should declare the parameter as a String. HttpHeaders is for getting all the headers and is annotated with a @Context. @HttpParam can only be converted to a limited number of types.
From the Jersey documentation for HeaderParam.
Binds the value(s) of a HTTP header to a resource method parameter, resource class field, or resource class bean property. A default value can be specified using the DefaultValue annotation. The type T of the annotated parameter, field or property must either:
Be a primitive type
Have a constructor that accepts a single String argument
Have a static method named valueOf or fromString that accepts a single String argument (see, for example, Integer.valueOf(String))
Be List<T>, Set<T> or SortedSet<T>, where T satisfies 2 or 3 above. The resulting collection is read-only.
So you're code would be more like
@Post
@Consumes("application/octet-stream")
public Representation post(InputStream zip, @HeaderParam(value = "Content- Disposition") String contentDisposition) throws Throwable {
System.out.println(contentDisposition);
String uploadedFileLocation = getStartingDir() + "/" + "abc.zip";
writeToFile(zip, uploadedFileLocation);
return new StringRepresentation("Uploaded!");
}
Upvotes: 1