2

I have an XPages that has a restService control on it.

<xe:restService
    id="restService1"
    pathInfo="service"
    state="false">
    <xe:this.service>
        <xe:customRestService
            contentType="application/json"
            serviceBean="com.domain.rest.Employee">
        </xe:customRestService>
    </xe:this.service>
</xe:restService>

I want to pass in JSON data from an outside application. For this test I'm just using the postman plugin for Chrome.

I have some shell code that gets the REST verb and sends it to a matching method. The stub for the methods looks like this :

public void doPost( HttpServletRequest req, HttpServletResponse res, PrintWriter out ) {
        // Do something here
        this.doUnHandled(req, res, out);
    }

What I'm struggling with is how do I get read in the body of the Post so I can turn that incoming JSON into a Map or something else that I can work with in my Java code to then interact with Domino Documents. I've found a bunch of examples on the web, but they all seem different and I've not been able to put it together.

Ideally I'd like to use something built in I guess with com.ibm.commons.util.io.json for now. I know GSON and other things are popular but I just want to get something working first.

My latest attempt was with this example :

public void doPost( HttpServletRequest req, HttpServletResponse res, PrintWriter out ) throws IOException, JsonException {

        System.out.println("POSTING DATA");

        Map<String, Object> result = (Map<String, Object>) 
JsonParser.fromJson(JsonJavaFactory.instance, req.getReader());

        Map<String, Object> foo = new HashMap<String, Object>();
        foo.put("firstName", result.get("firstName"));
        System.out.println(foo.get("firstName"));

        this.doUnHandled(req, res, out);
    }

I had high hopes for that but I get an error that I can't use the buffered reader - req.getReader() - while ServletInputStream is in use.

My understanding is that the data I was is inside the req.getInputStream() and that might need to be read line by line and I've tried that with problems as well.

Any help or advice would be appreciated. Thanks!!

Eric McCormick
  • 2,716
  • 2
  • 19
  • 37
David Leedy
  • 3,583
  • 18
  • 38

2 Answers2

2
InputStreamReader isR = new InputStreamReader(req.getInputStream());
JsonJavaObject jsonObj = (JsonJavaObject) JsonParser.fromJson(JsonJavaFactory.instanceEx, isR);
Martin Jinoch
  • 308
  • 2
  • 7
  • This is giving me an Error for some reason : ERROR when parsing JSON stream I'm using POSTMAN to create the REST POST. I've tried "form-data" and also "x-www-form-encoded" modes. – David Leedy Dec 01 '16 at 18:36
  • 1
    Crap. I should learn to read answers first before jumping in and writing one :-( – Mark Leusink Dec 01 '16 at 21:41
1

So if you send your JSON in the request body like this:

{
  "user" : "Mark",
  "age" : 32
}

You can retrieve it from the POST request on the server using the java.util.Scanner class (there are more, but this is one way to do it):

 private static String extractPostRequestBody(HttpServletRequest request) {
    Scanner s = null;

    try {
        s = new Scanner(request.getInputStream(), "UTF-8").useDelimiter("\\A");
    } catch (IOException e) {
        e.printStackTrace();
    }
    return s.hasNext() ? s.next() : "";
}

The last step would then be to convert that into a Map using the built-in com.ibm.commons.util.io.json package:

String requestBody = extractPostRequestBody(request);
Map<String, Object> result = (Map<String, Object>) JsonParser.fromJson(JsonJavaFactory.instance, requestBody);

Once you have the map you can do:

String user = (String) result.get("user");
Mark Leusink
  • 3,747
  • 15
  • 23