• No results found

JSF flow of control The basic steps in using JSF Static navigation One result mapping Dynamic navigation Multiple result mappings Accessing the request and response objects Common JSF problems

N/A
N/A
Protected

Academic year: 2019

Share "JSF flow of control The basic steps in using JSF Static navigation One result mapping Dynamic navigation Multiple result mappings Accessing the request and response objects Common JSF problems"

Copied!
29
0
0

Loading.... (view fulltext now)

Full text

(1)

© 2012 Marty Hall

Customized Java EE Training: http://courses.coreservlets.com/

Java, JSF 2, PrimeFaces, Servlets, JSP, Ajax, jQuery, Spring, Hibernate, RESTful Web Services, Hadoop, Android.

Developed and taught by well-known author and developer. At public venues or onsite at yourlocation.

JSF: Controlling Page

Navigation

Originals of Slides and Source Code for Examples:

http://www.coreservlets.com/JSF-Tutorial/

This somewhat old tutorial covers JSF 1, and is left online for those maintaining existing projects. All new projects should use JSF 2, which is both simpler and more powerful. See http://www.coreservlets.com/JSF-Tutorial/jsf2/.

© 2012 Marty Hall

For live training on JSF 1 or 2, please see

courses at http://courses.coreservlets.com/.

(2)

Topics in This Chapter

JSF flow of control

The basic steps in using JSF

Static navigation

One result mapping

Dynamic navigation

Multiple result mappings

Accessing the request and response

objects

Common JSF problems

5

© 2012 Marty Hall

Customized Java EE Training: http://courses.coreservlets.com/

Java, JSF 2, PrimeFaces, Servlets, JSP, Ajax, jQuery, Spring, Hibernate, RESTful Web Services, Hadoop, Android.

(3)

JSF Flow of Control

(Highly Simplified)

7

Blah.jsp

submit form

POST request Blah.faces InstantiateBean Controller MethodRun Action conditionreturn ChooseJSP forward result1.jspresult2.jsp

... resultN.jsp

Bypass Java code. Form specifies return condition.

faces-config.xml

- beans declared in managed-bean section - mapping of return conditions

declared in navigation-rule section

Business Logic

results

JSF Flow of Control (Simplified)

A form is displayed

Form uses f:view and h:form

The form is submitted to itself

Original URL and

ACTION

URL are http://…/

blah

.faces

A bean is instantiated

Listed in the managed-bean section of faces-config.xml

The action controller method is invoked

Listed in the action attribute of h:commandButton

The action method returns a condition

(4)

Steps in Using JSF

1) Create a bean

A) Properties for form data

B) Action controller method

C) Placeholders for results data

2) Create an input form

A) Input fields refer to bean properties

B) Button specifies return condition

(or action controller method that will return condition)

3) Edit faces-config.xml

A) Declare the bean

B) Specify navigation rules

4) Create results pages

Output form data and results data with h:outputText

5) Prevent direct access to JSP pages

Use a filter that redirects blah.jsp to blah.faces

9

Example: Registration

Started by copying jsf-blank-myfaces

Renamed it to jsf-navigation

Edited .settings/…component file as in previous lecture

Original URL

http://

hostname

/jsf-navigation/register.faces

When form submitted

A static page (WEB-INF/results/result.jsp) is displayed

Static result

No business logic, beans, or Java code of any sort

Main points

Format of original form

(5)

Main Points of This Example

Input form has following format:

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

<f:view>

HTML markup

<h:form>

HTML markup and h:blah tags

</h:form>

HTML markup

</f:view>

faces-config.xml specifies navigation rules:

<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE faces-config PUBLIC …>

<faces-config>

<navigation-rule>

<from-view-id>/blah.jsp</from-view-id> <navigation-case>

<from-outcome>some string</from-outcome>

<to-view-id>/WEB-INF/results/something.jsp</to-view-id> </navigation-case>

</navigation-rule>

</faces-config>

11

Step 1: Create a Bean

Postponed until next lecture

This example ignores form data

Button in form directly specifies return condition

(6)

Step 2: Create Input Form

Basic format

<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> <f:view>

<BODY>

<h:form>

</h:form>

</BODY> </f:view>

Invoking page

Actual file is

blah

.jsp

URL is

blah

.faces

13

Step 2: Create Input Form

The h:form element

ACTION is automatically self (current URL)

METHOD is automatically POST

Elements inside h:form

Use special tags to represent input elements

• h:inputText corresponds to <INPUT TYPE="TEXT">

• h:inputSecret corresponds to <INPUT TYPE="PASSWORD">

• h:commandButton corresponds to <INPUT TYPE="SUBMIT">

In later sections, we will see that input elements will be associated

with bean properties

For static navigation, specify simple string as action of

h:commandButton

• String must match navigation rule from faces-config.xml

More info on h:

blah

elements

http://java.sun.com/j2ee/javaserverfaces/1.1/docs/tlddocs/

(7)

Step 2: Example Code

(register.jsp)

<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> <f:view>

<!DOCTYPE …> <HTML>

<HEAD>…</HEAD> <BODY>

<CENTER>

<TABLE BORDER=5>

<TR><TH CLASS="TITLE">New Account Registration</TH></TR> </TABLE>

<P> <h:form>

Email address: <h:inputText/><BR> Password: <h:inputSecret/><BR>

<h:commandButton value="Sign Me Up!" action="register"/> </h:form>

</CENTER></BODY></HTML> </f:view>

15

Step 2: Result

File is …/WebContent/register.jsp

(8)

Step 3: Edit faces-config.xml

General format

<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE faces-config PUBLIC …>

<faces-config>

</faces-config>

Specifying the navigation rules

<faces-config>

<navigation-rule>

<from-view-id>/the-input-form.jsp</from-view-id> <navigation-case>

<from-outcome>string-from-action</from-outcome> <to-view-id>/WEB-INF/…/something.jsp</to-view-id> </navigation-case>

</navigation-rule> </faces-config>

17

Step 3: Example Code

<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE faces-config PUBLIC …>

<faces-config>

<navigation-rule>

<from-view-id>/register.jsp</from-view-id>

<navigation-case>

<from-outcome>register</from-outcome>

<to-view-id>/WEB-INF/results/result.jsp</to-view-id>

</navigation-case> </navigation-rule> </faces-config>

(9)

Step 4: Create Results Pages

RequestDispatcher.forward used

So page can/should be in WEB-INF

Example code:

…/WEB-INF/results/result.jsp

<!DOCTYPE …> <HTML>

<HEAD>…</HEAD> <BODY>

<CENTER>

<TABLE BORDER=5>

<TR><TH CLASS="TITLE">Success</TH></TR> </TABLE>

<H2>You have registered successfully.</H2> </CENTER>

</BODY></HTML>

19

Step 4: Example Result

(10)

Step 5: Prevent Direct Access

to JSP Pages

Filename/URL correspondence

Actual files are of the form

blah

.jsp

URLs used are of the form

blah

.faces

You must prevent clients from directly accessing JSP

pages

Since they would give erroneous results

Strategies

You cannot put input-form JSP pages in WEB-INF

Because URL must correspond directly to file location

So, use filter in web.xml. But:

You have to know the extension (.faces)

Assumes no non-JSF .jsp pages

This is a major drawback to JSF design

21

Direct Access to JSP Pages

(11)

Preventing Direct Access:

FacesRedirectFilter

public class FacesRedirectFilter implements Filter { private final static String EXTENSION = "faces";

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {

HttpServletRequest request = (HttpServletRequest)req; HttpServletResponse response = (HttpServletResponse)res; String uri = request.getRequestURI();

if (uri.endsWith(".jsp")) { int length = uri.length(); String newAddress =

uri.substring(0, length-3) + EXTENSION; response.sendRedirect(newAddress);

} else { // Address ended in "/"

response.sendRedirect("index.faces"); }

} ...

23

Preventing Direct Access:

web.xml

...

<filter>

<filter-name>faces-redirect-filter</filter-name> <filter-class>

coreservlets.FacesRedirectFilter </filter-class>

</filter>

<filter-mapping>

<filter-name>faces-redirect-filter</filter-name> <url-pattern>*.jsp</url-pattern>

(12)

Preventing Direct Access:

Result

Either URL

– http://localhost/jsf-navigation/register.faces – http://localhost/jsf-navigation/register.jsp

25

© 2012 Marty Hall

Customized Java EE Training: http://courses.coreservlets.com/

Java, JSF 2, PrimeFaces, Servlets, JSP, Ajax, jQuery, Spring, Hibernate, RESTful Web Services, Hadoop, Android.

(13)

JSF Flow of Control

(Simplified)

27

Blah.jsp

submit form

POST request Blah.faces InstantiateBean Controller MethodRun Action conditionreturn ChooseJSP forward result1.jspresult2.jsp

... resultN.jsp faces-config.xml

- beans declared in managed-bean section

- mapping of return conditions declared in navigation-rule section

Business Logic

results

JSF Flow of Control (Simplified)

A form is displayed

Form uses f:view and h:form

The form is submitted to itself

Original URL and

ACTION

URL are http://…/

blah

.faces

A bean is instantiated

Listed in the managed-bean section of faces-config.xml

The action controller method is invoked

Listed in the action attribute of h:commandButton

The action method returns a condition

(14)

Steps in Using JSF

1) Create a bean

A) Properties for form data

B) Action controller method

C) Placeholders for results data

2) Create an input form

A) Input fields refer to bean properties

B) Button specifies action controller method that will return condition

3) Edit faces-config.xml

A) Declare the bean

B) Specify navigation rules

4) Create results pages

Output form data and results data with h:outputText

5) Prevent direct access to JSP pages

Use a filter that redirects blah.jsp to blah.faces

29

Example: Health Plan Signup

Original URL

http://

hostname

/jsf-navigation/signup.faces

Collects info to see if user qualifies for health plan

When form submitted, one of two possible

results will be displayed

User is accepted into health plan

User is rejected from health plan

Main points

Specifying an action controller in the form

Creating an action controller method in the bean

Using faces-config.xml to

Declare bean

Map return conditions to output pages

(15)

Main Points of This Example

Specify the controller with #{beanName.methodName}

<h:commandButton

value="Sign Me Up!"

action="#{healthPlanController.signup}"/>

Controller method returns strings corresponding to conditions

– If null is returned, the form is redisplayed

– Unlike with Struts, the controller need not extend a special class

Use faces-config.xml to declare the controller as follows

<faces-config> <managed-bean>

<managed-bean-name>controller name</managed-bean-name>

<managed-bean-class>controller class</managed-bean-class>

<managed-bean-scope>request</managed-bean-scope> </managed-bean>

</faces-config>

Add multiple navigation-rule entries to faces-config.xml

– One for each possible string returned by the controller – If no string matches, the form is redisplayed

31

Scope could also be session or application

Step 1: Create a Bean

(A) Properties for form data

Postponed until next lecture

(B) Action controller method

public class HealthPlanController {

public String signup() { if (Math.random() < 0.2) {

return("accepted"); } else {

return("rejected"); }

(16)

Step 2: Create Input Form

Same general syntax as in previous example

Except for action of commandButton

<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> <f:view>

<h:form>

First name: <h:inputText/><BR> Last name: <h:inputText/><BR> ...

<h:commandButton

value="Sign Me Up!"

action="#{healthPlanController.signup}"/>

</h:form>… </f:view>

33

Step 2: Result

File is …/WebContent/signup.jsp

URL is http://localhost/jsf-navigation/signup.faces

(17)

Step 3: Edit faces-config.xml

(A) Declaring the bean

<faces-config> <managed-bean>

<managed-bean-name> healthPlanController </managed-bean-name> <managed-bean-class>

coreservlets.HealthPlanController </managed-bean-class>

<managed-bean-scope>request</managed-bean-scope> </managed-bean>

</faces-config>

35

Use request scope unless you have a specific reason to use session scope or (rarely) application scope

Step 3: Edit faces-config.xml

(B) Specifying navigation rules

Outcomes should match return values of controller

<faces-config>

(bean definitions

from previous page)

<navigation-rule>

<from-view-id>/signup.jsp</from-view-id> <navigation-case>

<from-outcome>accepted</from-outcome>

(18)

Step 4: Create Results Pages

…/WEB-INF/results/accepted.jsp

<!DOCTYPE …>

<HTML>

<HEAD>…</HEAD>

<BODY>

<CENTER>

<TABLE BORDER=5>

<TR><TH CLASS="TITLE">Accepted!</TH></TR>

</TABLE>

<H2>You are accepted into our health plan.</H2>

Congratulations.

</CENTER>

</BODY></HTML>

37

Step 4: Create Results Pages

(Continued)

…/WEB-INF/results/rejected.jsp

<!DOCTYPE …>

<HTML>

<HEAD>…</HEAD>

<BODY>

<CENTER>

<TABLE BORDER=5>

<TR><TH CLASS="TITLE">Rejected!</TH></TR>

</TABLE>

<H2>You are rejected from our health plan.</H2>

Get lost.

</CENTER>

</BODY></HTML>

(19)

Step 4: Results

39

Step 5: Prevent Direct Access

to JSP Pages

Use filter that captures url-pattern *.jsp

(20)

© 2012 Marty Hall

Customized Java EE Training: http://courses.coreservlets.com/

Java, JSF 2, PrimeFaces, Servlets, JSP, Ajax, jQuery, Spring, Hibernate, RESTful Web Services, Hadoop, Android.

Developed and taught by well-known author and developer. At public venues or onsite at yourlocation.

Notes and

Additional Capabilities

Summary

Wildcards in navigation rule

* for from-view-id matches any starting page

Omitting from-outcome results in all values matching

from-action in addition to from-outcome

For when different buttons invoke different methods and methods

have same values mapped differently. Overused.

Getting the request and response objects

ExternalContext context =

FacesContext.getCurrentInstance().getExternalContext(); HttpServletRequest request =

(HttpServletRequest)context.getRequest(); HttpServletResponse response =

(HttpServletResponse)context.getResponse();

Interleaving managed-bean & navigation-rule

It is legal to alternate back and forth

(21)

Wildcards in Navigation Rules

* for from-view-id matches any starting page

Used when multiple different pages map same return

value to same result page

Example

<navigation-rule>

<from-view-id>*</from-view-id> <navigation-case>

<from-outcome>success</from-outcome>

<to-view-id>/WEB-INF/results/success.jsp</to-view-id> </navigation-case>

</navigation-rule>

43

Without Wildcards

<navigation-rule>

<from-view-id>/page1.jsp</from-view-id> <navigation-case>

<from-outcome>condition1</from-outcome>

<to-view-id>/WEB-INF/results/result1.jsp</to-view-id> </navigation-case>

<navigation-case>

<from-outcome>unknown-user</from-outcome>

<to-view-id>/WEB-INF/results/unknown.jsp</to-view-id> </navigation-case>

</navigation-rule> <navigation-rule>

<from-view-id>/page2.jsp</from-view-id> <navigation-case>

(22)

With Wildcards

<navigation-rule> <from-view-id>*</from-view-id> <navigation-case> <from-outcome>unknown-user</from-outcome> <to-view-id>/WEB-INF/results/unknown.jsp</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <from-view-id>/page1.jsp</from-view-id> <navigation-case> <from-outcome>condition1</from-outcome> <to-view-id>/WEB-INF/results/result1.jsp</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <from-view-id>/page2.jsp</from-view-id> <navigation-case> <from-outcome>condition2</from-outcome> <to-view-id>/WEB-INF/results/result2.jsp</to-view-id> </navigation-case> </navigation-rule> 45

Wildcard Matching Return

Conditions

Omitting from-outcome means all other

return conditions match

Except for null, which always means redisplay form

(23)

Explicit from-outcome

<navigation-rule>

<from-view-id>/page1.jsp</from-view-id> <navigation-case>

<from-outcome>condition1</from-outcome>

<to-view-id>/WEB-INF/results/result1.jsp</to-view-id> </navigation-case>

<navigation-case>

<from-outcome>condition2</from-outcome>

<to-view-id>/WEB-INF/results/result2.jsp</to-view-id> </navigation-case>

<navigation-case>

<from-outcome>condition3</from-outcome>

<to-view-id>/WEB-INF/results/result2.jsp</to-view-id> </navigation-case>

<navigation-case>

<from-outcome>condition4</from-outcome>

<to-view-id>/WEB-INF/results/result2.jsp</to-view-id> </navigation-case>

</navigation-rule>

47

Default (Omitted) from-outcome

<navigation-rule>

<from-view-id>/page1.jsp</from-view-id> <navigation-case>

<from-outcome>condition1</from-outcome>

<to-view-id>/WEB-INF/results/result1.jsp</to-view-id> </navigation-case>

<navigation-case>

<to-view-id>/WEB-INF/results/result2.jsp</to-view-id> </navigation-case>

(24)

from-action

Designates the method that you came from

Suppose you had two buttons that invoked two different methods,

and both returned "error". But you want the two "error" values to

have different results pages.

<navigation-rule> <from-view-id>/somepage.jsp</from-view-id> <navigation-case> <from-action>#{beanName.method1}</from-action> <from-outcome>error</from-outcome> <to-view-id>/WEB-INF/results/err1.jsp</to-view-id> </navigation-case> <navigation-case> <from-action>#{beanName.method2}</from-action> <from-outcome>error</from-outcome> <to-view-id>/WEB-INF/results/err2.jsp</to-view-id> </navigation-case> </navigation-rule>

Easier to avoid using the same names for different things

Rarely needed in real life, but some books (

JSF The Complete

Reference

) use it needlessly.

49

Getting the Request

and Response Objects

JSF controller methods do not have direct

access to the request and response

Unlike in Struts, where controller method (execute) gets

request and response automatically

If they are needed, use static method calls to get them

ExternalContext context =

FacesContext.getCurrentInstance().getExternalContext(); HttpServletRequest request =

(HttpServletRequest)context.getRequest(); HttpServletResponse response =

(HttpServletResponse)context.getResponse();

In some environments, you cast results of getRequest and

getResponse to values other than HttpServletRequest and

HttpServletResponse

E.g., in a portlet environment, you might cast result to

PortletRequest and PortletResponse

(25)

Getting the Request

and Response Objects

Purpose

Useful for many request properties

Explicit session manipulation (e.g., changing inactive

interval or invalidating session)

Explicit cookie manipulation (e.g., long-lived cookies)

Reading request headers (e.g., User-Agent)

Looking up requesting host name

Not needed to get request parameters

– Bean populated automatically as in next lecture

Useful for a few response properties

Setting status codes

Setting response headers

Setting long-lived cookies

51

Interleaving managed-bean and

navigation-rule

If you have several different addresses in

your app, it is OK to alternate

<managed-bean> Stuff for bean1 </managed-bean> <navigation-rule>

Rules for address that uses bean1 </navigation-rule>

(26)

© 2012 Marty Hall

Customized Java EE Training: http://courses.coreservlets.com/

Java, JSF 2, PrimeFaces, Servlets, JSP, Ajax, jQuery, Spring, Hibernate, RESTful Web Services, Hadoop, Android.

Developed and taught by well-known author and developer. At public venues or onsite at yourlocation.

Common Problems

Pressing Button and Nothing

Happens

In JSF, many error conditions simply result

in the system redisplaying the form

No error messages or warnings

Very confusing to beginning developers

Debugging strategies for these situations

Many of the errors cause the process to abort at certain

points. Knowing how far things got is very helpful.

Use print statements or IDE breakpoints

Put a print statement in the controller method

Put a print statement in the empty constructor

– public MyBean() { System.out.println("MyBean built"); }

– Bean should be instantiated twice for request scope

Put print statements in the bean setter methods

(27)

Pressing Button and Nothing

Happens: Common Cases

1.

Return value of controller method does not

match from-outcome of navigation-case

Remember values are case sensitive

2.

Using from-action instead of from-outcome

<navigation-case>

<from-action>accepted</from-action>

<to-view-id>/WEB-INF/results/accepted.jsp</to-view-id>

</navigation-case>

This is really a special case of (1), since there is now

no

from-outcome

This situation occurs frequently with Eclipse users that

don't look carefully at the choices Eclipse offers in

popup menu for the navigation-case entries.

55

Should be from-outcome, not from-action

Pressing Button and Nothing

Happens: Common Cases

3.

Forgetting # in action of h:commandButton

<h:commandButton

value="Button Label"

action="{beanName.methodName}"/>

This is really a special case of (1), since

action="beanName.methodName" means the literal

String "beanName.methodName" is the from-outcome

In this situation and several others, it is very helpful to

put a print statement in controller method to see if/when

it is invoked

(28)

Pressing Button and Nothing

Happens: Common Cases

5.

Controller method returns null

This is often done on purpose to redisplay the form, but can be

done accidentally as well.

6.

Type conversion error

You declare field to be of type int, but value is not an integer

when you submit.

• Behavior of redisplaying form is useful here. See validation section.

7.

Missing setter method

You associate textfield with bean property foo, but there is no

setFoo method in your bean.

• Debugging hint: You will see printout for bean being instantiated, but not for controller method

8.

Missing h:form

If you use h:inputText with no surrounding h:form, textfields will

still appear but nothing will happen when you press submit button

57

Summary

Basic steps to using JSF

Create a bean

• For now, only contains controller method

Create an input form

• The action of h:commandButton refers to controller method

Edit faces-config.xml

• Declare bean

• Define navigation rules

Create results pages

Prevent direct access to JSP pages

Static navigation

Specify literal outcome as action of button

• Outcome mapped by faces-config.xml to output page

Dynamic navigation

Specify method as action of button

Method returns outcomes

• Outcomes mapped by faces-config.xml to output pages

(29)

© 2012 Marty Hall

Customized Java EE Training: http://courses.coreservlets.com/

Java, JSF 2, PrimeFaces, Servlets, JSP, Ajax, jQuery, Spring, Hibernate, RESTful Web Services, Hadoop, Android.

References

Related documents

The stable storage persistence model is very selective about the events that it subscribes to, and incorporates a garbage collection scheme that performs even in the presence

As illustrated in Figure 1, the asymmetric unit of the title structure consists of one dpma H cation, one dpma molecule, and one iodide anion in the non-centrosymmetric space group

Data collection: APEX2 (Bruker, 2009); cell refinement: SAINT (Bruker, 2009); data reduction: SAINT; program(s) used to solve structure: SHELXTL (Sheldrick, 2008); program(s) used

The density of mites as a community and the density of particular mite groups are higher in winter rye crop in comparison with potato.. Winter sown crops, being

The cell esds are taken into account individually in the estimation of esds in distances, angles and torsion angles; correlations between esds in cell parameters are only used

For wide-spectrum medicinal applications of spiro compounds incorporating heterocyclic substructures, see: Patil et al.. (2010); Pawar

Pyrazosul- furon-ethyl was the most recent SU herbicide released in Malaysia for the control of aquatic weed species in rice fields (Ahmad-Hamdani, pers. comm.), thus as

The cell s.u.'s are taken into account individually in the estimation of s.u.'s in distances, angles and torsion angles; correlations between s.u.'s in cell parameters are only