Ajax 未在我的 Liferay portlet 中触发

Ajax not triggered in my Liferay portlet

我有一个 MVCPortlet,我尝试在 jsp 页面中调用 ajax。

我的jsp如下:

<%@include file="/html/init.jsp"%>

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


<script type="text/javascript">

function selectRat(){

    var rat = new Object();
    rat.nom = $('#ratsList').val();

    alert(rat.nom + ' '/* + portletURL*/);


    $.ajax({

        url: "${updateRatAjax}" ,
        type: 'POST',
        dataType: 'json',
        data: JSON.stringify(article),
        contentType: 'application/json',
        mimeType: 'application/json',

        success: function (data) {
            alert('ajax' + article.nom);
            }
    });

    alert('end of function');
}
</script>
....

    <select  class="offset2 span4 form-control"  name=ratsList id = ratsList onchange="selectRat()">
        <option>1</option>
        <option>2</option>
        <option>3</option>
    </select>

    <input  name = "selectedRat" id ="selectedRat"></input>

我的控制器 portlet 资源如下:

public class MainControllerPortlet extends  MVCPortlet {
...
    public void updateRatAjax( ResourceRequest request, ResourceResponse response)
            throws IOException, PortletException {
        System.out.println(" updateRatAjax");

    }
}

我也试过在js函数中这样调用url:

  url:"<%= updateRatAjax %>",

 var portletURL = "<%= updateRatAjax %>";
   url: portletURL,

没机会了。 alert(rat.nom + ' '/* + portletURL*/); 显示器 但是当 $.ajax({...}) 被调用时,js 方法必须停止。

该问题可能与应用程序无法使用 updateRatAjax 方法映射 resourceURL 有关。 在这个项目中,actionURL 被正确映射到控制器的方法,我没有将它们映射到 web.xml 中,也没有使用任何分配。 我认为我也不需要映射 portlet:resourceURL,但我可能错了。我第一次使用 portlet:resourceURL 所以我对它们一无所知。

提前感谢您的帮助。

编辑: 按照 Sudakatux 的回答,我将 JS 函数更改为: ...

 var portletURL = "${updateRatAjax}"; // "<%= updateRatAjax %>";//working  // 
  alert(rat.nom + '\n ' +   portletURL); //portletURL displays correctly with both options on previous line

    $.ajax({

        url: portletURL ,
        type: 'POST',
        dataType: 'text',
        cache: false,
        success: function (data) {
            alert('success ajax' );
            }, 
        error: function(http, message, exc) { 
           alert('error ajax'); 
       }

    });

奇怪的是,我收到成功消息,但从未调用控制器方法:

public void updateRatAjax( ResourceRequest request, ResourceResponse response)
        throws IOException, PortletException {
//public void updateRatAjax(ActionRequest request, ActionResponse response)        throws  PortalException, SystemException {
    System.out.println("MainController portlet : updateRatAjax");
}

我觉得不错 - 一些合理性检查:

  • 日志中有任何内容吗?
  • 你提到了 alert(rat.nom + ' '/* + portletURL*/); 但没有提到 alert(rat.nom + portletURL); (当然有首字母 var portletURL = "<%= updateRatAjax %>";
  • 您的 init.jsp 是否包含 portlet 标签库并且可用?您可能只想包含在您的页面上,以便它被打印出来并且您可以检查它
  • 或者:JSP 生成的 HTML 代码是什么? (为了绕过 Liferay 的缩小器,将 ?strip=0 添加到 URL - 这样更易于阅读。
  • 这是一个与其他 portlet 共享页面的 portlet。您确定您使用的 ID 不会干扰任何其他 portlet 的 ID 吗?

试一试

<portlet:resourceURL var="timeSyncURL" id="serverTimeSync" />

<script type="text/javascript">
var serverTimeFunction = function serverTime() { 
var time = null; 
    $.ajax({url: '<%=timeSyncURL.toString() %>', 
 async: false, dataType: 'text', 
 success: function(text) { 
    console.log("updated time "+ text);
     time = new Date(Number(text)); 
     console.log("time is "+time);
 }, error: function(http, message, exc) { 
     time = new Date(); 
}}); 

所以我在这里调用的服务与您的 updateRatAjax 方法具有相同的签名。对我来说工作正常

这是一个不太优雅的选项,但它肯定可以工作 覆盖 serveResource 方法

@Override
        public void serveResource(ResourceRequest resourceRequest,
                ResourceResponse resourceResponse)
            throws  IOException, PortletException {

if(resourceRequest.getResourceID().equals("serverTimeSync")){
                 PrintWriter out = resourceResponse.getWriter();

                 out.println(new Date().getTime());
}

serveResource 用于 AJAX 个调用,因此这肯定会起作用。

Yes, you are right, your AJAX call (resourceURL) is not getting mapped with appropriate listener in action class.

问题是您高度关注链接 AJAX 调用到控制器的特定方法,基于默认 MVC portlet 的 var 属性,就像我们在 Spring MVC portlet 使用 @ResourceMapping("xxx") 注释。

请参阅以下摘自 Multiple Ajax calls liferay portlets 的行:

Adding more in this. We can not use the serveResource method like processAction. There can be multiple processAction in single Liferay portlet(Which is not Spring MVC portlet), while in case of serveReource it will be single.

现在,只需重写 serveResource,如下所示:

public void serveResource( ResourceRequest request, ResourceResponse response)
    throws IOException, PortletException {
    System.out.println(" updateRatAjax");
}

此外,如果您有多个 AJAX 调用,您有两个选择:

1.将 id 属性添加到 <portlet:resourceURL> 标签后,使用 serveResource 中的 resourceRequest.getResourceID() 过滤请求,例如:

<portlet:resourceURL id="updateRatAjax" ></portlet:resourceURL>

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

    if(resourceRequest.getResourceID().equals("updateRatAjax")){
        System.out.println(" updateRatAjax");
    }
}

2。通过 <portlet:resourceURL> 或 AJAX data:

使用附加参数过滤请求
<portlet:resourceURL>
    <portlet:param name="action" value="updateRatAjax" />
</portlet:resourceURL>

data: {
    article: JSON.stringify(article),
    action: 'updateRatAjax'
},

控制器:

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

    String action = ParamUtil.getString(request , "action", "");

    if(action.equals("updateRatAjax")){
        String article = ParamUtil.getString(request , "article", "");
        System.out.println(" updateRatAjax");
    }
}