【问题标题】:How to load with jquery json data from a backing bean in a custom JSF component?如何从自定义 JSF 组件中的支持 bean 加载 jquery json 数据?
【发布时间】:2018-05-19 06:14:47
【问题描述】:

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

我正在将一个肮脏的黑客 iframe 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 REST 服务端点的单个 xhtml 页面的内容,但这些解决方案不适合标记库,必须在 Web 项目的 web.xml 中进行配置。有没有办法用 ajax 事件或标签库中的 ajaxBehavior 来做到这一点?

提前致谢。

【问题讨论】:

  • 我们在标签库中需要它作为自定义 UiComponent。我将使用 PhaseListener 对其进行测试——article 中描述了类似的解决方案。如果可行,我会在这里发布

标签: javascript java jquery jsf


【解决方案1】:

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;
  }
}

希望对其他人有所帮助,欢迎提出改进建议。

【讨论】:

    猜你喜欢
    • 2011-07-14
    • 2011-07-01
    • 2020-03-14
    相关资源
    最近更新 更多