JSF commandButton - passing POST params to an external site - jsf

I need a link which redirect me to a different site and send POST parameters. Something like:
<h:form>
<h:commandButton value="submit" action="http://example.com">
<f:param name="user" value="robson">
</h:commandButton>
</h:form>
The code above doesn't work of course.
I'd like to acheive this in HTML:
<form action="http://example.com" method="POST">
<input type="hidden" name="user" value="robson">
<input type="submit" value="submit">
</form>
Is that possible?

Use the vanilla HTML <form> tag, not the JSF tag if you're going to send form data to a non-JSF target.
The JSF form tag is designed to facilitate JSF postback operations, which is why it has no "action" attribute.

Related

JSF link to external site without showing username and password in the URL

I was able to do a SSO(Single sign on) on click of external link from the code below. SSO works but username/password is seen on url.
https://example.org/index.php?userLogin=user1&userPassword=pass123
<h:outputLink styleClass="ui-menuitem-link ui-corner-all"
value="https://example.org/index.php">
<h:outputText value="Ext Tool" />
<h:outputText styleClass="ui-icon ui-icon-suitcase"
style="float:left" rendered="#{userBean.in}" />
<f:param name="userLogin" value="#{userBean.user.eUser}" />
<f:param name="userPassword" value="#{userBean.user.ePass}" />
</h:outputLink>
I also used tried as below...
<h:commandLink action="#{userBean.eSubmit()}">
<h:outputText value="Ext Tool" />
<f:param name="userLogin" value="#{userBean.user.eUser}" />
<f:param name="userPassword" value="#{userBean.user.ePass}" />
</h:commandLink>
In the bean.. My coding is like this
public void eSubmit() throws IOException{
FacesContext fc = FacesContext.getCurrentInstance();
fc.getExternalContext().redirect("https://example.org/index.php?userLogin=" + user.getUser() + "&userPassword=" + user.getPass());
}
Even for the above code with commandLink - UserName and password are visible in the URL. Please guide me to hide password in the URL.
Am new to JSF so please help me understand...
A redirect instructs the client to create a new GET request on the specified URL. That's why you see it being reflected in browser's address bar.
As to performing a POST to an external site, you don't necessarily need JSF here. You're not interested in updating JSF model nor invoking a JSF action. Just use a plain HTML POST form.
<form method="post" action="https://example.org/index.php">
<input type="hidden" name="userLogin" value="#{userBean.user.eUser}" />
<input type="hidden" name="userPassword" value="#{userBean.user.ePass}" />
<input type="submit" value="Ext Tool" />
</form>
If necessary, throw in some CSS to make the submit button look like a link, or some JS to let a link submit that form.

Composite components & ID

I want to implement some javas cript into my JSF composite component, but I have problem with id. My java script with:
document.getElementById("myForm:customerId")
does not work, because the id is wrong. I have JSF composite component:
<composite:implementation>
<div id="element_customer">
<h2 class="element_title">Customer</h2>
<h:form id="myForm">
<h:inputText id="customerId" value="#{cc.attrs.customerId}"/>
</h:form>
</div>
</composite:implementation>
and HTML output is:
<div id="element_customer">
<h2 class="element_title">Customer</h2>
<form id="j_idt44:myForm" name="j_idt44:myForm" method="post" ... >
<input type="hidden" name="j_idt44:myForm" value="j_idt44:myForm" />
<input id="j_idt44:myForm:customerId" ... name="j_idt44:myForm:customerId" />
</form>
</div>
Why is "j_idt44" used in HTML output?
Composite components are NamingContainer components like <h:form>, <h:dataTable>, etc. This allows you to have multiple of them in the same view without conflicting IDs.
You need to give the composite component a fixed ID as well. E.g.
<my:composite id="someId" />
I'd also suggest to use <div id="#{cc.id}"> instead of <div id="element_customer">. It will then become someId with the above example.
Unrelated to the concrete problem, this isn't entirely the right purpose of a composite component. A composite component is intented to be of the same kind of <h:inputText>, etc. You seem to rather want a tag file or maybe an include file. See also When to use <ui:include>, tag files, composite components and/or custom components?

Proper way to call servlet from Facelets?

What is the proper way to call a servlet from a facelets file using a form with submit button? Is there a particular form required?
Just use a plain HTML <form> instead of a JSF <h:form>. The JSF <h:form> sends by default a POST request to the URL of the current view ID and invokes by default the FacesServlet. It does not allow you to change the form action URL or method. A plain HTML <form> allows you to specify a different URL and, if necessary, also the method.
The following kickoff example sends a search request to Google:
<form action="http://google.com/search">
<input type="text" name="q" />
<input type="submit" />
</form>
Note that you do not need to use JSF components for the inputs/buttons as well. It is possible to use <h:inputText> and so on, but the values won't be set in the associated backing bean. The JSF component overhead is then unnecessary.
When you want, for example, to send a POST request to a servlet which is mapped to a URL pattern of /foo/* and you need to send a request parameter with the name bar, then you need to create the form as follows:
<form action="#{request.contextPath}/foo" method="post">
<input type="text" name="bar" />
<input type="submit" />
</form>
This way the servlet's doPost() method will be invoked:
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String bar = request.getParameter("bar");
// ...
}
You can call in below way from jsf:
<h:outputText value="Download" />
<h:outputLink value="#{request.contextPath}/files" id="btnDownload1" styleClass="redButton">
<h:outputText value="FILESDOWNLOAD" />
</h:outputLink>
</h:panelGrid>
Then in web.xml:
<servlet>
<servlet-name>files</servlet-name>
<servlet-class>com.Download</servlet-class>

Calling servlet post from jsf in different war

I want to call a Servlet which exists in a different war from my war. When user clicks a button we need to call the post method of the servlet. To implement this I did see an existing example which is slightly different but works in that case.
I am using jsf, so in the jsp there is a h:form with another html form inside of it. Below is the code:
<h:form>
<div id="gform" class="column span-20 append-1">
<h:outputText value="Text." /><br/><br/>
<h:commandLink id="addPaymentButton" styleClass="button" onclick='autorenew();return false;'> <span><h:outputText value="Payment Option"/></span> </h:commandLink>
<a id="noThanksButton" href="#"><span><h:outputText value="No Thanks"/></span></a><br/><br/><br/>
<h:outputText style="color:grey" value="Some text" />
<div> </div>
</div>
<form id="hiddenSubmit" method="post" action="https://localhost.myapp.com/myapp/LoginRouter" >
<input type="hidden" name="redirectUrl" value="/myapp/customers/addNewSavedCCInfo.faces"/>
<input type="hidden" name="jump_message" value="IAmJumpingToCC"/>
<input type="hidden" name="jump_url" value="/premiumServices/myPage.htm"/>
<input id="hiddenSubmitButton" type="submit" name="submit" style="display: none" value='' />
</form>
</h:form>
<script language="javascript">
function autorenew(){
window.alert('In js fnt');
document.hiddenSubmit.getElementById('hiddenSubmitButton').click();
window.alert('In js fnt COMPLETE');
return false;
}
So when the button is clicked, javascript is executed which submits the form to the servlet. However I can see in firebug that the second form which I need to submit does not appear. I am not sure how I can call the post method of a servlet class in a different war. Any ideas welcome, I am really stuck!
Thanks.
As per the HTML specification it's forbidden to nest <form> elements. The (mis)behaviour is browser dependent. Some browsers will send all parameters, some browsers will send only the data of the parent form, other browsers will send nothing.
You want to have a single form here. You can perfectly replace the <h:form> by a plain vanilla HTML <form> with the desired action pointing to the servlet in question.

JSF / CSS attribute conflicts

It's our first JSF app, and I'm in the middle of integrating our graphic designer's CSS into our facelets files. He tells me that he needs the name and id attributes of the input tags to be the same as the for attribute of the label tag.
His request:
<label for="username">User Name:</label>
<input id="username" type="text" name="username" />
However, when JSF code renders the HTML, I get extra identifiers in these attributes.
My facelet code:
<label for="username">User Name:</label>
<h:inputText value="#{login.username}" id="username" name="username" />
Final XHTML that's sent to the browser:
<label for="username">User Name:</label>
<input id="j_id2:username" type="text" name="j_id2:username" />
It makes sense to me from a JSF standpoint, but is there a way for me to meet our graphic designer's request and make everyone happy? Or is this a bad JSF oversight?
Thanks!
You can use the JSF outputLabel tag, which should handle the ids automatically:
<h:inputText id="username">
<h:outputLabel for="username" value="User Name: "/>
</h:inputText>
Edit: To avoid confusion: You can also put the outputLabel outside the inputText Element. I just use it mostly like this.

Resources