Search code examples
jqueryajaxliferayportlet

How to return an object in response using ajax in liferay portlet?


I need to return a string on success method. Here is my AJAX code in jsp page.

  <portlet:actionURL name="filterDocuments" var="filterDocuments">
    <portlet:param name="action" value="filterDocuments"/>
</portlet:actionURL>

<script type="application/javascript">
    var filterDto = {
        page: 0,
        tags: {},
        search: null
    };
    $.ajax({
        type: "POST",
        url: "<%=filterDocuments%>",
        data: filterDto,
        success: function (msg) {
            alert(msg);
        }
    });
</script>

And here is my handler on backend side.

@ActionMapping(params = "action=filterDocuments")
    public void filterDocuments(ActionRequest actionRequest, ActionResponse actionResponse) throws IOException {
        PrintWriter writer = PortalUtil.getHttpServletResponse(actionResponse).getWriter();
        writer.write("text");
        writer.flush();
        writer.close();
    }

And in result it shows me an empty string in alert message. How to deal with it?

UPDATE I changed controller method to

 @ResourceMapping(value = "filterDocuments")
public void filterDocuments(ActionRequest actionRequest, ActionResponse actionResponse) throws IOException {
    PrintWriter writer = PortalUtil.getHttpServletResponse(actionResponse).getWriter();
    writer.write("text");
    writer.flush();
    writer.close();
}

And url at my jsp is

    <portlet:resourceURL var="ajaxResourceURL"/>

<script type="application/javascript">
    var filterDto = {
        page: 0,
        tags: {},
        search: null
    };
    $.ajax({
        type: "POST",
        url: "<%=ajaxResourceURL%>",
        data: filterDto,
        success: function (msg) {
            alert(msg);
        }
    });
</script>

And now it gives me an exception

org.springframework.web.portlet.NoHandlerFoundException: No handler found for portlet request: mode 'view', phase 'RESOURCE_PHASE', parameters map['search' -> array[''], 'page' -> array['0']]

Full controller class

  @Controller
@RequestMapping("VIEW")
@Log4j
public class SpringMVCController extends MVCPortlet {




    @RenderMapping
    public String view(RenderRequest request, RenderResponse response) {


        String view = PropertiesConfig.getAsString("views", request);

        return view;
    }


    @Override
    public void serveResource(ResourceRequest resourceRequest,
                              ResourceResponse resourceResponse)
            throws IOException, PortletException {
        try {
            PrintWriter writer = resourceResponse.getWriter();
            writer.write("text");
            writer.flush();
            writer.close();
            CaptchaUtil.serveImage(resourceRequest, resourceResponse);
        } catch (Exception e) {
            log.error(e.getMessage());
        }
    }


    @ResourceMapping(value = "action=filterDocuments")
    public void filterDocuments(ActionRequest actionRequest, ActionResponse actionResponse) throws IOException {
        PrintWriter writer = PortalUtil.getHttpServletResponse(actionResponse).getWriter();
        writer.write("text");
        writer.flush();
        writer.close();
    }


}

Solution

  • The following is/are the problem(s) with your updated code:

    i. You have not specified the id attribute (with required value) on portlet:resourceURLas per your portlet:actionURL. Change it to:

    <portlet:resourceURL id="filterDocuments" var="filterDocuments" />
    

    ii. The mapping method's signature in action class is not same as id attribute's value of portlet:resourceURL on UI, change it to:

    @ResourceMapping("filterDocuments")
    public void filterDocuments(ResourceRequest request, ResourceResponse response)
    throws IOException, SystemException {
        PrintWriter writer = response.getWriter();
        writer.write("text");
        writer.flush();
        writer.close();
    }
    

    iii. Remove the other serveResource method from action class, as that is for the Generic (default) portlet type only.

    Reference: Liferay Spring Portlet Tutorial