0

In short, what is the best way in JSF 2.2 to load json data from a backing bean into a javascript prog that runs in a browser.

I'm porting a dirty hacked iframed visjs network graph to JSF 2.2 - Primefaces 6.1. We have all special tags in a jsf tag library as custom UiComponent's in a jar module. I added a new graph tag, an extended UiComponentBase class, to the tag library and put all visjs javascript files with @ResourceDependency to the class. The tag loads fine, but jquery try to open a url to load json formatted graph coordinates:

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

On the old iframe solution, visjs load all data via this url.

I read some things about a single xhtml page with an <h:outputText>, a servlet or a JAXRS rest service endpoint, but these solutions does not fit into a taglibrary and must be configurated in the web.xml of the web project. Is there a way to do it with ajax events, or an ajaxBehavior in a tag library?

Thanks in advance.

Jochen Buchholz
  • 370
  • 1
  • 16
  • See https://stackoverflow.com/questions/5675017/calling-a-javascript-function-from-managed-bean – Jasper de Vries Dec 05 '17 at 14:39
  • We need it in a tag library as an custom UiComponent. I will test it with a PhaseListener - a similar solution is described in this [article](https://community.oracle.com/docs/DOC-983160). If it works, I will post it here – Jochen Buchholz Jan 11 '18 at 09:00

1 Answers1

0

The graph UiComponent in the taglib works now as expected. A extended datamodel is filled in a backing bean, similar like the lazy datamodel of the primefaces datatable. The jQuery url request from the client side in the web browser is catched with a custom PhaseListener. There was no way to access the UiComponent from the PhaseListener, because the UiViewRoot component tree was empty. So I put the datamodel in the graph UiComponent class into the SessionMap and can access the datamodel in the PhaseListener. I'm not sure that is the best way, to do this. Here is the custom 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;
  }
}

I hope that helps others, sugestions for improvement are welcome.

Jochen Buchholz
  • 370
  • 1
  • 16