Thursday, June 7, 2018

How to transfer parameters between applications via doPost method in ADF

Hello and welcome,

Today I am going to show you how to pass parameters between applications via doPost method in ADF.

Some customers require a separated applications to fulfill his need. Some how, these applications need to be keep in touch. in other words you probably need one as master application which control navigation to the other applications.

In this case you need -after successfully authentication operation in that master application- to waiting the potential user to navigate to desired sub-application. In addition to need to pass some authorized parameters to sub application.

No doubt there are many ways to do it. But I believe that passing these parameters via post method is the most safest way to keep your sensitive values far away from cheating of users if exists.

let's we go to implementation part:
First I created master application (caller) with home page which is going to handle the navigation:
  1. We have a sample link (you can use any other iterative components like button...) which include client listener component refers to java script function "callConsumerServlet"
  2. We use regular jsf technique to create one or more hidden inputs with name/value to be considered during form action.
  3. '/consumer/consumerredirect' represents the url pattern of consumer servlet class. do not include 'Faces Servlet' url pattern in this URL, just 'contextName/consumer-servlet-url-pattern' or you can use full path as: 'http://domain:port/contextName/consumer-servlet-url-pattern' in case of that sub-applications deployed on a different machine.
  4. The action method is going to be 'post' to apply hidden parameters transferring.
  5. Line (form.method = "post") is optional. is by default will be considered as post.
XML of home jsf page:
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE html>
<f:view xmlns:f="http://java.sun.com/jsf/core" xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
    <af:document title="home.jsf" id="d1">
        <af:resource type="javascript">
          function callConsumerServlet(evt) {

              //Get current form
              var form = document.forms[0];
              
              //get value through client attribute associated with link component on JSF page
              var transAttrValue = evt.getSource().getProperty('transAttr');
              //console.log(transAttrValue)
              
              //attributes need to be appended and passed through form
              var transInput1 = document.createElement('input');
              transInput1.name = 'transInput1';
              transInput1.value = transAttrValue;
              transInput1.type = 'hidden';
              form.appendChild(transInput1);

              //servelt setup and calling
              form.method = "post";
              form.action = '/consumer/consumerredirect';
          }
        </af:resource>
        <af:form id="f1">
            <af:pageTemplate viewId="/templatePage.jsf" id="pt1">
                <f:facet name="body">
                    <af:panelSplitter id="ps1" splitterPosition="200" dimensionsFrom="parent">
                        <f:facet name="first">
                            <af:panelAccordion id="pa1" discloseNone="true" styleClass="PanelAccSubMenu">
                                <af:showDetailItem text="Applications Menu" id="sdi1" disabled="true" disclosed="true">
                                    <af:link text="Consumer application" id="l2">
                                        <af:clientListener type="action" method="callConsumerServlet"/>
                                        <af:clientAttribute name="transAttr" value="#{menuMgr.transAttr}"/>
                                    </af:link>
                                </af:showDetailItem>
                            </af:panelAccordion>
                        </f:facet>
                        <f:facet name="second">
                            <af:outputText value="Home" id="ot1"/>
                        </f:facet>
                    </af:panelSplitter>
                </f:facet>
            </af:pageTemplate>
        </af:form>
    </af:document>
</f:view>

Managed bean properties to be used during navigation through client attribute:
package view.caller;

public class MenuMgr {
    private String transAttr;

    public void setTransAttr(String transAttr) {
        this.transAttr = transAttr;
    }

    public String getTransAttr() {
        return "Hello servlet";
    }
}

Second part which is the consumer application implementation, Just get target parameter inside servlet class then put it in session scope.
package view;

import java.io.IOException;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;

@WebServlet(name = "consumerRedirect", urlPatterns = { "/consumerredirect" })
public class consumerRedirect extends HttpServlet {
    @SuppressWarnings("compatibility:-5285037467424087153")
    private static final long serialVersionUID = 1L;

    public void init(ServletConfig config) throws ServletException {
        super.init(config);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("consumerRedirect|doPost start");
        Object transInput1Obj = request.getParameter("transInput1");
        if(transInput1Obj != null){
            String transInput1 = transInput1Obj.toString();
            System.out.println("consumerRedirect|doPost|trans1Input:" + transInput1);
            request.getSession().setAttribute("transInput1", transInput1);
        }
        response.sendRedirect("/consumer/faces/menu.jsf");
    }
}

XML of menu jsf page to show passed parameters:
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE html>
<f:view xmlns:f="http://java.sun.com/jsf/core" xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
    <af:document title="menu.jsf" id="d1">
        <af:form id="f1" >
            <af:pageTemplate viewId="/templatePage.jsf" id="pt1">
                <f:facet name="body">
                    <af:outputText value="#{sessionScope.transInput1}" id="ot1" inlineStyle="font-size:large;"/>
                </f:facet>
            </af:pageTemplate>
        </af:form>
    </af:document>
</f:view>


Finally deploy all your applications on server as EAR file; if you start with master application then you can navigate to sub-application as below:


Result:



The Sample is available and compatible with 12.2.1.3.0: transParamBetweenApps v1.rar

How to transfer parameters between applications via doPost method in ADF

Hello and welcome, Today I am going to show you how to pass parameters between applications via doPost method in ADF. Some customers r...