|
Version 4.10.0 | ||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
Object hirondelle.web4j.action.ActionImpl
public abstract class ActionImpl
Abstract Base Class (ABC) for implementations of the Action
interface.
This ABC provides concise methods for common operations, which will make implementations read more clearly, concisely, and at a higher level of abstraction.
A simple fetch-and-display operation can often be implemented using this class
as a base class. However, operations involving user input and/or edits to the
datastore should very likely use other abstract base classes, such as
ActionTemplateListAndEdit
, ActionTemplateSearch
, and
ActionTemplateShowAndApply
.
This class places success/fail messages in session scope, not request scope. This is because such messages often need to survive a redirect operation. For example, when a successful edit to the database occurs, a redirect is usually performed, to avoid problems with browser reloads. The only way a success message can survive a redirect is by being placed in session scope.
This class assumes that a session already exists. If a session does not already exist, then calling such methods will result in an error. In practice, the user will almost always have already logged in, and this will not be a problem. As a backup, actions can always explicitly create a session, if needed, by calling
getRequestParser.getRequest().getSession(true);
Field Summary | |
---|---|
static String |
DATA
Value "data" - generic key for a single 'data' object placed in scope for a JSP. |
static String |
ERRORS
Value "web4j_key_for_errors" - identifies a MessageList , placed
in session scope, to hold error information for the end user. |
static String |
ITEM_FOR_EDIT
Value "itemForEdit" - generic key for an object placed in scope for a JSP. |
static String |
ITEMS_FOR_LISTING
Value "itemsForListing" - generic key for a collection of objects placed in scope for a JSP. |
static String |
MESSAGES
Value "web4j_key_for_messages" - identifies a MessageList , placed
in session scope, to hold messages for the end user. |
static String |
USER_ID
Value "web4j_key_for_user_id" - identifies the user's id, placed in session scope. |
Constructor Summary | |
---|---|
protected |
ActionImpl(ResponsePage aNominalPage,
RequestParser aRequestParser)
Constructor. |
Method Summary | |
---|---|
protected void |
addError(AppException aEx)
Add all the error messages attached to aEx. |
protected void |
addError(String aMessage)
Add a simple AppResponseMessage describing a
failed validation of user input, or a failed datastore operation. |
protected void |
addError(String aMessage,
Object... aParams)
Add a compound AppResponseMessage describing a
failed validation of user input, or a failed datastore operation. |
protected void |
addMessage(String aMessage)
Add a simple AppResponseMessage , to be displayed
to the end user. |
protected void |
addMessage(String aMessage,
Object... aParams)
Add a compound AppResponseMessage , to be displayed
to the end user. |
protected void |
addToRequest(String aName,
Object aObject)
Add a name-object pair to request scope. |
protected void |
addToSession(String aName,
Object aObject)
Add a name-object pair to an existing session. |
protected void |
copyFromSessionToRequest(String aName)
Place an object which is in an existing session into request scope as well. |
protected void |
createSessionAndCsrfToken()
Create a new session (if one doesn't already exist) outside of the usual user login, and add a CSRF token to the new session to defend against Cross-Site Request Forgery (CSRF) attacks. |
protected void |
endSession()
If a session exists, then it is invalidated. |
abstract ResponsePage |
execute()
Execute desired operation. |
protected MessageList |
getErrors()
Return all the errors passed to all addError methods. |
protected HttpSession |
getExistingSession()
Return the existing session. |
protected Object |
getFromSession(String aName)
Retrieve an object from an existing session, or null if no object is paired with aName. |
protected Id |
getIdParam(RequestParameter aReqParam)
Convenience method for retrieving a parameter as a simple Id. |
protected Collection<Id> |
getIdParams(RequestParameter aReqParam)
Convenience method for retrieving a multivalued parameter as a simple Collection<Id> . |
protected Locale |
getLocale()
Return the Locale associated with the underlying request. |
protected SafeText |
getLoggedInUserName()
Return the name of the logged in user. |
protected MessageList |
getMessages()
Return all messages passed to all addMessage methods |
protected Operation |
getOperation()
Return the Operation associated with this Action, if any. |
protected DynamicSql |
getOrderBy(RequestParameter aSortColumn,
RequestParameter aOrder,
String aDefaultOrderBy)
Return an ORDER BY clause for an SQL statement. |
protected SafeText |
getParam(RequestParameter aReqParam)
Convenience method for retrieving a parameter as SafeText . |
protected String |
getParamUnsafe(RequestParameter aReqParam)
Convenience method for retrieving a parameter as raw text, with no escaped characters. |
protected RequestParser |
getRequestParser()
Return the RequestParser passed to the constructor. |
ResponsePage |
getResponsePage()
Return the resource which will render the final result. |
protected TimeZone |
getTimeZone()
Return the TimeZone associated with the underlying request. |
protected Id |
getUserId()
Return the Id stored in session scope under the key USER_ID . |
protected boolean |
hasErrors()
Return true only if at least one addError method has been called. |
protected void |
removeFromSession(String aName)
Synonym for addToSession(aName, null). |
protected void |
setResponsePage(ResponsePage aNewResponsePage)
Called by subclasses if the final ResponsePage
differs from the nominal one passed to the constructor. |
Methods inherited from class Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
---|
public static final String ERRORS
MessageList
, placed
in session scope, to hold error information for the end user.
These errors are used by both WEB4J and the application programmer.
public static final String MESSAGES
MessageList
, placed
in session scope, to hold messages for the end user. These messages are
used by both WEB4J and the application programmer. They typically hold success
and information messages.
public static final String USER_ID
Many applications will benefit from having both the user id and the user login name placed in session scope upon login. The Servlet Container will place the user login name in session scope upon login, but it will not place the corresponding user id (the database's primary key of the user record) in session scope.
If an application chooses to place the user's underlying database id into session scope under
this USER_ID key, then the user's id will be returned by getUserId()
.
public static final String ITEM_FOR_EDIT
Not mandatory to use this generic key. Provided simply as a convenience.
public static final String ITEMS_FOR_LISTING
Not mandatory to use this generic key. Provided simply as a convenience.
public static final String DATA
Not mandatory to use this generic key. Provided simply as a convenience.
Constructor Detail |
---|
protected ActionImpl(ResponsePage aNominalPage, RequestParser aRequestParser)
This constructor will add an attribute named 'Operation' to the request. Its
value is deduced as specified by getOperation()
. This attribute is intended for JSPs,
which can use it to access the Operation regardless of its original source.
aNominalPage
- simply one of the possible ResponsePage
s,
arbitrarily chosen as a "default". It may be changed after construction
by calling setResponsePage(hirondelle.web4j.action.ResponsePage)
. Recommended that the "success" page
be chosen as the nominal page. If not, then selection of any of the
possible ResponsePage
s is acceptable.aRequestParser
- allows parsing of request parameters into higher level java objects.Method Detail |
---|
public abstract ResponsePage execute() throws AppException
Action
Typical operations include :
ResponsePage
.
Returns an identifier for the resource (for example a JSP) which will display the end result of this Action (using either a forward or a redirect).
execute
in interface Action
AppException
public final ResponsePage getResponsePage()
protected final Operation getOperation()
Operation
associated with this Action, if any.
The Operation is found as follows :
Operation.valueFor(String)
Operation.List
being added to request scope, since the extension value list is known to
Operation.valueFor(String)
.
This style is useful for implementing fine-grained <security-constraint>
items in web.xml. See the User Guide for more information.
When using the 'extension' style, please note that web.xml contains related servlet-mapping settings. Such settings control which HTTP requests (as defined by a url-pattern) are passed from the Servlet Container to your application in the first place. Thus, any 'extensions' which your application intends to use must have a corresponding servlet-mapping setting in your web.xml.
protected final SafeText getLoggedInUserName()
By definition in the servlet specification, a successfully logged in user
will always have a non-null return value for
HttpServletRequest.getUserPrincipal()
.
If the user is not logged in, this method will always return null.
This method returns SafeText
, not a String.
The user name is often rendered in the view. Since in general the user name
may contain special characters, it is appropriate to model it as
SafeText.
protected final Id getUserId()
Id
stored in session scope under the key USER_ID
.
If no such item is found, then return null.
The user id should only be used in server-side code, and never presented to the user in a JSP.
protected final void setResponsePage(ResponsePage aNewResponsePage)
ResponsePage
differs from the nominal one passed to the constructor.
If an implementation calls this method, it is usually
called in execute()
.
protected final void addToRequest(String aName, Object aObject)
If the pair already exists, it is updated with aObject.
aName
- satisfies Util.textHasContent(String)
.aObject
- if null and a corresponding name-object pair exists, then
the pair is removed from request scope.protected final HttpSession getExistingSession()
If a session does not already exist, then an error will result.
protected final void addToSession(String aName, Object aObject)
If the pair already exists, it is updated with aObject.
aName
- satisfies Util.textHasContent(String)
.aObject
- if null and a corresponding name-object pair exists, then
the pair is removed from session scope.protected final void removeFromSession(String aName)
protected final Object getFromSession(String aName)
aName
- satisfies Util.textHasContent(String)
.protected final void copyFromSessionToRequest(String aName)
When serving the last page in a session, some session items may still be needed for rendering the final page.
For example, a log off page in a mutlilingual application might present a
"goodbye" message in the language that the user was using. Since the
session is being destroyed, the Locale
stored in the session must be
first copied into request scope before the session is killed.
aName
- identifies an Object which is currently in session scope, and satisfies
Util.textHasContent(String)
. If no attribute of the given name
is found in the current session, then a null is added to the request scope
under this name.protected final void endSession()
protected final void addError(String aMessage)
AppResponseMessage
describing a
failed validation of user input, or a failed datastore operation.
One of the addError methods must be called when a failure occurs.
protected final void addError(String aMessage, Object... aParams)
AppResponseMessage
describing a
failed validation of user input, or a failed datastore operation.
One of the addError methods must be called when a failure occurs.
protected final void addError(AppException aEx)
One of the addError methods must be called when a failure occurs.
protected final MessageList getErrors()
protected final boolean hasErrors()
protected final void addMessage(String aMessage)
AppResponseMessage
, to be displayed
to the end user.
protected final void addMessage(String aMessage, Object... aParams)
AppResponseMessage
, to be displayed
to the end user.
protected final MessageList getMessages()
protected final Locale getLocale()
Locale
associated with the underlying request.
The configured implementation of LocaleSource
defines how
Locale is looked up.
protected final TimeZone getTimeZone()
TimeZone
associated with the underlying request.
The configured implementation of TimeZoneSource
defines how
TimeZone is looked up.
protected final RequestParser getRequestParser()
RequestParser
passed to the constructor.
protected final Id getIdParam(RequestParameter aReqParam)
Synonym for getRequestParser().toId(RequestParameter).
protected final Collection<Id> getIdParams(RequestParameter aReqParam)
Collection<Id>
.
Synonym for getRequestParser().toIds(RequestParameter).
protected final SafeText getParam(RequestParameter aReqParam)
SafeText
.
Synonym for getRequestParser().toSafeText(RequestParameter).
protected final String getParamUnsafe(RequestParameter aReqParam)
This method call is unsafe in the sense that it returns String
instead of SafeText
. It is usually preferable to use SafeText
,
since it protects against Cross-Site Scripting attacks.
If, however, the caller needs to use a request parameter value to perform a computation, as opposed to presenting user data in markup, then this method is provided as a convenience.
protected final DynamicSql getOrderBy(RequestParameter aSortColumn, RequestParameter aOrder, String aDefaultOrderBy)
Provided as a convenience for the common task of creating an ORDER BY clause from request parameters.
aSortColumn
- carries a ResultSet column identifer, either a
numeric column index, or the name of the column itself.aOrder
- carries the value ASC or DESC (ignores case).aDefaultOrderBy
- default text to be used if the request parameters are not
present, or have no content.protected final void createSessionAndCsrfToken()
This method exists to extend the CsrfFilter
, to allow it to apply to a form/action that does not already have a
user logged in.
Warning: you can only call this method in Actions for which the
SuppressUnwantedSessions
filter is NOT in effect.
Warning: This method should be used with care when using Tomcat. This method creates an 'anonymous' session, unattached to any user login. Should the user log in afterwards, a robust web application should assign a new session id. (See OWASP for more information.) The problem is that Tomcat 5 and 6 do not follow this rule, and will retain any existing session id when the user logs in.
This method is needed only when the user has not yet logged in. An excellent example of operations not requiring a login are operations that deal with account management on a typical public web site :
For such forms, it's strongly recommended that corresponding Actions call this method.
This will allow the CsrfFilter
mechanism to be used to defend such forms against CSRF attack.
As a second benefit, it will also allow information messages sent to the end user to survive redirect operations.
|
Version 4.10.0 | ||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |