grails controller handling ajax file upload - grails

I am implementing a file uplaod via jquery ajax but I fail to do something with the data on the controller side. I get the params but not the File which is in this example a jpeg. The data is in the Request Payload.
My problem is on server side. How do I get a File on server side?
#Secured(['ROLE_USER', 'ROLE_ADMIN', 'ROLE_PARTNER', 'ROLE_READ_ONLY', 'ROLE_USER_PAYING'])
def fileupload () {
println "---------------------------------------------------"
params.each{
println it.key +"="+ it.value
}
request.getHeaderNames().each{
println (it)
}
render("OK")
}
This is the output i receive:
---------------------------------------------------
filename=1506368_10152113826431683_327028558_o.jpg
apiKey=c7937acaf6d5411d8920d194dc48c041
action=fileupload
controller=post
host
connection
content-length
...
How do I get the file in my controller?

I'm doing the same, and using request.getInputStream() in the controller for getting the binary data. This actually comes from the ServletRequest interface - see http://docs.oracle.com/javaee/7/api/javax/servlet/ServletRequest.html#getInputStream--

Related

How to test 404 json response on ZF2

Considering that in my Zend Framework module I'm able to access via browser or REST. When I got a 404 via REST, this is the content:
{"httpStatus":404,"title":"Not Found"}
So how do I test this response using PHPUnit?
I have already a test for another route that is working:
public function testIndexActionCanBeAccessed()
{
$this->dispatch('/ws/dashboard');
$this->assertResponseStatusCode(200);
$this->assertModuleName('Ws');
$this->assertControllerName('Ws\Controller\Dashboard');
$this->assertControllerClass('DashboardController');
$this->assertMatchedRouteName('application/ws');
}
But I don't know how to do this other case.
public function testIndexActionCanBeAccessed()
{
$this->dispatch('/ws/asd');
$this->assertResponseStatusCode(404); // this is OK
// but how check the json response?
}
Also, if I do this $response = $this->getResponse(); I got the entire HTML 404 html file, which is not what I want.
You may want to check to ensure that the controller is actually returning a JSON response.
Also, your Accept header for the AJAX request should specify application/json.

Http resource request method and Grails server

I'm building a controller which delivers image from Linux file system. And I need to force request http method.
on gsp side I have something like :
<div style="background-image: url('${createLink(controller: 'customServing', action:'imageserv', params: [param1: 'foo'])}');"></div>
controller side is :
static allowedMethods = [index: 'GET',
imageserv: ['POST']]
the action look like:
def imageserv = {
ByteArrayOutputStream baos=new ByteArrayOutputStream()
ImageIO.write(originalImage, "png", baos )
ImageIO.write(ImageIO.read(new File(whateverPic)),'png',baos)
byte[] imageAsByte = baos.toByteArray()
response.setHeader('Content-length', imageAsByte.length.toString())
response.contentType = 'image/png'
response.outputStream << imageAsByte
response.outputStream.flush()
}
The web browser will automatically issue a request to get the background
image: Remote Address:[::1]:8080
Request URL:http://localhost:8080/customServing/imageserv?param1=foo
Request Method:GET
I would have used Ajax or classic javascript to format my request, but I can't because of conception needs. (so it also implies grails remote link, or html form manually fired submit event are not valid option)
Is there any way to indicate (client side or server side) browser to issue only POST request for page resource rendering?
edit: I do have total control over context environment (Cent OS 7, Tomcat 8)

Proxying MultiPart form requests in Grails

I have a Grails controller that receives a DefaultMultipartHttpServletRequest like so:
def myController() {
DefaultMultipartHttpServletRequest proxyRequest = (DefaultMultipartHttpServletRequest) request
}
This controller acts as a proxy by taking pieces of this request and then resends the request to another destination.
For non-multipart requests, this worked fine, I did something like:
IProxyService service = (IProxyService) clientFactory.create()
Response response = service.doPOST(proxyRequest.getRequestBody())
Where proxyRequest.getRequestBody() contains a JSON block containing the request payload.
However, I do not know how to get this to work with multipart request payload, since the request body is no longer a simple block of JSON, but something like the following (taken from Chrome devtools):
How can I can pass this request payload through using my proxy service above, where doPost takes a String?
Have you tried
def parameterValue = request.getParameter("parameterName")
to get the parameter value?
If you see the method signatures for DefaultMultipartHttpServletRequest you will see there are methods for getting the files and other parameters separately because the request body is getting used to both upload the file and to pass in other parameters.

$httpProvider interceptor how to read all headers

I have an interceptor using $httpProvider as follwos (taken from Angular doc)
$httpProvider.interceptors.push(function ($q) {
return {
'response': function (response) {
// look for the antiforgerytoken and update dataService with the same.
return response || $q.when(response);
}
};
});
using the debugger I see that this method is called on each response and when I look at the 'response' object pased I see only one header, namely the Accept-Header as shown below
When I look at the response packet in the chrome I see many more headers
My question is why am I not able to see all the headers in the response?
Specifically I want to read the cookie for AntiforgeryToken and store it, how can I do that?
I believe the cookie AntiforgeryToken is a HttpOnly cookie and cannot be accessed from javascript. Can you check
See some details here http://blog.codinghorror.com/protecting-your-cookies-httponly/
Such cookies are mean for server exclusively.

XML file generation to user specified location

I am generating a xml file using JAXB but at present file is generated at specified location,How can i use a browse button to specify the location of folder to save the generated file.
Have tried with input type="file" of HTML but it is useful for uploading the file.Want it to do from rich faces only.
Just write it directly to the HTTP response along with a Content-Disposition header with a value of attachment. This will force the browser to pop a Save As dialogue.
So, essentially all you need to do is to marshal the XML tree straight to the output stream of the HTTP response instead of the output stream of the file after having set the proper headers.
FacesContext fc = FacesContext.getCurrentInstance();
ExternalContext ec = fc.getExternalContext();
// ...
ec.responseReset(); // Make sure the response is clean and crisp.
ec.setResponseContentType("text/xml"); // Tell browser which application to associate with obtained response.
ec.setResponseCharacterEncoding("UTF-8"); // Tell browser how to decode the characters in obtanied response.
ec.setResponseHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\""); // Tell browser to pop "Save As" dialogue to save obtained response on disk.
marshaller.marshal(model, ec.getResponseOutputStream()); // Look ma, just marshal JAXB model straight to the response body!
fc.responseComplete(); // Tell JSF that we've already handled the response ourselves so that it doesn't need to navigate.
Note: downloading a file via ajax is not possible. Remember to turn off the ajax feature of the RichFaces/Ajax4jsf command component invoking this method, if any.
See also:
How to provide a file download from a JSF backing bean?

Resources