1

My grails 2.2.4 app needs to support accepting files over HTTP from a third party application and sending the file, after making some tweaks to it, back out as a response to the third party application.

I want to convert the data sent by the third party application to a file using InputStream and then send the file back out using OutputStream

So I built this code:

API Classes

class ApiResponse {
    ApiMeta meta
    ApiObject apiObj
}
class ApiMeta {
    int code
    String errorType
    List msgs = []
}
class ApiObject {
    OutputStream os
}

//Object Marshaller

    JSON.registerObjectMarshaller( ApiObject ) { ApiObject obj ->

            //How can I send output stream as json?
    }

Controller

//controller
def save() {
    request.withFormat {
        json {
            ApiResponse resp
            //How can I convert the JSON data in params to a file?

            response.status = 201
            resp = new ApiResponse(
                   meta: new ApiMeta(code: 201), 
                   apiObj: new ApiObject(os: transfers))

            render resp as JSON
        }
     multipartForm {
     }
  }

Question

  • How can I convert JSON payload sent by the third party service into a file?
  • Is it ok to put OutputStream in my ApiObject class so that I can send the JSON payload back to the service?
birdy
  • 9,286
  • 24
  • 107
  • 171

1 Answers1

0

My grails 2.2.4 app needs to support accepting InputStream over HTTP from a third party application and sending OutputStream as a response back.

That does not really make sense. Third party apps can't really send an InputStream to your app and your app can't really send an OutputStream back. The third party app can send you data in the body of the request and you can read the body by retrieving an InputStream from the request, and the same sort of thing could happen when you put data in the response. At first read I thought maybe you were just wording things in a way that doesn't make sense but then when I saw your domain class, that suggests that maybe you really are confused about how this works.

class Request {
    InputStream instream
    OutputStream outstream
    static constraints = {
        instream nullable: false, blank: false
    }
}

You can't do that. You cannot persist an InputStream or an OutputStream to the database.

EDIT:

If you have a controller like this:

class MyController {
    def someAction(Widget w) {
        // do whatever you need to do with the Widget
    }
}

class Widget {
    String name
    String category
}

And you send a request to that controller action with a JSON body which looks like this...

{"name":"Robert","category":"Prog Rocker"}

Grails will automatically read the body of the request and do the corresponding binding. You would never have to directly interact with any input stream to make that happen. Is that the sort of thing you are looking for?

Jeff Scott Brown
  • 26,804
  • 2
  • 30
  • 47
  • Thanks for clarifying. I've modified the question. I understand that `InputStream` won't be sent by the third party application. Rather, it will send a JSON payload which I can convert to a file using `InputStream` (how do I do this?) I guess I'm confused whether an actual file can be sent FROM a third party application and sent back TO a third party application using HTTP and JSON? Can you point to an example that shows how to do this? thanks – birdy Jun 29 '14 at 15:13
  • From this http://stackoverflow.com/questions/4083702/posting-a-file-and-data-to-restful-webservice-as-json it seems that the third party application should be doing base64 of the file? – birdy Jun 29 '14 at 15:19
  • your updated edit is exactly what I'm looking for, however, the request you sent is all text data. My unclarity is how that request will change if I was sending a file (say, an image file) – birdy Jun 29 '14 at 15:20
  • I am glad that update is what you are looking for. Your original question doesn't say anything about files or base64 encoding. You can retrieve file contents from the body using something like `request.getFile("fileName")`. See http://grails.org/doc/latest/guide/theWebLayer.html#uploadingFiles. – Jeff Scott Brown Jun 29 '14 at 15:23
  • Great. I am going to try the example in that link but not use the multipart form and instead send HTTP request to test it out. Thanks – birdy Jun 29 '14 at 15:42