Better Faster Lighter Java [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Better Faster Lighter Java [Electronic resources] - نسخه متنی

Justin Gehtland; Bruce A. Tate

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید








8.5 Presentation


In most places, the Spring

framework doesn't
reinvent working technologies. In the area of presentation logic,
though, Spring introduces a simple model-view-controller framework
called MVC Web that has many competing architectures, like Struts and
Java Server Faces (JSF). Take solace, though. You
don't have to use MVC Web to use Spring. But if you
decide to do so, you will find a few advantages:

MVC Web is based on interfaces

rather than inheritance. As we
discussed in Chapter 3, interfaces often give
better flexibility and looser coupling than inheritance-based
designs.

MVC Web does not dictate your choice of view. Other frameworks tend
to provide better support for favored view technologies, such as
Velocity (proprietary) and Struts (JSP). For example, Struts exposes
the model via request attributes. As a result, you need to build a
bridge servlet to use a technology such as Velocity that
doesn't understand the Servlet API. Spring exposes
the model through a generic map, so it can work with any view
technology.

MVC Web provides consistent configuration across all aspects of a
Spring application. It uses the same inversion-of-control paradigm
that the other frameworks use.

MVC Web makes testing easier. Since you don't have
to extend another class (like Action or ActionForm in Struts), you
can easily mock the request and response.


If you've ever used Struts, you're
familiar with the basic paradigm of MVC Web. Figure 8-4 shows how it works. Controllers basically
handle all incoming requests from input views. If the input request
is a submitted form, the controller calls a business validation
routine, created and configured by the programmer, and sends either
the associated error view or success view back to the user, based on
results.



Figure 8-4. The MVC Web framework works much like Struts


8.5.1 Configuration


As with other elements of


the
Spring framework, when you're trying to understand a
new application, start with the configuration files and drill down
from there. In this example, the user interface is configured in the
petstore-servlet.xml file.

Consider HTML pages that search for products in a category, and
search for products based on keywords. The configuration file needs
two controllers to the application context file. Each entry specifies
a controller and the model object, like in Example 8-10.


Example 8-10. Excerpt from web.xml


  <bean name="/shop/searchProducts.do" 
class="jpetstore.web.spring.SearchProductsController">
<property name="petStore"><ref bean="petStore"/></property>
</bean>
<bean name="/shop/viewProduct.do" class="org.springframework.samples.jpetstore.web.
spring.ViewProductController">
<property name="petStore"><ref bean="petStore"/></property>
</bean>

Recall that all access to our data layer goes through the
façade. As you'd expect, these bean ID
entries specify the façade, called
petstore. Each form in the application works in
the same way. Let's drill down further and look at
the controller for searchProducts.


8.5.2 Controllers


For MVC Web, each form


generally
shares a single instance of a controller, which routes all requests
related to a given form. It also marshals the form to the correct
validation logic and returns the appropriate view to the user. Example 8-11 shows the controller for the
searchProducts view.


Example 8-11. SearchProductsController.java


      public class SearchProductsController implements Controller {
[1] private PetStoreFacade petStore;
public void setPetStore(PetStoreFacade petStore) {
this.petStore = petStore;
}
[2] public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response)
throws Exception {
[3] if (request.getParameter("search") != null) {
String keyword = request.getParameter("keyword");
if (keyword == null || keyword.length( ) == 0) {
return new ModelAndView("Error",
"message",
"Please enter a keyword to search for, then press the search button.");
}
else {
[4] PagedListHolder productList = new PagedListHolder(
this.petStore.searchProductList(keyword.toLowerCase( )));
productList.setPageSize(4);
request.getSession( ).setAttribute(
"SearchProductsController_productList", productList);
[5] return new ModelAndView("SearchProducts", "productList", productList);
}
}
else {
[6] String page = request.getParameter("page");
PagedListHolder productList = (PagedListHolder) request.getSession( ).
getAttribute("SearchProductsController_productList");
if ("next".equals(page)) {
productList.nextPage( );
}
else if ("previous".equals(page)) {
productList.previousPage( );
}
return new ModelAndView("SearchProducts", "productList", productList);
}
}
}

Here's what the annotations mean:

[1] Each controller has access to the appropriate domain
model. In this case, it's natural for the view to
access the model through our façade.[2] A controller has an interface like a servlet, but
isn't actually a servlet. User requests instead come
in through a single dispatcher servlet, which routes them to the
appropriate controller, populating the request
membermeter. The controller merely responds to the appropriate request,
invoking business data and routing control to the appropriate page.[3] In this case, the request is to
"search." The controller must parse
out the appropriate keywords.[4] The controller invokes the business logic with the
keywords provided by the user.[5] The controller routes the appropriate view back to the
user (with the appropriate model).[6] In this case, the request is
"page." Our user interface supports
more products than might fit on a single page.

8.5.3 Forms


Just like Struts, Spring can map HTML forms


onto
Java objects. Example 8-12 is the Java bean
that's returned when a Pet Store user registers an
account.


Example 8-12. AccountForm.java


public class AccountForm {
private Account account;
private boolean newAccount;
private String repeatedPassword;
public AccountForm(Account account) {
this.account = account;
this.newAccount = false;
}
public AccountForm( ) {
this.account = new Account( );
this.newAccount = true;
}
public Account getAccount( ) {
return account;
}
public boolean isNewAccount( ) {
return newAccount;
}
public void setRepeatedPassword(String repeatedPassword) {
this.repeatedPassword = repeatedPassword;
}
public String getRepeatedPassword( ) {
return repeatedPassword;
}
}

Each of these bean fields corresponds directly to an HTML input field
or control. The Spring framework translates a submit request to the
form, which can then be accessed as a POJO for validation, mapping
input data, or other purposes. With Spring, unlike Struts, form
objects can be any Java bean. There's no need to
extend ActionForm. That's
important, because you don't need to copy properties
from an ActionForm to a domain object or value
object.


8.5.4 Validation


You may have noticed validation logic

within
the original applciationContext.xml. These beans
are generally considered business logic, but they've
got a tight relationship to the user interface and
they're invoked directly by the Spring framework.
When a user submits a form, Spring fires the validation logic. Based
on the result, Spring routes control to the appropriate page. Example 8-13 shows the AccountValidator
class, which validates the account form.


Example 8-13. AccountValidator.java


public class AccountValidator implements Validator {
public boolean supports(Class clazz) {
return Account.class.isAssignableFrom(clazz);
}
public void validate(Object obj, Errors errors) {
ValidationUtils.rejectIfEmpty(errors, "firstName", "FIRST_NAME_REQUIRED",
ValidationUtils.rejectIfEmpty(errors, "lastName", "LAST_NAME_REQUIRED",
ValidationUtils.rejectIfEmpty(errors, "email", "EMAIL_REQUIRED",
ValidationUtils.rejectIfEmpty(errors, "phone", "PHONE_REQUIRED",
ValidationUtils.rejectIfEmpty(errors, "address1", "ADDRESS_REQUIRED",
ValidationUtils.rejectIfEmpty(errors, "city", "CITY_REQUIRED",
ValidationUtils.rejectIfEmpty(errors, "state", "STATE_REQUIRED",
ValidationUtils.rejectIfEmpty(errors, "zip", "ZIP_REQUIRED", "ZIP is required.");
ValidationUtils.rejectIfEmpty(errors, "country", "COUNTRY_REQUIRED",
}
}

In this example, the Spring framework makes life easier for
developers in several ways. The developer does not need to write
validation methods by hand. Also, many prepackaged methods exist. The
framework takes care of validation and routing. The framework takes
care of routing control based on success or failure.

One chapter on the Spring framework cannot do it justice, but
you've seen the overall gist of it. The advantages
of the frameworkand more importantly, this coding
styleshould jump off the page at you if you
haven't seen it before. In particular, notice the
clarity and simplicity that a cleanly layered architecture provides.
You can probably imagine how easy it is to incorporate business logic
with a transparent framework

like Spring.


/ 111