Execute Javascript function between two Backing bean methods - jsf

I'm writing a JSF web application who follow the next steps:
Read a number from an input text
Look for the number in a legacy system
Generate a message and send It to a websocket
Get the response from the websocket
Store the result in a database
All of these steps must be executed in a single event, all of these tasks are executed in a backing bean, the problem is to execute the javascript to call the websocket and use this result to save it in the database.
I tried to use the RequestContext.getCurrentInstance().execute("function();"); method, but this function "Executes script after ajax request completes or on page load" and I need to get the result to store it into the database and execute other operations.
The question is, How and where can I handle these calls?
NOTE:
I can see the following options, but I'm not sure how to implement them:
Handle the calls using Javascript instead of backing bean, following the next tasks:
from Javascript call a backing bean method to look the number and get the response.
from Javascript get the result of the backing bean and send it to the websocket.
from javascript receive the response from the websocket and call another backing bean to store the result into the database.
Found a way to call a javascript function from the backing bean before the ajax request completes.
Call the WebSocket in the Backing bean instead of using Javascript.
I hope you can help me, Thanks.
----EDIT-----
The websocket is running in localhost, in this way the web page handle a device in a local machine, so it must be executed in the Javascript side and the 3rd option is not possible.

an option could be the following:
your xhtml should have 3 forms:
"User inputText/number form"
"websocket-Request Form" (hidden form/input)
"websocket response Data Form" (hidden form)
now you follow these steps:
A user submits input to your Bean (via ajax or commandActions ...etc)
bean-methode reads/validates that submitted data, then update value in form#2
Javascript/Jquery should listen on form#2/inputhidden value changed( then sends a wensocket request)
after recieving websocket response, update value inside form#3 and do autosubmit. now submitting this form calls an action methode in your bean which saves data to DB.

Related

Cookie set in web filter is not available in request bean

I'm trying to create a localized JSF web application which allows user to select a language via dropdown. When language is selected, I simulate a redirect to the same page but with URL parameter:
window.location.replace(urlToMyApp + '?locale=DE');
Next, I read 'locale' parameter in application's web filter and write it in a cookie with the same name:
String localeValue = httpRequest.getParameter("locale");
Cookie cookie = new Cookie("locale", localeValue);
cookie.setMaxAge(-1);
cookie.setDomain(cookieDomain);
cookie.setPath(cookiePath);
httpResponse.addCookie(cookie);
Now when I try to read that cookie in request bean init method, cookie is not available. If I select another language via dropdown (EN for example), previously selected language (DE) is read in init method.
I assume that cookie written in filter is not available before next "request - response" cycle, can someone confirm that?
If that's true I'm asking for an idea to translate my application immediately after selecting another language.
Just one thing that I think I need to mention - language dropdown is not part of my application. It's part of some kind of framework for several applications to be included (like portal).
I assume that cookie written in filter is not available before next "request - response" cycle, can someone confirm that?
That's correct.
You've added the new cookie to the response, not to the request. So any attempt to read it from the same request won't work. The cookie will only be available in the request if the browser has actually sent it. But it can only do that if it has obtained the cookie data from a previous response.
If that's true I'm asking for an idea to translate my application immediately after selecting another language.
If the request scoped bean is managed by CDI #Named, then just inject it in the filter and set the locale over there.
#Inject
private Bean bean;
public void doFilter(...) {
// ...
bean.setLocale(locale);
// ...
}
Else if it's not managed by CDI, but by the since JSF 2.3 deprecated #ManagedBean, then manually instantiate it and put it in request scope so that JSF will just reuse the same bean.
public void doFilter(...) {
// ...
Bean bean = new Bean();
bean.init(); // If necessary.
bean.setLocale(locale);
request.setAttribute("bean", bean); // "bean" is managed bean name.
// ...
}
See also:
Get JSF managed bean by name in any Servlet related class
Localization in JSF, how to remember selected locale per session instead of per request/view

From IdentityServer3 successful login, how to automatically call WebAPi (MVC 5 Framework 4.8), without the physical click of the Call API button?

I've just started trying to set up IdentityServer3 on MVC5 app (latest framework).
The demo has a button to call the API, but I want to if the login is successful, automatically call the js function which does an ajax call back to my api.
The manager class has
.signinpopup()
and
.catch(function(error) { ..}
but does not support
.success(function(){…}
Is there some way of doing it from js , or is that handled by the server?, possibly in it's Client settings, maybe RedirectUris ?
Many thanks
The easy way to do it, is once the login succeeds and writes the token into a div element, hide the div element and use the jquery onchange event to call the function to call the API.

Writing plain HTML in a JSF based web application

I have this use case in a JSF application.
Supposed in a JSF web application, I have a button that calls an external service that returns a complete HTML response then how can I show that HTML response to my users browsers?
The sequence of events are like this.
In user browser, my application is displayed. A button is there that user can click.
Clicking the button will call an external service. The external service will return information about a certain HTML tags. The HTML is complete with both head/body and with javascript. Currently the service can be implemented thru REST service or a plain DB call then
How can I display that HTML tag in my user browser?
Is this possible to write non-JSF output in a JSF web application?
Just to add, I think my problem is how to write an HTML in my backing bean and write it back to the users browser.
Just write it outright to the HTTP response body whereafter you instruct JSF that the response is manually completed. The principle is not much different from How to provide a file download from a JSF backing bean?, except that you need to set content disposition to inline (which is already the default anyway).
public void writeHtmlResponse() throws IOException {
FacesContext fc = FacesContext.getCurrentInstance();
ExternalContext ec = fc.getExternalContext();
ec.setResponseContentType("text/html;charset=UTF-8");
ec.setResponseCharacterEncoding("UTF-8");
ec.getResponseOutputStream().write(html.getBytes("UTF-8"));
fc.responseComplete(); // Important! Otherwise JSF will attempt to render the response which obviously will fail since it's already written with a file and closed.
}

Error Rendering View: java.lang.IllegalStateException: getOutputStream() has already been called for this response

I am creating a project in JSF and spring whose main only purpose is to generate PDF file in the browser. Everything seems fine and pdf generated too but on console i am getting this exception.Anyone have idea about this? I have searched and found that many peoples had that problem but i didn't find any solution for mine one.
SEVERE: Error Rendering View[/WebPages/SearchPages/index.xhtml]
java.lang.IllegalStateException: PWC3991: getOutputStream() has already been called for this response
I am getting this error while creating my outputstream object
HTTPServletResponse response = (HTTPServletResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse();
ServletOutputStream out = response.getOutputStream();
Is there any problem while my creation or anyother reason? Any help would be greatly appreciable
You need to tell JSF that you've already completed the HTTP response yourself, otherwise JSF will still continue doing the default RENDER_RESPONSE job after the action method is finished, which would result in exactly this exception, because the response is already committed.
You can do that by calling FacesContext#responseComplete() in the action method.
responseComplete
public abstract void responseComplete()
Signal the JavaServer Faces implementation that the HTTP response for this request has already been generated (such as an HTTP redirect), and that the request processing lifecycle should be terminated as soon as the current phase is completed.
See also:
How to provide a file download from a JSF backing bean?

Keep a session alive for an indefinite amount of time

Is there a way to keep a page's session active without resorting to sending the state to the client? I'm not able to set the STATE_SAVING_METHOD to client and I'd prefer to not use the a4j:keepalive.
I've tried using a simple hidden iframe that submits to the Bean in question but it invalidates the main page.
I am using JSF 1.2 and myfaces.
This is to get around a ViewExpiredException on a page that does not require the user to log in. The majority of the existing site requires the user to log in.
Implement an ajax poll as a "heartbeat" to keep the session alive. At its simplest you can achieve this as follows with help of a little jQuery to avoid boilerplate code of 100 lines to get it to work across all different browsers the world is aware of:
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
$(document).ready(function() {
setInterval(function() {
$.get("${pageContext.request.contextPath}/poll");
}, ${(pageContext.session.maxInactiveInterval - 10) * 1000});
});
</script>
The ${pageContext.session.maxInactiveInterval} prints the remaining seconds the session has yet to live according to the server side configuration (which is by the way controllable by <session-timeout> in web.xml) and is been deducted with 10 seconds, just to be on time before it automatically expires, and converted to milliseconds so that it suits what setInterval() expects.
The $.get() sends an ajax GET request on the given URL. For the above example, you need to map a servlet on the URL pattern of /poll and does basically the following in the doGet() method:
request.getSession(); // Keep session alive.
That should be it.
BalusC's answer helped me to meet this requirement in my app, but since I'm using PrimeFaces, I wanted to share how BalusC's answer inspired the code i'm using to do this.
xhtml page
<p:poll listener="#{pf_usersController.keepUserSessionAlive()}"
interval="#{session.maxInactiveInterval - 10}" />
bean
public void keepUserSessionAlive() {
FacesContext context = FacesContext.getCurrentInstance();
HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
request.getSession();
}
as always, thank you, BalusC!
EDIT: An enduser put this to the test this morning, and it is working great! my app usually forces session timeout 15 minutes after full page refresh (redirect to sessionExpired.xhtml via meta refresh based on session.maxInactiveInterval and session timeout value in web.xml); if user is on one page doing a bunch of AJAX requests, session will timeout, since AJAX != full page refresh, but this code allowed enduser to 'keep session alive' while enduser was on payroll page in the app, and session stayed alive for 1 to 2 hours! :)

Resources