1

I have a JSF-page in which the user can submit some data to an external link. However, before doing so I need to call a local action from a backing bean. In what way can I achieve this?

This is an example of my form (using vanilla HTML due to the external link action):

<form method="POST" action="https://EXTERNAL-LINK.com/">
    <input type="hidden" ... />
    <button>Submit</button>
</form>

So in short this is my case:

  1. Submitting the form my hitting the button
  2. Calling a local method from a bean
  3. Submitting the form to the external link

Any ideas on how to achieve this?

Menno
  • 10,573
  • 13
  • 51
  • 84

2 Answers2

2

I would submit a JSF form via AJAX behind the scenes first and when the response arrives I would submit your plain HTML form to an external URL.

Example:

<script type="text/javascript">
    function jsf(data) {
        if(data.status == 'success') {
            document.getElementById('plain-submit').click();
        }
    }
    function normal() {
        document.getElementById('jsf-submit').click();
    }
</script>
...
<h:form prependId="false">
    ...
    <h:commandButton id="jsf-submit" action="#{bean.action} value="Submit" style="display:none">
        <f:ajax execute="@form" ... onevent="jsf"/>
    </h:commandButton>
</h:form>
<form method="POST" action="https://EXTERNAL-LINK.com/">
    ...
    <input id="button-submit" type="button" onclick="normal()" ...>Submit</input>
    <input id="plain-submit" type="submit" style="display:none">Submit</input>
</form>

Or it would be even easier to reverse the situation by making plain HTML form invisible, thus decreasing the number of JavaScript operations: you submit the (visible) JSF form via AJAX and then submit (invisible) plain HTML form when response successfully arrives back.

skuntsel
  • 11,346
  • 11
  • 41
  • 64
2

Change the <form> to <h:form> and other HTML components to JSF components, bind their values with your managed bean and let the user submit the data. Then, in your action method you evaluate the data and then use a library like Apache HttpClient to send a POST request to the URL you want/need.

This could be a raw example of this (based on your example).

JSF code

<h:form >
    <h:inputHidden value="#{bean.aField}" />
    <h:commandButton value="Submit" action="#{bean.anAction}" />
</h:form>

Managed bean code

@ManagedBean
@RequestScoped
public class Bean {
    private String aField;
    //constructor, getter and setter...
    public void anAction() {
        //do your form processing...
        HttpRequestHandler httpRequestHandler = new HttpRequestHandler();
        httpRequestHandler.handlePost(...); //send the arguments here
    }
}

public class HttpRequestHandler {
    public void handlePost(String ... parameters) {
        //you do the Apache HttpClient POST handling here
        //always create a class between your application and your third party libraries
        //code adapted from HttpClient examples: http://hc.apache.org/httpcomponents-client-ga/examples.html
        HttpClient httpclient = new DefaultHttpClient();
        try {
            HttpPost httpPost = new HttpPost(...);// your URL goes here
            //do as you please with the HttpPost request

        } finally {
            httpclient.getConnectionManager().shutdown();
        }
    }
}

If you don't want to add the Apache HttpClient library for this job, then you could use native Java classes like URLConnection as shown here: Using java.net.URLConnection to fire and handle HTTP requests

Community
  • 1
  • 1
Luiggi Mendoza
  • 81,685
  • 14
  • 140
  • 306
  • I tried sending a HttpPost from my bean, but it seems I'm not redirected in that case (the external link is of a payment program). Am I correct that this only happens when submitting a form or am I missing something in that? – Menno Jul 15 '13 at 14:51
  • If your browser needs to show the external URL in address then this approach won't do (note that you should state this in your question). Use skuntsel approach instead. – Luiggi Mendoza Jul 15 '13 at 14:52
  • A very good approach! Though OP should get the response as well and (re)populate some fields after it arrives (and I'd put that into the code as well). Of course, +1. – skuntsel Jul 15 '13 at 14:57
  • @skuntsel yes, that can be handled in the `HttpRequestHandler` and the related design but since OP hasn't stated how to use it, I just let a basic example :). – Luiggi Mendoza Jul 15 '13 at 14:57
  • Ok, too bad it won't do in this case because this solution would have been my favorite. My apologies for not mentioning it in the question and thanks for your quick and good feedback. – Menno Jul 15 '13 at 14:57