The refactorings in this section apply to the presentation tier.
Introduce a Controller
Control logic is scattered throughout the application, typically duplicated in multiple Java Server Page (JSP) views.
Extract control logic into one or more controller classes that serve as the initial contact point for handling a client request.
Introduce a controller
Control code that is duplicated in multiple JSPs also needs to be maintained in each JSP. Extracting this code into one or more centralized controller class improves the modularity, reusability, and maintainability of the application.
Assume we have the structure shown in Example 1 in many of our JSPs.
Example: Introduce a Controller – JSP Structure
The three vertical dots represent the body of each JSP, which is not being shown in this example. While this body portion differs for each JSP, the helper at the top of the page, implemented as a custom tag, is the same. This helper is responsible for controlling access to this page. It is an “all-or-nothing” type of control, meaning that a client is either granted access to the whole page or is denied access entirely.
If we change the design and introduce a controller, as described in the mechanics, then each of our JSPs will no longer include the <control:grant_access/> tag, as seen in Example.
Instead, we have a centralized controller that manages this behavior, handling the access control check that we removed from each JSP. Example is a snippet of code from the controller, which is implemented as a servlet.
Example : Introduce a Controller – Controller Structure
Of course, there are some cases where helpers are suitable for control code. For example, if only a small fraction of our JSPs need this type of access control, then it is not unreasonable to include a custom tag helper in each of these few pages to accomplish this goal. Another reason we might use custom tags in individual JSPs is to control access to specific subviews of a composite view.
If we are already using a controller,then we still might want to add this behavior in this centralized place, since the number of pages we want to protect might grow over time. To handle the case of an existing controller, we simply extract control code from our views and add it to the existing controller. In effect, we are moving methods instead of extracting a new class.
Introduce Synchronizer Token
Clients make duplicate resource requests that should be monitored and controlled, or clients access certain views out of order by returning to previously bookmarked pages.
Use a shared token to monitor and control the request flow and client access to certain resources.
Introduce synchronizer token
There are a number of scenarios in which control of an incoming request is desired. One of the most common reasons is the desire to control duplicate request submissions from a client. Such duplicate submissions may occur when the user clicks the Back or Stop browser buttons and resubmits a form.
While this issue is mainly one of controlling the order or flow of the requests, there is also the issue of controlling access based on permissions.
When Is a Token Generated and Stored? When Is a Token Checked?
A synchronizer token is compared for a match before processing an arriving request. A new token value is generated and stored after processing this request, but before the response is prepared and sent to the client.
Synchronizer token life cycle
The source code excerpts in Introduce Synchronizer Token are reprinted with permission under the Apache Software License, Version 1.1.
The Struts presentation framework applies several of the J2EE patterns and refactorings. It introduces this exact type of request flow control, and we use excerpts from this open source framework in our example.
Instead of creating a separate utility class to encapsulate the token generation and matching logic, Struts simply adds this functionality to a preexisting class that is part of its control mechanism. The class is called Action,and it is a common superclass for all actions. Actions are Command objects that extend the controller functionality. This is an application of the Front Controller pattern, Command and Controller strategy.
As shown in Example, the saveToken() method, which is part of the Action class, generates and stores token values.
Example : Generate and Store Token
Copyright(c)1999 The Apache Software Foundation. All rights reserved.
This method generates a unique token, calculated using the session ID and the current time, and stores this value into the user session.
At some point(usually immediately) prior to generating the HTML display for the client responsible for submitting a request that we do not want to duplicate (this display typically includes a form to be posted back to the server), a one-time token value is set, as previously described, by making the following method invocation:
Additionally, the JSP responsible for generating this HTML display also includes logic that delegates to a helper class to generate a hidden field that includes this token value. Thus, the page sent to the client, which typically includes a form that will be submitted back to the server,includes a hidden field of the following form:
The value attribute of this hidden field is the value of the token that was generated by the saveToken() method.
When the client submits the page that includes this hidden field,the controller delegates to a Command object(again, a subclass of the Action class)that compares the token value in the user session with the value in the request object parameter that came from the hidden field in the page. The Command object uses the method shown in Example, also excerpted from its superclass (the Action class again),to compare the values.
Example : Check For a Valid Token
Copyright(c)1999 The Apache Software Foundation. All rights reserved.
If there is a match,then we are certain that this request submission is not a duplicate. If the tokens do not match, then we are able to take appropriate action to deal with this potentially duplicate form submission.
Localize Disparate Logic
Business logic and presentation formatting are intermingled within a JSP view.
Extract business logic into one or more helper classes that can be used by the JSP or by a controller.
Figure shows logic being extracted from a view and into helpers.
Localize Disparate Logic: Factor Back
Figure shows logic being extracted from a view and into a controller, a command object, and helpers.
Localize Disparate Logic: Factor Forward
To create cleaner abstractions, increase cohesion and reduce coupling, which improves modularity and reusability. Well-partitioned, modular applications also provide better separation of developer roles, since Web developers own formatting code, while software developers own business logic.
We start with the sample code listed in Example. It is a JSP that includes lots of scriptlet code, intermingling business logic with the view.
Example : JSP with Scriptlet Code
This JSP generates an HTML table that lists employees at a certain salary level. The JSP encapsulates formatting and business logic, as shown in Figure.
View with intermingled business logic and formatting code
As Example shows, we apply the View Helper pattern, changing the design and extracting scriptlet code from the JSP view.
Example : JSP with Scriptlet Code Extracted
Additionally, we have written two custom tag helpers to encapsulate our business and presentation formatting processing logic by adapting the data model into the rows and columns of our HTML table.
The two helpers are the <corepatterns:employeelist> tag and the
Figure shows that we have moved from the design represented by the left side of the arrow to the one represented on the right side.
Extracting business logic into helper classes
Business logic has been extracted into helper classes instead of being embedded directly within the JSP. These helpers handle a variety of tasks, including content retrieval, access control, and adapting model state for display. In the second case, the helper actually encapsulates some of the presentation processing logic, such as formatting a result set into an HTML table. This helps us meet our goal of extracting as much programming logic from the view as possible, thus using the JSP to ask the helper for the completed table, instead of including scriptlet code in the JSP to generate the table.
Helper components may be implemented as JavaBeans or custom tags. JavaBean helpers are well suited to encapsulating content retrieval logic and storing the results, while custom tag helpers are well suited to the aforementioned task of converting the model for display, such as creating a table from a result set. There is quite a bit of overlap, though, so other factors, such as developer experience and manageability issues, may affect the decision about how to implement a helper.
Applying the second bullet of the mechanics, we simply delegate the work to the helpers, as shown in Figure.
Delegate work to helpers
The JSP view uses the helper classes to perform the view processing and generation. Typically, a controller is used in front of the JSP as the initial contact point for client requests. The controller dispatches to the view, but prior to doing so, the controller may also delegate work to the helper components. Having introduced a controller, we have made the transition shown in Figure.
Introducing a controller
Hide Presentation Tier-Specific Details From the Business Tier
Request handling and/or protocol-related data structures are exposed from the presentation tier to the business tier.
Remove all references to request handling and protocol-related presentation tier data structures from the business tier. Pass values between tiers using more generic data structures.
Hide presentation tier-specific details from the business tier
Implementation details specific to one tier should not be introduced in another tier. The service API exposed by the business tier to the presentation tier will likely be used by other clients as well. If the service API accepts parameters with types, such as HttpServletRequest, then every client to the service is forced to package its data in a servlet request data structure. This drastically reduces the service's reusability.
When handling a request, frameworks typically create numerous data structures. For example, typically a framework will transparently complete the step of copying the relevant state from the HttpServletRequest data structure to a more generic data structure, massaging request parameters into a framework-specific data type.While this data type may fulfill the same basic role as a value object, it is a framework-specific data type. Thus, passing this data structure into the business tier introduces coupling between the request-handling framework and the business services. In this case, one could still take the approach just described and copy the framework-specific data structure into a generic structure before passing it to the business tier. Instead, a more efficient solution is to simply create a generic type of interface that mirrors the methods of the framework-specific type. If this interface type is overlaid onto the framework-specific object, then this object can be shared with the business tier without any coupling to the specific framework.
J2EE Related Interview Questions
|Java Script Interview Questions||Adv Java Interview Questions|
|J2SE Interview Questions||Core Java Interview Questions|
|Java Struts Interview Questions||Hibernate Interview Questions|
|JavaServer Faces (JSF) Interview Questions||Java 8 Interview Questions|
|JavaFX Interview Questions||NHibernate Interview Questions|
|Spring MVC Framework Interview Questions||The Java Debugger (JDB) Interview Questions|
J2ee Platform Overview
Presentation Tier Design Considerations And Bad Practices
Business Tier Design Considerations And Bad Practices
J2ee Patterns Overview
Presentation Tier Patterns
Business Tier Patterns
Integration Tier Patterns
Epilogue J2ee Patterns Applied
All rights reserved © 2020 Wisdom IT Services India Pvt. Ltd
Wisdomjobs.com is one of the best job search sites in India.