如何从自定义JSF组件中的辅助bean加载jquery json数据?

时间:2017-12-05 14:33:57

标签: javascript java jquery jsf

简而言之,JSF 2.2中将json数据从支持bean加载到浏览器中运行的javascript prog中的最佳方法是什么。

我正在将一个肮脏的黑客iframed visjs网络图移植到JSF 2.2 - Primefaces 6.1。我们在jsf标记库中有所有特殊标记作为jar模块中的自定义UiComponent。我向标记库添加了一个新的图形标记,一个扩展的UiComponentBase类,并将所有带有@ResourceDependency的visjs javascript文件放到该类中。标签加载正常,但jquery尝试打开一个URL来加载json格式的图形坐标:

$.ajax({
    url: "/ajax/getNetwork",
    type: "POST",
    data: "",
    dataType: "json",
    success: showNetwork,
    error: showError
});

在旧的iframe解决方案中,visjs通过此URL加载所有数据。

我阅读了一些关于带有<h:outputText>,servlet或JAXRS休息服务端点的xhtml页面的内容,但这些解决方案不适合标记库,必须在Web的web.xml中进行配置项目。有没有办法用ajax事件或标记库中的ajaxBehavior来做?

提前致谢。

1 个答案:

答案 0 :(得分:0)

taglib中的图形UiComponent现在按预期工作。扩展数据模型填充在辅助bean中,类似于primefaces数据表的惰性数据模型。来自Web浏览器中客户端的jQuery url请求将使用自定义PhaseListener进行捕获。无法从PhaseListener访问UiComponent,因为UiViewRoot组件树为空。因此,我将图形UiComponent类中的数据模型放入SessionMap,并可以访问PhaseListener中的数据模型。我不确定这是最好的方法,这样做。这是自定义PhaseListener:

public class GraphPhaseListener implements PhaseListener {
  private TopologyModel topoModel;

  private PhaseId phaseId = PhaseId.RENDER_RESPONSE;

  @Override
  public void beforePhase(PhaseEvent event) {          
     FacesContext context = event.getFacesContext();
     Object obj = context.getExternalContext().getRequest();
     if(!(obj instanceof HttpServletRequest)) {
         return;
     }
     HttpServletRequest request = (HttpServletRequest) obj;
     if(!("true").equals(request.getHeader("networkAjax")) || !request.getMethod().equals("POST")) {
         return;
     }


    Map<String, Object> sessionMap = event.getFacesContext().getExternalContext().getSessionMap();
    Object object = sessionMap.get(EnhancedGraphRenderer.GRAPH_TOPOLOGIE_KEY);
    if(object == null || !(object instanceof TopologyModel)) {
        return;
    }
    topoModel = (TopologyModel) object;
    String graphAction = request.getHeader("graphAction");
    String actionResponse = "";
    if(graphAction==null) {
        return;
    }
    switch(graphAction) {
        case "getNetwork":
            actionResponse = topoModel.getJsonNetwork();
        break;
        case "getNodeTypes":
            actionResponse = topoModel.getJsonNodeTypes();
            //actionRespoonse = topoModel.getFromAction("{node_type:switch, node_id: 2, request: children}")
        break;
        default:
            actionResponse = "{}";
    }

    HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();
    try {
        PrintWriter output = response.getWriter();
        output.print(actionResponse);
        context.responseComplete();
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

  }

  @Override
  public void afterPhase(PhaseEvent arg0) {

  }

  @Override
  public PhaseId getPhaseId() {
      return phaseId;
  }
}

我希望能帮助他人,欢迎改善消费。