syntax_highlight

четверг, 2 августа 2012 г.

How to automaticly track train/airplane tickets

Hello everyone! Today I'm gona tell you about a common situation in life:

  • you need to buy a ticket for a precise date but there are no available (oh crap!)
  • you know 95% for sure that some tickets will appear for sale suddenly, you want to get them!
  • you have no time and patience to track site from time to time to check for those tickets
  • you can write a programm that'll do this for you
  • ...
  • profit!

четверг, 7 июня 2012 г.

AppCache JSON or other network requests not working

Today I've stumbled on the HTML5 AppCache problem - it denied to fetch all my network JSON requests and throws an error like:
GET http://somehost:10001/someapp/data.json - failed
I've tried a lot of variants, editing the manifes file, but none of them succeed. Exept one:
CACHE MANIFEST

#resources to cache
CACHE:
js/json_executor.js

#all other
NETWORK:
*
Should put an asterisk below NETWORK section. It seems like AppCache is using "deny all" strategy when a network request is processed. So what we do here is simply permit all network requests during page loading.

среда, 6 июня 2012 г.

Access JSF ManagedBean from Servlet

Before giving a ready solution I want to clarify some moments that can answer many unasked questions:
  • FacesContext is ThreadLocal (but ServletContext is not), that's why you can access it in a static way
  • FacesContext cannot be accessed in a static way from a servlet (only if it's FacesServlet)
  • FacesContext store it's beans into request attributes, session attributes or application attributes
  • You cannot inject @ManagedBean as @ManagedProperty into servlet
Now the answer is simple - JSF beans (if they are already instantiated and managed) can be accessed via attributes
JSF bean:
@ManagedBean(name="SimpleBBean")
@SessionScoped
public class SimpleBBean {
  // managed bean properties
}
and in the servlet:
SimpleBBean simpleBBean = (SimpleBBean) this.getServletContext().getAttribute("SimpleBBean");
SimpleBBean simpleBBean2 = (SimpleBBean) request.getAttribute("SimpleBBean");
SimpleBBean simpleBBean3 = (SimpleBBean) request.getSession().getAttribute("SimpleBBean");
response.getWriter().println("beans: " + simpleBBean + " " + simpleBBean2 + " " + simpleBBean3);
the output will be:
beans: null null SimpleBBean@ebf121
you can also set the scope attributes and then retrieve them from FacesContext

вторник, 5 июня 2012 г.

JSF open in other browser window

There are situations when there is a demand to open the link in another browser window.
How can we do this in HTML is simple:
<a href="http://mysite.com/page?id=442" target="_blank">Open post</a>
in JSF the analog code will be:
<h:outputLink value="http://mysite.com/page" target="about:blank">
  <f:param name="id" value="#{bbean.pageid}"/>
  <h:outputText value="Open post" />
</h:outputLink>
where <param> elements are used to produce request parameters.

Ok, now lets consider that you want to open a new browser window just after submitting and navigating to other JSF page. For example to open generated PDF in this page. What can be done here? Something shoud perform HTTP request. JavaScript to the rescue!
<h:outputScript>
  window.open('about:blank', 'PDF');
  window.open('/pdf?#{bbean.pdfId}=31&amp;type=#{bbean.pdfType}', 'PDF');
</h:outputScript>
put this script on the navigating page. As JSF will render this page, the script will be executed and popup page will appear.
If you wish to use parameters, don't forget to escape HTML special characters. ( & --> &amp; )

Just remember that popups are very NOT user-friendly, try to avoid them.

четверг, 31 мая 2012 г.

JSF Javascript submit button disabling

In case of submitting forms JSF and Javascript are less friends than cat and dog!
The main problem here is that JSF uses submit button attributes to perform action and actionListener requests to the server. Also JSF catches 'onclick' events to do that.
That means that if you try to do smth like this

<h:commandButton id="submitButton" value="Submit" action="nextPage"
onclick="this.disabled='disabled';"/>



nothing will be send to the server, because button become disabled before JSF performed it's actions.
That's of course the reason why navigation is not working.


This problem could be solved by invoking our custom 'onclick' javascript function after JSF.
Seems like a work for setTimeout() function
function clickButton(but) {
 setTimeout(function(){
  but.disabled='disabled';
 },1);
}
and the button
<h:commandButton id="submitButton" value="Submit"
action="nextPage" onclick="clickButton(this);"/>

You can add this code to any submit button in any JSF form and be sure that it will be disabled just after it was clicked, and no multiple requests will be send. Well... nearly just after =)