Closed confile closed 10 years ago
+1 I am interested in this answer too
Sorry I nave no access to code now. However I've got uploads working simply following Jersey 1.x tutorials
Could you post some code how to get the CommonsMultipartFile?
Here is one way of doing it:
@POST
@Path('/upload')
Response upload(InputStream data) {
StringBuffer content = new StringBuffer()
// Max file size allowed (32 MiB).
int limit = (32 * 1024 * 1024)
// The current number of bytes read.
int current = 0
// The buffer (reads in chunks of 8 KiB).
char[] chunk = new char[(8 * 1024)]
// Number of bytes to project to detect limit breach.
int byteProjection
// Reader.
Reader reader = new BufferedReader(new InputStreamReader(data, "UTF-8"))
// Read from data.
while ((byteProjection = reader.read(chunk)) != -1) {
// If we project that this read has breached the limit, reject.
if (current + byteProjection > limit) {
// throw bad request here
}
content.append(chunk, 0, byteProjection)
current += byteProjection
}
// what ever...
grreat thank you
Closing the issue if an answer was provided
yes thank you
I tried to Upload a file using the following resource:
@POST
@Produces('application/json')
UploadDto upload(
@Context HttpServletRequest request,
@QueryParam("cookie") String cookie) {
def contentType
byte [] fileBytes
log.debug "upload - cookie: "+cookie
try{
if (request instanceof MultipartHttpServletRequest) {
log.debug "request instanceof MultipartHttpServletRequest"
MultipartHttpServletRequest myrequest = request
CommonsMultipartFile file = (CommonsMultipartFile) myrequest.getFile('file')
fileBytes = file.bytes
contentType = file.contentType
log.debug ">>>>> upload size of the file in byte: "+ file.size
}
else if (request instanceof SecurityContextHolderAwareRequestWrapper) {
log.debug "request instanceof SecurityContextHolderAwareRequestWrapper"
SecurityContextHolderAwareRequestWrapper myrequest = request
//get uploaded file's inputStream
InputStream inputStream = myrequest.inputStream
fileBytes = IOUtils.toByteArray(inputStream);
contentType = myrequest.getHeader("Content-Type")
log.debug ">>>>> upload size of the file in byte: "+ fileBytes.size()
}
else {
log.error "request is not a MultipartHttpServletRequest or SecurityContextHolderAwareRequestWrapper"
println "request: "+request.class
}
}
catch (IOException e) {
log.error("upload() failed to save file error: ", e)
}
}
When I use the code in my Grails Controller it worked well but when I use it in a REST Resource I always get: request is not a MultipartHttpServletRequest or SecurityContextHolderAwareRequestWrapper
The send a file blob from JavaScript I use XMLHttpRequest which contains the blob in the body and some query parameters.
Did I miss something?
@confile usually the following is enough for my needs
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadMyFile(
@FormDataParam('file') InputStream fileInputStream,
@FormDataParam('file') FormDataContentDisposition contentDispositionHeader
...){...}
I've never tried sending the file as a blob in the body of a XHR. Maybe the plugin controller is consuming the request, returning an instance of another type, btw you missed to tell us the actual request type.
The request type is POST. How do I get query parameter from the request?
Here is how I send the file from JavaScript. I use this to make sending possible cross devices:
var str2ab_blobreader = function(str, callback) {
var blob;
BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder
|| window.BlobBuilder;
if (typeof (BlobBuilder) !== 'undefined') {
var bb = new BlobBuilder();
bb.append(str);
blob = bb.getBlob();
} else {
blob = new Blob([ str ]);
}
var f = new FileReader();
f.onload = function(e) {
callback(e.target.result)
}
f.readAsArrayBuffer(blob);
}
var fileName = "fileName.jpg";
var contentType = "image/jpeg";
if (file.type.toString().toLowerCase().indexOf("png") > -1) {
fileName = "fileName.png";
contentType = "image/png";
}
var xhrNativeObject = new XMLHttpRequest();
xhrNativeObject.open("post", url, true);
xhrNativeObject.setRequestHeader("Content-Type", contentType);
xhrNativeObject.onload = function(event) {
var targetResponse = event.currentTarget;
if ((targetResponse.readyState == 4)
&& (targetResponse.status == 200)) {
var obj = JSON.parse(targetResponse.responseText);
console.log(obj.uploadImageId);
} else {
console.log("fail");
}
}
var buffer = str2ab_blobreader(file, function(buf) {
xhrNativeObject.send(buf);
});
About the request type, I was asking which value you got from println "request: "+request.class
?
About accessing a query param: you already did it declaring a param on the resource method and annotating it with @QueryParam
(i.e. @QueryParam("cookie") String cookie
)
The result of println "request: "+request.class is
request: com.sun.proxy.$Proxy58
Do you have any idea how to fix this?
@davidecavestro Do you have any idea how to fix this?
The request instance is proxied with a jdk proxy, hence instanceof logic fails. That's one of the reasons why it should ben avoided using instanceof when possible. I'd proceed declaring a stream param as I suggested above then accessing the query params through the context
@davidecavestro FormDataParam is not part of javax.ws.rs did you mean FormParam?
@davidecavestro Which resources do I have to import to use FormDataParam?
I meant FormDataParam
available from jersey-multipart.
I tried to use compile 'com.sun.jersey.contribs:jersey-multipart:1.18.2'
When I use this:
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadMyFile(
@FormDataParam('file') InputStream fileInputStream,
@FormDataParam('file') FormDataContentDisposition contentDispositionHeader
...){...}
I get the following error:
2014-12-04 10:46:54,084 [localhost-startStop-1] ERROR [localhost].[/buddyis] - Exception sending context initialized event to listener instance of class org.grails.jaxrs.web.JaxrsListener
Message: tried to access method com.sun.jersey.core.reflection.ReflectionHelper.getContextClassLoader()Ljava/lang/ClassLoader; from class com.sun.jersey.spi.scanning.AnnotationScannerListener
Line | Method
->> 92 | <init> in com.sun.jersey.spi.scanning.AnnotationScannerListener
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 59 | <init> in com.sun.jersey.spi.scanning.PathProviderScannerListener
| 79 | init . . . . . . . . in com.sun.jersey.api.core.ScanningResourceConfig
| 104 | init in com.sun.jersey.api.core.PackagesResourceConfig
| 78 | <init> . . . . . . . in ''
| 89 | <init> in ''
| 696 | createResourceConfig in com.sun.jersey.spi.container.servlet.WebComponent
| 674 | createResourceConfig in ''
| 203 | init . . . . . . . . in ''
| 374 | init in com.sun.jersey.spi.container.servlet.ServletContainer
| 557 | init . . . . . . . . in ''
| 51 | init in org.grails.jaxrs.web.JerseyServlet
| 175 | init . . . . . . . . in org.grails.jaxrs.web.JaxrsContext
| 165 | init in ''
| 45 | contextInitialized . in org.grails.jaxrs.web.JaxrsListener
| 262 | run in java.util.concurrent.FutureTask
| 1145 | runWorker . . . . . in java.util.concurrent.ThreadPoolExecutor
| 615 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 745 | run . . . . . . . . in java.lang.Thread
Error |
2014-12-04 10:46:54,111 [localhost-startStop-1] ERROR core.StandardContext - Error listenerStart
Error |
Do you have any idea how to fix it?
Hi @confile , did you find solution? I am stuck here too ...
No
Does this plugin also support FileUpload with REST?
I an normal Grails controler action you would do something like this:
How to I do fileupload in a rest resource to get the CommonsMultipartFile?