Kamis, 30 Januari 2014

What is it with roseindia?


Cry or laugh?


There's another Java related website at roseindia.net which hosts lot of basic Java EE tutorials along a huge mass of advertisements. There are also some JSF tutorials over there. Since I saw that site for the first time, about 1.5 years ago, I quickly realized that almost every article and code sample at that site must be taken with a huge bag of salt. But OK, I thought, that kind of websites unfortunately exist, nothing to do against, so I ignored it for the rest of the time.



And today, while surfing over the net I accidently came across http://www.roseindia.net/jsf/actionListener.shtml (screenshot). Now I don't know whether I have to cry or laugh about it. Initially I laughed hard, very hard. Running a Swing JOptionPane component from inside a server side Java class with the intention to display a message at the client side!! And showing that off as a tutorial?!? But then I realized that there might be many new-to-JSF developers who came across the roseindia.net site and took the gross of the articles for serious and implemented it for production. Ouch, that hurts! Also see the comments at the bottom of that article.



Update: here and here are another examples of a horror story related to roseindia.net. A poor programmer decided to implement the JSP file upload example as described at http://www.roseindia.net/jsp/file_upload/Sinle_upload.xhtml.shtml (ouch, note the typo and double extensions in the roseindia.net URL, how professional). The code example is bad in almost every way. The HTML code contains nasty uppercases (the author is apparently hanging in the '90s HTML style). The HTML code contains the

tag which is deprecated since 1998 (yes, that is 10 years ago!! the same applies on the tag which appears everywhere in roseindia.net's HTML source, how professional). The Java code is written entirely in a JSP file rather than a Java class (scriptlets are receipt for trouble). The uploaded file is allocated completely in memory instead of in a memory buffer (server will crash if the file or all files together are larger than JVM's available memory). The bytes are unnecessarily converted to String without respect to request encoding and using the system default encoding (ouch, what would happen with binary files? and with text files in another encoding?). Also read the comments at that article. Heck, almost every article has that kind of comments, shouldn't that already say something about the quality of the articles? See further also this stackoverflow.com answer.



Update 2: another horror story can be found here. One decided to download and install JSTL using the procedure as described at http://www.roseindia.net/jstl/downloading-jstl.shtml. Did you read it? It suggests to extract the complete JAR file, duplicate all of its TLD files in the WEB-INF and duplicate all of the TLD declarations in the web.xml of every webapplication which is going to use JSTL. Terrible. Just placing the JAR files in the classpath was been enough. The myth of extracting the JAR file is only applicable if you have downloaded the wrong JSTL version for your webapp which causes that EL (those ${} things) in JSTL tags may possibly fail. For more detail of the proper approach, read JSTL wiki page on stackoverflow.com.



Lesson learned: if you are new to Java EE, do not use roseindia.net! It might contain some good articles -which are generally copypasted/rephrased/changed from actually good sources (I've seen exact copypastes of parts of official TLD and API documentations, e.g. Tomahawk TLD and Java Servlet API, how lame..), or are in very rare cases just by coincidence good-, but for the rest it only introduces bad practices and/or contains stupid examples. That site almost seems to be maintained by amateurs with zero professional experience and targeted on the advertisement incomes only. If you are new, you never knows which is good and which is bad. So, just ignore that site. Forever.



Good JSF sites


At least here is a list of trusted and good JSF 1.2 related sites:



Update: we're now already at JSF 2.0/2.1, here's a list of trusted and good JSF 2.0/2.1 related sites:



And, of course, the JSF related articles at this blog. Check them out at the 'Tags' or 'Articles' section in the right column. The JSF wiki page at stackoverflow.com is also a nice starting point. Further I've collected all top Stack Overflow answers at JSF.ZEEf.com.



Source:http://balusc.blogspot.com/2008/06/what-is-it-with-roseindia.html

Uploading files with JSF



WARNING - OUTDATED CONTENT!


This article is targeted on JSF 1.2. For JSF 2.0/2.1 with Tomahawk, please checkout my answer on this Stackoverflow.com question. For JSF 2.0/2.1 on Servlet 3.0 with a custom component, please checkout this article. For JSF 2.2, just use its native file upload component in flavor of whose value can be tied to a javax.servlet.http.Part property.







Upload and store files


Downloading files is made relatively easy using a FileServlet, but uploading files is a bit harder. Entering/selecting the raw absolute file path in h:inputText and sending it to the server so that it can be used in a File object isn't going to work, as the server doesn't have access to the client's file system. That will work only if the server as well as the client runs on the same machine and that wouldn't occur in real life.



To browse and select a file for upload you basically need a HTML input type="file" field in the form. As stated in the HTML specification you have to use the POST method and the enctype attribute of the form have to be set to "multipart/form-data". Unfortunately the Sun JSF Reference Implementation Mojarra doesn't provide a component out of the box which renders a input type="file" field. But the MyFaces Tomahawk component library, which can also be integrated in Sun JSF Reference Implementation Mojarra, provides us the t:inputFileUpload component.


Back to top


Integrating Tomahawk in Mojarra


Assuming that you already have a Mojarra environment, you just need to add at least the following JAR's to the classpath, e.g. /WEB-INF/lib. The version numbers doesn't matter that much, as long as you get the newest.



The Tomahawk JAR is the Tomahawk component library itself which under each contains the t:inputFileUpload component and the ExtensionsFilter. The commons-fileupload and commons-io JAR's are required for the file upload. They contains a multipart/form-data parser and several I/O utilities respectively. The commons-logging and commons-el JAR's are required by the core of the Tomahawk component library.


After adding the JAR's, open your web.xml and add the ExtensionsFilter to it. It should filter multipart/form-data requests and make use of the commons-fileupload to parse the request. To get uploading files work in JSF, it should at least be mapped on the servlet name of the FacesServlet, which may differ per environment. By default it is "Faces Servlet". Just check the servlet name in its definition.




Extensions Filter
org.apache.myfaces.webapp.filter.ExtensionsFilter


Extensions Filter
Faces Servlet


It is not required, but you can configure the ExtensionsFilter with one or more of the following useful init-param settings which you can put in the tag:







Set the size limit for uploaded files.
Format: 10 - 10 bytes
10k - 10 KB
10m - 10 MB
1g - 1 GB

uploadMaxFileSize
100m



Set the threshold size - files below this limit are stored
in memory, files above this limit are stored on disk.
Format: 10 - 10 bytes
10k - 10 KB
10m - 10 MB
1g - 1 GB

uploadThresholdSize
100k



Set the path where the intermediary files will be stored.

uploadRepositoryPath
/temp



Back to top


Basic use example


Here is a basic use example of a JSF file and the appropriate backing bean which demonstrates the working of the t:inputFileUpload.



<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://myfaces.apache.org/tomahawk" prefix="t" %>

html>


lang="en">

</span>File upload test<span class="codetag">


id="uploadForm" enctype="multipart/form-data">
columns="3">
for="file" value="Select file" />
id="file" value="#{myBean.uploadedFile}" required="true" />
for="file" style="color: red;" />

/>
value="Submit" action="#{myBean.submit}" />
for="uploadForm" infoStyle="color: green;" errorStyle="color: red;" />



value="file/#{myBean.fileName}" rendered="#{myBean.fileName != null}">
Download back





Please note the enctype of the h:form. This is required to be able to POST binary data. Also note that the download link makes use of the FileServlet. Make sure that it points to the same directory as where the file is uploaded. You can configure it as an init-param.



Here is how the appropriate backing bean (request scoped) look like:



package mypackage;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.myfaces.custom.fileupload.UploadedFile;

public class MyBean {

// Init ---------------------------------------------------------------------------------------

private UploadedFile uploadedFile;
private String fileName;

// Actions ------------------------------------------------------------------------------------

public void submit() {

// Just to demonstrate what information you can get from the uploaded file.
System.out.println("File type: " + uploadedFile.getContentType());
System.out.println("File name: " + uploadedFile.getName());
System.out.println("File size: " + uploadedFile.getSize() + " bytes");

// Prepare filename prefix and suffix for an unique filename in upload folder.
String prefix = FilenameUtils.getBaseName(uploadedFile.getName());
String suffix = FilenameUtils.getExtension(uploadedFile.getName());

// Prepare file and outputstream.
File file = null;
OutputStream output = null;

try {
// Create file with unique name in upload folder and write to it.
file = File.createTempFile(prefix + "_", "." + suffix, new File("c:/upload"));
output = new FileOutputStream(file);
IOUtils.copy(uploadedFile.getInputStream(), output);
fileName = file.getName();

// Show succes message.
FacesContext.getCurrentInstance().addMessage("uploadForm", new FacesMessage(
FacesMessage.SEVERITY_INFO, "File upload succeed!", null));
} catch (IOException e) {
// Cleanup.
if (file != null) file.delete();

// Show error message.
FacesContext.getCurrentInstance().addMessage("uploadForm", new FacesMessage(
FacesMessage.SEVERITY_ERROR, "File upload failed with I/O error.", null));

// Always log stacktraces (with a real logger).
e.printStackTrace();
} finally {
IOUtils.closeQuietly(output);
}
}

// Getters ------------------------------------------------------------------------------------

public UploadedFile getUploadedFile() {
return uploadedFile;
}

public String getFileName() {
return fileName;
}

// Setters ------------------------------------------------------------------------------------

public void setUploadedFile(UploadedFile uploadedFile) {
this.uploadedFile = uploadedFile;
}

}


Note: make "c:/upload" at least configureable. Maybe as a property in a propertiesfile which could also be shared by the FileServlet.



Back to top


Copyright - There is no copyright on the code. You can copy, change and distribute it freely. Just mentioning this site should be fair.


(C) February 2008, BalusC



Source:http://balusc.blogspot.com/2008/02/uploading-files-with-jsf.html

JSF tutorial with Eclipse and Tomcat



Notice


There is a newer JSF 2.0 tutorial out with Eclipse 3.6 SR1 (Helios) and Glassfish v3.







Introduction


In this tutorial you will learn how to setup a Sun JSF RI 1.2 (Mojarra) playground with Eclipse 3.4 (Ganymede) and Apache Tomcat 6.0 (Catalina). A JSF 1.2 environment requires at least the Java 5.0, JSP 2.1 and Servlet 2.5 API's. We'll download and install Java SE 6 SDK, Eclipse 3.4 IDE (with WTP for Java EE development) and Tomcat 6.0 Application server (which supports JSP 2.1 and Servlet 2.5 API's). Additionally we'll also download and install JSTL 1.2 which can be used in combination with JSF, thanks to unified EL.



There are also another IDE's available next to Eclipse, e.g. Sun Netbeans, Sun Java Studio Creator, Oracle JDeveloper, IntelliJ IDEA, etcetera. The choice for Eclipse is made because it's highly configureable, customizeable, has lots of helpful wizards and .. it's free! True, it may eat memory and it may sometimes crash. Just make sure that your environment has enough RAM memory for Java EE development. I recommend at least 2GB of which 1GB is reserved to Eclipse. Also at least a Pentium4 CPU around 3GHz, or a Core 2 Duo CPU around 2GHz, or a Athlon64 CPU around 2.5GHz is recommended. Also make sure that you install trusted plugins the right and clean way, because the well-known Eclipse-instability is almost always caused by bad plugins.


There are also another application servers available next to Apache Tomcat, e.g. Sun Java Application Server (also known as Glassfish in its current release), JBoss Application Server, Mortybay Jetty, Objectweb Jonas, etcetera. The choice for Tomcat is made because it's small, lightweight, relatively fast and is supported by Eclipse by default by an excellent plugin. The only disadvantage of Tomcat is that it doesn't support EJB's. So if you ever want to develop with EJB's, then you'll have to switch to another application server which supports EJB's, such as Glassfish and JBoss AS.


Back to top


Preparing


Create a working directory where you install and store all related files. In this tutorial we'll use C:\Java as working directory. If you want to store it somewhere else, then you'll have to replace every occurence of "C:\Java" throughout the tutorial by the desired directory.


Back to top


Download and install Java SE 6 JDK


The Java SE 6 JDK contains the standard Java API. You can also consider to download and install the Java EE 5 SDK instead which contains the Sun implementation of the enterprise Java API next to the standard Java API. But the Java EE 5 SDK ships with a Glassfish Application Server implementation, while we need the Tomcat Application Server implementation. The Tomcat Application Server implementation already contains at least the javax.el and javax.servlet implementations of the Java EE 5 API, which are required by JSF. The javax.servlet.jsp.jstl implementation, which is also required by JSF, is missing in the Tomcat implementation, but it can be downloaded and installed separately. So we can just skip the download and installation of Java EE 5 SDK, the Java SE 6 JDK is sufficient.



  1. Surf to the Java SE 6 JDK download page.

  2. Pick the latest non-beta JDK without Java EE SDK and/or Netbeans, currently it is called JDK 6 Update 7. Press the Download button.

  3. Choose Platform/Language, accept the License Agreement and press the Continue button.

  4. Click at the link below 'Java SE Development Kit 6u7', you will get the file jdk-6u7-windows-i586-p.exe (naming may differ per version), save it to disk.

  5. Install the JDK and JRE in C:\Java\jdk1.6.0_07 and C:\Java\jre1.6.0_07 respectively.



Back to top


Download and install Eclipse 3.4 IDE


The Eclipse IDE is available in several tastes. As we're going to develop Java EE web applications with JSF, we need the Java EE variant. It contains under each the WTP (Web Tools Platform) which eases the development of web applications. The currently latest version is Eclipse 3.4.



  1. Surf to the Eclipse download page.

  2. Click at the Eclipse IDE for Java EE Developers link.

  3. Download or pick a mirror and you will get the file eclipse-jee-ganymede-win32.zip (naming may differ per version), save it to disk.

  4. Extract the zip and move the child directory \eclipse to C:\Java\eclipse.


Back to top


Download and install Tomcat 6.0


The Tomcat Application Server is available in several releases, each supporting a different JSP/Serlvet specification. As we're going to develop with JSF 1.2, we need at least the Tomcat release supporting JSP 2.1 and Servlet 2.5. However, if you're using another view technology than JSPs, such as Facelets or JSFTemplating, then you can run JSF 1.2 on JSP 2.0 and Servlet 2.4 without issues. This is supported by at least Tomcat 5.5.



  1. Surf to the Tomcat 6.0 download page.

  2. Scroll a bit down the page and under Binary Distributions » Core click at the zip link.

  3. You will get the file apache-tomcat-6.0.18.zip (naming may differ per version), save it to disk.

  4. Extract the zip and move the child directory \apache-tomcat-6.0.18 to C:\Java\apache-tomcat-6.0.18.


Back to top


Download and install JSTL 1.2


The servlet-api.jar of Tomcat doesn't contain the JSTL API, while it is also required by JSF. So we need to download it separately and place it in the classpath of Tomcat.



  1. Surf to the JSTL 1.2 download page.

  2. Click at the jstl-1.2.jar link.

  3. You will get the file jstl-1.2.jar (naming may differ per version), save it to disk.

  4. Move it unchanged to the C:\Java\apache-tomcat-6.0.18\lib directory, which is the main classpath of Tomcat.


NOTE: if you don't have full control over Tomcat (e.g. production server or shared hosting server), then you should rather put the jstl-1.2.jar in the /WEB-INF/lib of your web project.


Back to top


Download and install Mojarra 1.2


Since the 1.2_07 release of Sun JSF RI, the Sun JSF RI project got a codename called "Mojarra". You can find the project home page at http://javaserverfaces.dev.java.net.



  1. Surf to the Mojarra download page.

  2. Download the binary of the latest release, so click at the 1.2_09 binary link.

  3. You will get the file mojarra-1.2_09-b02-FCS-binary.zip (naming may differ per version), save it to disk.

  4. Extract the zip and move the child directory mojarra-1.2_09-b02-FCS to C:\Java\mojarra-1.2_09-b02-FCS.


Back to top


Run and configure Eclipse



  1. Run C:\Java\eclipse\eclipse.exe. You will be asked to select a workspace. Point it to C:\Java\workspace.

  2. On the welcome screen, click at the icon with the curved arrow at the right side: Go to the workbench.

  3. In the top menu, go to Window » Preferences » Java » Installed JREs. Select the current JRE (it should automatically be the same as you have installed, in this case the jre1.6.0_07, located at C:\Java\jre1.6.0_07) and click Edit. Select the C:\Java\jre1.6.0_07\lib\rt.jar, click at Source Attachment, click at External File, navigate to C:\Java\jdk1.6.0_07, select the src.zip file and add it. Now the source code of the Java SE API is available in Eclipse.

  4. In the Preferences dialogue, go to Web » JavaServer Faces Tools » Libraries and click New. Give the library an unique name, e.g. Mojarra 1.2_09. Set Version Supported to v1_2. Under Library Jars, click Add, navigate to C:\Java\mojarra-1.2_09-b02-FCS\lib, select the both JAR's jsf-api.jar and jsf-impl.jar and add them. Check Is JSF Implementation and click Finish.
    Note: since Eclipse 3.6, it has been moved into Java » Build Path » User Libraries. You should define it over there or just skip this step.

  5. In the Preferences dialogue, go to Web » JSP Files » Editor » Templates and click New. Enter name New JavaServer Faces (JSF) Page (HTML5), select context New JSP, enter description JSF with HTML5 markup and default view setup, copypaste the following snippet in the pattern field and click OK:
    <%@taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
    <%@taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
    <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

    html>


    lang="en">

    </span>Insert title here<span class="codetag">


    ${cursor}




  6. In the Prefrences dialogue, go to Web » JavaServer Faces Tools » Validation and under Type Assignment Problems set Method expression signature incompatibility to Warning or Ignore if you want to allow JSF action methods return void. I also recommend to set the Unary operation number (and boolean) coercion problems under Type Coercion Problems to Warning or Ignore, because it would unnecessarily give an error when you're using for example UIComponent#getValue() -which has Object type outcome- in EL but you treated it as number or boolean.
    I have filed a bug about this, vote for it if you agree!

  7. In the Preferences dialogue, go to General » Editors » Text Editors » Spelling and disable it. Really. It will save you from a big annoyment, because it also unnecessarily spellchecks XML documents like web.xml, faces-config.xml and on.

  8. Here are some more screenshots of how I configured some other preferences (Text Editors, HTML Editor and Errors/Warnings):

  9. Click OK to close the Preferences dialogue.


Back to top


Integrate Tomcat in Eclipse



  1. At the bottom box click at the Servers tab. Rightclick at the box and choose New » Server. In the wizard, select the server type Apache » Tomcat v6.0 Server and click Next. In the next page, click at Browse, point to C:\Java\apache-tomcat-6.0.18 and click Finish. Now Tomcat is integrated in Eclipse.

  2. Doubleclick the Tomcat server entry in the Servers tab, you'll get the server configuration. At the left column, under Server Locations, select Use Tomcat installation. This way Eclipse will take full control over Tomcat, so that you will be able to access the default Tomcat homepage with the Tomcat Manager at http://localhost:8080 when running from inside Eclipse. Optionally also check Publish module contexts to separate XML files under Server options. Otherwise Eclipse will modify the Tomcat's server.xml to its own taste, which may cause a XML validation warning with "[SetPropertiesRule]{Server/Service/Engine/Host/Context}" during Tomcat startup (which actually doesn't harm at all). At the right column, under Ports, please note the HTTP/1.1 port. This defaults to 8080, keep it in mind. You can change it there if you want.

  3. At the left column, under General Information, click Open launch configuration, navigate to tab Arguments, in the field VM arguments add the following argument at the end (separated with a space):

    -Dorg.apache.el.parser.COERCE_TO_ZERO=false

    This will fix an unwanted feature in the EL implementation which was introduced along with Tomcat 6.0.16 (empty number fields become 0 and so on). Also see this bug and the links in it. Click OK to close the launch configuration properties and save the configuration by choosing File » Save in the top menu or by pressing CTRL+S. Close the server configuration by clicking at the cross of the tab, or by pressing CTRL+F4.

  4. Rightclick the Tomcat server entry in the Servers tab and choose Start. You can also start it by clicking at the green arrow at the toolbar of the box. If you're running a firewall, you'll probably get kind of a warning during the first time of Tomcat startup. Just accept/allow/unblock it.

  5. Once it is started, go to http://localhost:8080 (where 8080 is supposed to be the HTTP/1.1 port of Tomcat). You should get the default Tomcat home page.

    If you get a timeout or kind of an unknown host error message, then doublecheck if Tomcat is configured properly (you should have selected Use Tomcat installation in step 2 and use the right port number) and if it is started properly. In Eclipse you can find the Tomcat logs at the Console tab of the bottom dialogue box.

  6. You can stop the server by rightclicking at the Tomcat server entry in the Servers tab and choose Stop. You can also stop it by clicking at the red square at the toolbar of the box.


Back to top


Prepare JSF web project in Eclipse



  1. At the left box open the Project Explorer tab if not already opened. Rightclick at the box and choose New » Dynamic Web Project.

  2. In the wizard, give it the Project name Playground, verify if Target Runtime is set to Apache Tomcat v6.0 and Dynamic Web Module version is set to 2.5. Under Configuration select JavaServer Faces v1.2 project and click Next.

  3. In the next page, you may change the module settings to your taste. Personally I like to have URL's always in lowercase, so I change the default Context Root from Playground to playground. Click Next.

  4. In the next page, you need to define JSF Capabilities. At JSF Libraries, select Mojarra 1.2_09 (which we have definied in the preferences). At URL Mapping Patterns, select the default /faces/* and remove it. Then add a new pattern with the value *.jsf. Finally click Finish.
    Note: since Eclipse 3.6, the library selection has been changed. You should select User Library or just Disable Library Configuration and supply the JAR files in /WEB-INF/lib yourself.

  5. During the creation of the web project you'll probably get a license agreement popup for the facesconfig_1_2.xsd file from sun.com. If you don't have any intentions to do bad things, just click at I Agree.

  6. After creation of the web project, you should get a directory structure similar to the screenshot below.



Back to top


Create JSF hello world in Eclipse - The Backing Bean



  1. Create a backing bean class: open the Playground project, rightclick at Java Resources folder and choose New » Class.

  2. Enter the package name mypackage, enter the class name MyBean, keep the other fields default and click Finish. The package and the class will be created and the editor box will show the class source.

  3. Add two properties to the bean:


    private String input;
    private String output;



  4. Add getters and setters: the input property will be used by an UIInput component, so it require both a getter and a setter. The output property will be used by an UIOutput component, so it require at least a getter. The setter is optional, but it won't be used by the JSF component. Rightclick somewhere at one of the both properties inside the source editor, choose Source » Generate Getters and Setters, or hit ALT+SHIFT+S, then R. In the wizard, select the desired getters and setters, if necessary choose the insertion point (I like to have getters and setters at the whole bottom of the class) and the sorting (I like to have getters first and then setters) and then click at OK. Eclipse will generate the suitable getters and setters. Useful if you ever would have a lot of properties. If necessary, hit CTRL+SHIFT+F to format the code again so that methods get separated by a blank line. You can configure formatting preferences in Window » Preferences » Java » Code Style » Formatter.

  5. Add an action method to the bean:


    public void action() {
    output = "Welcome at the JSF world, " + input;
    }


    Save the mypackage.MyBean by choosing File » Save in the top menu or by pressing CTRL+S.

  6. Define the backing bean in the faces-config.xml: doubleclick the file WebContent/WEB-INF/faces-config.xml to open the Faces Configuration editor. Navigate to the ManagedBean tab, select the request scope and click Add.

  7. In the wizard, enter the qualified class name mypackage.MyBean or click Browse and enter MyBean to get the matching items and select the mypackage.MyBean. Click next and verify if the managed bean name is set to myBean. Finally click at Finish.

  8. Go to the Source tab to see the managed bean entry. If necessary, hit CTRL+SHIFT+F to get the XML formatted. Save the faces-config.xml by choosing File » Save in the top menu or by pressing CTRL+S.


Back to top


Create JSF hello world in Eclipse - The JSF file



  1. Create a JSF file: rightclick at WebContent folder of the Playground project and choose New » JSP. Enter the File name test.jsp, click Next, select the template New JavaServer Faces (JSF) Page (HTML5) (which we have definied in the preferences) and click Finish.

  2. Add a basic form to the body of the test.jsp:

    for="input" value="Enter your name:" />
    id="input" value="#{myBean.input}" required="true" />
    value="submit" action="#{myBean.action}" />
    value="#{myBean.output}" />


    Save the test.jsp by choosing File » Save in the top menu or by pressing CTRL+S.


Back to top


Run JSF web project in Tomcat



  1. Rightclick the Tomcat server entry in the Servers tab and choose Add and Remove Projects. In the wizard, select the Playground project under Available Projects and click Add to add it to Configured Projects. Click Finish.

  2. Rightclick the Tomcat server entry in the Servers tab and choose Start. You can also start it by clicking at the green arrow at the toolbar of the box.

  3. Once it is started, go to http://localhost:8080/playground/test.jsf. Note the .jsf extension, it will be covered by the FacesServlet mapping in the WebContent/WEB-INF/web.xml. So this request will be passed through the FacesServlet and the FacesServlet will map it to the default JSP extension, which is .jsp. The FacesServlet will also create the FacesContext and pass the specific request through the JSF lifecycle.

    If you get a timeout or kind of an unknown host error message, then doublecheck if Tomcat is started properly and if the port is correct. If you get an internal server error exception, then doublecheck if the code is all correct. Also try to interpret and understand the exception message and the trace, if necessary with help of Google. In Eclipse you can find the Tomcat logs at the Console tab of the bottom dialogue box.


Back to top


And now?


Play with it!


This whole blog site contains lot of useful JSF material. You can find them in the Articles section at the right column of this blog site. Copy'n'paste them, or, preferably, type it over, and play, experiment and run it. The most popular and recommendable articles are the following:



Here are the most important JSF related links to be bookmarked and read thoroughly:


  • JSF specification (pick the 1st download link), it explains why JSF is there, how it works and what it all provides.

  • JSF API documentation, it contains detailed javadocs of the JSF API classes, it explains where the classes are for, how to use them and what all fields/methods do.

  • JSF TLD documentation, it shows which JSF tags are all available, what they all do and which attributes they supports.

  • Java EE tutorial, chapter 10 and on contains Sun's own JSF tutorial.

  • If you want to get a book, I highly recommend the JSF: The Complete Reference, one of its authors, Ed Burns, is the lead of the JSF specification.


You may want to checkout Facelets as replacement of JSP as view technology for JSF components. It offers much more advantages over JSP and is going to be included in the upcoming JSF 2.0 as default view technology.


Finally you can check the Favorites section at the right column of this blog site for more interesting links.


Back to top


Copyright - None of this article may be taken over without explicit authorisation.


(C) January 2008, BalusC



Source:http://balusc.blogspot.com/2008/01/jsf-tutorial-with-eclipse-and-tomcat.html

Action dependent requireness


Introduction


There are scenarios where you want to depend the "requireness" (between quotes, this word doesn't occur in an English dictionary) of an UIInput element on the UICommand action invoked. There are also a lot of hacks and workarounds written about it, e.g. using immediate="true" and valueChangeListener or binding attributes to retain the value (which gives you only two scenario cases) or moving the validation to the backing bean actions (which gives you endless scenario cases), etcetera.




Those workarounds require extra logic in the backing bean. It would be great if JSF offers an default possibility to let the requireness of the UIInput depend on the UICommand action invoked. Having an attribute like requiredActions which accepts a commaseparated string of the ID's of the buttons would be great. Unfortunately such an attribute isn't available. But don't feel disappointed, there is a possibility to use the request parameter map to determine which UICommand action invoked. Its client ID is namely available in the request parameter map. So just checking the presence of the client ID in the #{param} ought to be enough. KISS! ;)


Back to top


Basic JSF example



Here is a sample form. It represents a login form with two input fields and two buttons. The username as well as the password fields are required when you press the "Login" button, while the password field isn't required when you press the "Forget password" button. This is done by checking the presence of the client ID of the "Login" button in the required attribute of the password field. You can also check the absence of the client ID of the "Forget password" button as well.


The stuff is tested in a Java EE 5.0 environment with Tomcat 6.0 with Servlet 2.5, JSP 2.1 and JSF 1.2_07 (currently called Mojarra).



 id="form">
columns="3">
for="username" value="Username" />
id="username" value="#{myBean.username}"
required="true" />
for="username" style="color: red;" />

for="password" value="Password" />
id="password" value="#{myBean.password}"
required="#{!empty param['form:login']}" />
for="password" style="color: red;" />

/>

id="login" value="Login" action="#{myBean.login}" />
id="forget" value="Forget password" action="#{myBean.forget}" />

for="form" style="color: green;" />



The appropriate test backing bean (request scoped) look like:



package mypackage;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;

public class MyBean {

// Init ---------------------------------------------------------------------------------------

private String username;
private String password;

// Actions ------------------------------------------------------------------------------------

public void login() {

// Just for debug. Don't do this in real! Hash the password, compare in DB and forget it ;)
System.out.println("Login username: " + username);
System.out.println("Login password: " + password);

// Show succes message.
FacesContext.getCurrentInstance().addMessage("form", new FacesMessage("Login succesful!"));
}

public void forget() {

// Just for debug.
System.out.println("Forget username: " + username);

// Show succes message.
FacesContext.getCurrentInstance().addMessage("form", new FacesMessage("New password sent!"));
}

// Getters ------------------------------------------------------------------------------------

public String getUsername() {
return username;
}

public String getPassword() {
return password;
}

// Setters ------------------------------------------------------------------------------------

public void setUsername(String username) {
this.username = username;
}

public void setPassword(String password) {
this.password = password;
}

}


Now, when you hit the "Login" button, it will validate the username as well as the password fields, but when you hit the "Forget password" button, it will validate the username field only!



Back to top



Copyright - There is no copyright on the code. You can copy, change and distribute it freely. Just mentioning this site should be fair.


(C) December 2007, BalusC




Source:http://balusc.blogspot.com/2007/12/action-dependent-requireness.html

Rabu, 29 Januari 2014

Set focus and highlight in JSF


Notice

This article is targeted on JSF 1.2. Whilst this can be used in JSF 2.0 as well, a better JSF 2.0 implementation is provided by OmniFaces with its component. See also showcase example here.




The power of a PhaseListener

This article shows how to use a PhaseListener to set focus to the first input element which has a FacesMessage (which can be caused by a validation or conversion error or any other custom reason) and highlight all elements which has a FacesMessage. It is relatively simple, it costs effectively only a few lines inside the beforePhase of the RENDER_RESPONSE, two small Javascript functions for the focus and highlight and a single CSS class for the highlight.

Here is a sample form. Note the Javascript which should be placed at the very end of the HTML body, at least after the input element which should be focused and highlighted. The stuff is tested in a Java EE 5.0 environment with Tomcat 6.0 with Servlet 2.5, JSP 2.1 and JSF 1.2_07 (currently called Mojarra).

 id="form">
columns="3">
for="input1" value="Enter input 1" />
id="input1" value="#{myBean.input1}" required="true" />
for="input1" style="color: red;" />

for="input2" value="Enter input 2" />
id="input2" value="#{myBean.input2}" required="true" />
for="input2" style="color: red;" />

for="input3" value="Enter input 3" />
id="input3" value="#{myBean.input3}" required="true" />
for="input3" style="color: red;" />

/>
value="Submit" action="#{myBean.doSomething}" />
/>



This is how the Javascript functions setFocus() and setHighlight() should look like:

/**
* Set focus on the element of the given id.
* @param id The id of the element to set focus on.
*/

function setFocus(id) {
var element = document.getElementById(id);
if (element && element.focus) {
element.focus();
}
}

/**
* Set highlight on the elements of the given ids. It basically sets the classname of the elements
* to 'highlight'. This require at least a CSS style class '.highlight'.
* @param ids The ids of the elements to be highlighted, comma separated.
*/

function setHighlight(ids) {
var idsArray = ids.split(",");
for (var i = 0; i < idsArray.length; i++) {
var element = document.getElementById(idsArray[i]);
if (element) {
element.className = 'highlight';
}
}
}

And now the CSS style class for the highlight:

.highlight {
background-color: #fcc;
}

And finally the PhaseListener which sets the focus to the first input element which has a FacesMessage and highlights all input elements which has a FacesMessage:

/*
* net/balusc/webapp/SetFocusListener.java
*
* Copyright (C) 2007 BalusC
*
* This program is free software: you can redistribute it and/or modify it under the terms of the
* GNU Lesser General Public License as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this library.
* If not, see .
*/


package net.balusc.webapp;

import java.util.Iterator;

import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;

/**
* This phase listener checks if there is a client ID with message and will set the client ID as
* ${focus} in the request map. It will also gather all client IDs with message and will set it as
* ${highlight} in the request map.
*


* This phase listener should be configured in the faces-config.xml as follows:
*


* <lifecycle>
* <phase-listener>net.balusc.webapp.SetFocusListener</phase-listener>
* </lifecycle>
*

*
* @author BalusC
* @link http://balusc.blogspot.com/2007/12/set-focus-in-jsf.html
*/

public class SetFocusListener implements PhaseListener {

// Actions ------------------------------------------------------------------------------------

/**
* @see javax.faces.event.PhaseListener#getPhaseId()
*/

public PhaseId getPhaseId() {

// Listen on render response phase.
return PhaseId.RENDER_RESPONSE;
}

/**
* @see javax.faces.event.PhaseListener#beforePhase(javax.faces.event.PhaseEvent)
*/

public void beforePhase(PhaseEvent event) {

// Init.
FacesContext facesContext = event.getFacesContext();
String focus = null;
StringBuilder highlight = new StringBuilder();

// Iterate over all client ID's with messages.
Iterator clientIdsWithMessages = facesContext.getClientIdsWithMessages();
while (clientIdsWithMessages.hasNext()) {
String clientIdWithMessages = clientIdsWithMessages.next();
if (focus == null) {
focus = clientIdWithMessages;
}
highlight.append(clientIdWithMessages);
if (clientIdsWithMessages.hasNext()) {
highlight.append(",");
}
}

// Set ${focus} and ${highlight} in JSP.
facesContext.getExternalContext().getRequestMap().put("focus", focus);
facesContext.getExternalContext().getRequestMap().put("highlight", highlight.toString());
}

/**
* @see javax.faces.event.PhaseListener#afterPhase(javax.faces.event.PhaseEvent)
*/

public void afterPhase(PhaseEvent event) {
// Do nothing.
}

}

Define the SetFocusListener as follows in the faces-config.xml:

    
net.balusc.webapp.SetFocusListener


That's all, folks!

Back to top

Copyright - GNU Lesser General Public License

(C) December 2007, BalusC


Source:http://balusc.blogspot.com/2007/12/set-focus-in-jsf.html