With each page you design it's important to decide how to handle a bad activation context, because a bad context can occur in various ways.
For example, look at the URL of this page. The activation context is clearly visible as 1 and it is easy to change. Try replacing it with 2 and you will see person 2. Users may become accustomed to this facility.
Here is the requested person:
In this example a bad context could occur several ways:
Here are the alternatives:
This page has been built to handle only one situation: person does not exist. All other problems will be caught by the exception reporting page.
EventContext
To handle a variable number of context parameters, or even an unexpected number of
context parameters, use EventContext.
See the Variable Parameters example, Easy Object Select example, and One Page CRUD example.
The source for Person, @EJB handling, etc. is shown in the @EJB example.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!-- We need a doctype to allow us to use special characters like
We use a "strict" DTD to make IE follow the alignment rules. -->
<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd">
<body class="container">
<h3>Handling A Bad Context</h3>
<p>With each page you design it's important to decide how to handle a bad activation context, because a bad context
can occur in various ways.</p>
<p>
For example, look at the URL of this page. The activation context is clearly visible as <em>1</em> and it is easy to
change. Try replacing it with <em>2</em> and you will see person 2. Users may become accustomed to this facility.
</p>
<p>Here is the requested person:</p>
<div class="eg">
<t:if test="person">
<t:beandisplay object="person" />
</t:if>
<t:if test="!person">
<div class="alert alert-danger">Person ${personId} does not exist.</div>
</t:if>
</div>
<p>In this example a bad context could occur several ways:</p>
<ul>
<li>You've removed the context from the URL.</li>
<li>
You've chosen a person that does not exist, eg. <em>100</em>.
</li>
<li>You are not authorised to the person (in JumpStart this is not checked).</li>
<li>
The format of the context is incorrect, eg. <em>abc</em>.
</li>
<li>You bookmark the page but when you return to it later the context is no longer valid because data,
authorization, or the application have changed.</li>
</ul>
<p>Here are the alternatives:</p>
<ol>
<li>
<strong>Handle it on the same page</strong> - either display the person or display the error.<br /> This approach has
the big advantage that it keeps the same URL - the user can see what they requested.<br /> The <em>"exception"</em>
event can help simplify this. See References below.
</li>
<li>
<strong>Return a new page</strong>, possibly passing it the exception or a message to display.<br /> The page could
even return <a href="http://en.wikipedia.org/wiki/404_error">HTTP 404</a> as described <a
href="http://news.gmane.org/find-root.php?message_id=%3c48A4290A.7010407%40fsadev.com%3e">here</a>.
</li>
<li>
Throw an exception and let <strong>Tapestry's exception reporting page</strong> catch it. <br /> This is the simplest
approach but probably not suitable for production. See the Exception Reporting Page example.
</li>
<li>
Throw an exception and catch it with <strong>your own exception reporting page</strong> as described in the Exception
Reporting Page example.<br /> The exception reporting page could give certain exceptions special treatment eg.
you might like to treat expected exceptions, like DoesNotExistException and NotAuthorisedException, differently
than unexpected exceptions.
</li>
</ol>
<p>This page has been built to handle only one situation: person does not exist. All other problems will be caught
by the exception reporting page.</p>
<p>
<strong>EventContext</strong><br /> To handle a variable number of context parameters, or even an unexpected number of
context parameters, use <a href="http://tapestry.apache.org/component-events.html#ComponentEvents-EventContext">EventContext</a>.
See the Variable Parameters example, Easy Object Select example, and One Page CRUD example.
</p>
References:
<a href="http://tapestry.apache.org/component-events.html#ComponentEvents-InterceptingEventExceptions">Intercepting
Event Exceptions</a>,
<a href="http://tapestry.apache.org/overriding-exception-reporting.html">Overriding Exception Reporting</a>,
<a href="http://tapestry.apache.org/component-events.html#ComponentEvents-EventContext">EventContext</a>.
<a href="http://tapestry.apache.org/5.4/apidocs/org/apache/tapestry5/corelib/components/If.html">If</a>,
<a href="http://tapestry.apache.org/5.4/apidocs/org/apache/tapestry5/corelib/components/BeanDisplay.html">BeanDisplay</a>.
<br />
<br />
<p>
<t:pagelink page="Index">Home</t:pagelink>
</p>
<p>The source for Person, @EJB handling, etc. is shown in the @EJB example.</p>
<t:tabgroup>
<t:sourcecodetab src="/web/src/main/java/jumpstart/web/pages/examples/infrastructure/HandlingABadContext.tml" />
<t:sourcecodetab src="/web/src/main/java/jumpstart/web/pages/examples/infrastructure/HandlingABadContext.java" />
<t:sourcecodetab src="/web/src/main/resources/META-INF/assets/css/examples/plain.css" />
</t:tabgroup>
</body>
</html>
package jumpstart.web.pages.examples.infrastructure;
import javax.ejb.EJB;
import jumpstart.business.domain.person.Person;
import jumpstart.business.domain.person.iface.IPersonFinderServiceLocal;
import org.apache.tapestry5.annotations.Import;
import org.apache.tapestry5.annotations.Property;
@Import(stylesheet = "css/examples/plain.css")
public class HandlingABadContext {
// The activation context
@Property
private Long personId;
// Screen fields
@Property
private Person person;
// Generally useful bits and pieces
@EJB
private IPersonFinderServiceLocal personFinderService;
// The code
void onActivate(Long personId) {
this.personId = personId;
}
Long onPassivate() {
return personId;
}
void setupRender() {
// Get person - ask business service to find it (from the database)
person = personFinderService.findPerson(personId);
// Handle null person in the template (with an If component).
}
}
.eg {
margin: 20px 0;
padding: 14px;
border: 1px solid #ddd;
border-radius: 6px;
-webkit-border-radius: 6px;
-mox-border-radius: 6px;
}