4
votes

What I want to do is, just post data to server and get data from server by using JSON & AJAX. I am converting legacy non AJAX project to AJAX. It is a liferay portlet spring ibatis jquery project. Form submission was success and I could not be able to retrieve data from server as JSON. I used spring-mvc-jquery-autocomplete-example sample to learn jackson for JSON. It was very easy no need me to even think about JSON. I just copy-paste two jar files in my build path and annotate @ResponseBody to my method. But still response is full html page. Why?

JSP code here

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


    <c:set var="formPortletNamespace">form<portlet:namespace/></c:set>

    <form:form method="post" action="${formAction}" commandName="uiState" id="${formPortletNamespace}" cssClass="travelInsurancePortletForm jqCustomStyle" autocomplete="off">
        <% /* Selected action as a parameter */ %>
        <input type="hidden" name="portletAction" id="portletAction"/>

        <form:hidden path="quote.quotingWebApp" />

JS code here.This code submit the form to server

function doPortletAction(actionName) {
   jQuery('form#form<portlet:namespace/> input#portletAction').val(actionName); 

   jQuery('form#form<portlet:namespace/> input#<portlet:namespace/>-posted').val('true');
//jQuery('form#form<portlet:namespace/>').submit();


jQuery.ajax({
    url: jQuery('#form<portlet:namespace/>').attr("action"),
    type: 'POST',
    datatype:'json',
    data: jQuery('#form<portlet:namespace/>').serialize(),
    success: onAjaxSubmitReturn
});

}

Controller coding

@Controller
@RequestMapping("VIEW")
public class MyController{

    @ActionMapping(params="portletAction=myAction")
    public @ResponseBody UiState myAction( 
            PortletSession session, 
            ActionResponse response, 
            @RequestParam(value="endDate", required=false) Date endDate,
            @ModelAttribute("uiState") UiState requestUiState,
            BindingResult errors,
            ModelMap mm) throws Exception {

    UiState uiState=new UiState ();
        return uiState;

}
1
I'm not sure what UiState is, but its probably responding with a "text/html" content type, which is the default. You'll need to declare your response type as "application/json" in your myAction method.Ben VonDerHaar
thanks.I could be able to load JSON data from spring controller by using.Sanka

1 Answers

2
votes

First of all, Action phase does not produce any output. It always goes to Render phase. So this code wouldn't work anyway.

For second, as of Spring 4.1 it doesn't support @ResponseBody for portlets yet. It is planning in 4.2, but it might not be there as well.

So what you need is to use either @RenderMapping or @ResourceMapping (JSR-286/Portlet 2.0 only).

The most natural way is to use @ResourceMapping. Code will look like the following:

@ResourceMapping("myAction")
public void myAction(
        PortletSession session,
        ResourceResponse response,
        @RequestParam(value="endDate", required=false) Date endDate,
        @ModelAttribute("uiState") UiState requestUiState,
        BindingResult errors,
        ModelMap mm) throws Exception {

    UiState uiState = new UiState ();

    //TODO extra logic

    //explicitly set JSON as response type
    response.setContentType("application/json");

    //write JSON into output
    response.getWriter().write(serializeJSON(uiState));
}

Whereis serializeJSON is utility method by your choice.

Sample implementation is the following (based on Jackson serializer):

public static String serializeJSON(Object o) throws IOException {
    return new ObjectMapper().writeValueAsString(o);
}

Note: you need to use this snippet on your JSP(s):

<portlet:resourceURL var="formAction" id="myAction"/>