respond to http request with json object in portlet
Asked Answered
P

1

9

I am a beginner in liferay portlet development and I am developing a portlet that receives a http get request, processes some information and than it has to return a json object. My problem is that my portlet sends a whole html page instead of just the json object. This is my code:

HttpServletResponse servletResponse = PortalUtil.getHttpServletResponse((renderResponse));

            servletResponse.setHeader("Content-type", "application/json");
            servletResponse.setCharacterEncoding("application/json");
            PrintWriter out = servletResponse.getWriter();
            out.write(EntityUtils.toString(responseEntity));


            out.flush();
            out.close();

I execute this in the doView() method I know that this is not the best practice, but I am not concerned with that at the moment. Can someone explain to me how to return just the json object I read something about serveResponse, but I couldn't figure out how to invoke it.

Phare answered 11/7, 2013 at 11:26 Comment(2)
I would advise against using HttpServletRequest or HttpServletResponse classes in a portlet. It breaks the whole portlet programming model and just welcomes further bad practices. See the idea of broken windows codinghorror.com/blog/2005/06/the-broken-window-theory.htmlGagliardi
Be concerned that implementing this in doView is bad practice precisely because it does not work. That's what serveResource is forGhostly
E
15

Well, one thing to notice, that the doView() is mostly responsible for rendering of your portlet. Your requirement can better achieved by
1 - processAction(Portlet Action) or
2 - serveResource(Portlet AJAX service).

To my view, AJAX request-response will be the most suitable case; for that you just need to create a resource URL on your portlet view. Like:

<portlet:resourceURL var="ajaxResourceURL" />

Add a JavaScript method to the page, from where you can generate AJAX request to your portlet. The method will look something like this,

<script type="text/javascript">
function _callAjax(val1, val2){
    var url = '<%=ajaxResourceURL %>';    // pass resource URL you created using scriplet / EL.
    jQuery.ajax({
    type : "POST",
    url : url,
    cache:false,
    dataType: "json",
    data: {
      value1: val1,    // extra parameters if you want to pass
      value2: val2
    },    
    success : function(data){
        // do whatever you want with your response data
    },
    error : function(XMLHttpRequest, textStatus, errorThrown){
       alert(errorThrown);
       alert(textStatus);
    }
  });
};
</script>

Call that ajax method on a button / link click event:

<input type="button" onclick="_callAjax('val1', 'val2')" value="Send" /> 

And finally, in your portlet's action listener class add the following serveResource method, responsible for handling AJAX based request(s).

Here you can get your request parameters and generate a response in the sense you want:

@Override
public void serveResource(ResourceRequest request, ResourceResponse response) throws PortletException,IOException {

String value1 = ParamUtil.getString(request , "value1", "default");    // request parameters
String value2 = ParamUtil.getString(request , "value2", "");

PrintWriter writer = response.getWriter();

JSONObject jsonObject = new JSONObject();
jsonObject.put(String key, boolean/long/Collection/double/Map/Object value);

writer.write(jsonObject.toString());
}

Thats it! Hope, this will be helpful for you :)

Emmen answered 11/7, 2013 at 12:54 Comment(3)
I think you meant to use '${ajaxResourceURL}' when assigning the URL in the JavaScript function. Otherwise I would agree that AJAX and serveResource is proper way to return just a JSON object.Gagliardi
ajaxResourceURL is the URL created by your portlet indicating your serveResource method. You can assign URL to javascript function <%=ajaxResourceURL %> if you are using it on similar JSP. But, if you want to make request from some-where else then you need to assign a hard-coded URL, by printing the var.Emmen
Thank you extraordinary, you saved me!Phare

© 2022 - 2024 — McMap. All rights reserved.