Ajax call to GenericPortlet.serveResource() in WebSphere Portal 6.1

BAR picture BAR · Feb 11, 2011 · Viewed 7.7k times · Source

I'm trying to call a portlet's serveResource() method using jQuery/ajax. I managed to get a simple JSR-286 portlet working in Pluto 2.0 that is able to read a JSON string from the request body, create a Java object from the JSON, and return that object's toString() to my calling JavaScript. However when I deploy* the same portlet to WebSphere Portal 6.1 the request body is empty by the time it reaches serveResource().

I'm assuming I'm missing something basic/fundamental so any advice would be appreciated. I think I could get my sample working if I pushed the JSON string onto the URL parameters but would prefer to avoid that approach for now, unless I'm given a reason why my current approach is "bad".

Edit: *To be more specific, I deployed the same portlet to WAS7 running a WSRP Producer and consuming the portlet via WebSphere Portal 6.1.

Javascript Snippet:

function ajaxPost() {
    var url = "<%= testServiceURL %>";
    var current = $("input.current").val();
    $.ajax(
        {
            url: url,
            contentType: 'application/json; charset=utf-8',
            dataType: 'html',
            data: "{data: " + current + "}",
            type: 'POST',
            success: testSuccess,
            error: testError
        }
    );
    $("div.trace").append("ajax post fired<br />");
}

function testSuccess(data, textStatus, XMLHttpRequest)
{
    $("div.trace").append("testSuccess(): " + data + "<br />");
}

Portlet Snippet:

public class TestPortlet extends GenericPortlet {
    ...
    @Override
    public void serveResource(ResourceRequest request, ResourceResponse response) throws PortletException, IOException {
        String res = "Failed to read body";

        boolean bodyRead = true;
        StringBuffer sb = new StringBuffer();
        String line = null;
        try {
            BufferedReader reader = request.getReader();
            line = reader.readLine();
            while (line != null) {
                sb.append(line);
                line = reader.readLine();
            }
            reader.close();
        } catch (Exception e) {
            bodyRead = false;
        }

        Foo f = null;
        if (bodyRead) {
            try {
                Gson gson = new Gson();
                f = gson.fromJson(sb.toString(), Foo.class);
                res = "Received: " + f.toString();
            } catch (Exception e) {
                res = "Failed to convert body into Foo: '" + sb.toString() + "'";
            }
        }

        response.setContentType("text/html");
        response.getWriter().println(res);
    }
}

Answer

BAR picture BAR · Feb 15, 2011

Finally got it working...sort of.

By changing the contentType parameter in my ajax call to 'application/x-www-form-urlencoded' (and playing with different methods of representing my data) I now have my data available in the post body in my WebSphere environment, albeit in a URL parameter form as opposed to JSON.

Unfortunately, performing this change has resulted in breaking the functionality in Pluto. The request body in that environment is now empty.

Now to either change the code to retrieve the data from request.getParameter() (which I believe works in both environments with my change but requires further testing) or finding a contentType that will result in a populated request body in both environments.