The Service to Worker Pattern Tutorial



The model is part of the business tier, and it represents the interface between the underlying business data and all possible scenerios. The design of the model is therefore datacentric, since it is based on the underlying data and not necessarily the needs of a specific presentation.

In the L2EE world, models are generally Javabeans, or similarily named but functionally distinct Enterprise JavaBeanss. They provide a generic individual component for use within a larger framework. A JavaBean contains a set of properties, and the JavaBeans specification provides rules about the types and names used for setting and retrieving these properties. The framework , knowing only those rules, can interact with the data the bean represents. The bean itself is responsible for the details of retrieving the information, and can abstract the grubby specifics from the application.

The rules for writing a JavaBean must provide a constructor that takes no arguments it must not have any public variables; and any access to bean state should take place through getXXX( ) and setXXX( ) accesor methods. Business methods are other methods that operate on the model data.

In this tutorial, a simple JavaBean is used. The MailingBean stores all data about a user's first name, last name, and email address. These fields are availble through six accessor methods: getFirst( );, setFirst( );,getLast( );, setLast( );, getEmail( );, SetEmail( ). The bean also contains a single business method doSubscribe( );. When this method is invoked, the bean attempts to add the address specified in the email to the list. If it fails it will return false and provide a more detailed error message, accessible via the getErrorString( ); accessor.

The models and views in the Service to worker pattern remain more or less unchanged from the MVC and Front Controller patterns.

The Model is UserBean

Script 1.0 Login Interface Servlet


//session scope used to store the users login information, so information persists
//across all requests from the user.

public interface UserBean{
// user field name
public String getFirst( );
public void setUser(String user);

//password field name
public String getPassword( );
public void setPassword(String password);

//language
public String getlanguage( );
public void setLanguage(String language);

//business method to perform
public boolean doLogin( );
public boolean isLogin( );

//login reuslt
public String getErrorString( );

}



Script 1.0 Login.jsp

/*
// //$J2EE-Models.iNetModels.Com-Id:Administrator 12:00 PM 07/20/2006 $
// Copyright (C) 2006 The iNetModel Development Team
// Models.iNetModels.Com
//Service to Worker Pattern (s2w) Model.UserBean
// Script 1.0 Login.jsp
//
*/


//Views are simple JSP pages that read the model data from the UserBean.



< %page contentType="text/html"% >
< jsp:useBean id="userbean" scope="session" class="UserBean"/ >
< html>
< head>
< title>Login< /title>
< /head>
< body>
< form action="pages/workflow" method="post" >
< input type="text" name="username">
value=< jsp:getProperty name="s2w_models.userbean" property="username"/ >
Password: < input type="text" name="password">
< input type="submit" value="Log In">
< /form>
< /body>
< /html




Noticed in this code is that action now targets /pages/workflow. This will be the target of all our links, such as those in the second page, language.html. Since this page does not store any dynamic data it is stored as a plain HTML file.

Script 1.0 Language.html

/*
//
//$J2EE-Models.iNetModels.Com-Id:Administrator 12:00 PM 07/20/2006 $
// Copyright (C) 2006 The iNetModel Development Team
// Models.iNetModels.Com
// Service to Worker Pattern (s2w) View.language
// Script 1.0 language.html
//
*/


< html>
< head>
< title>Login < /title>
< /head>
< body>
< form action="pages/workflow" method="get" >
Language: < select name="language" >
< option value="EN">English< /option>
< option value="SP">Spanish< /option>
< /select>
< input type="submit" value="continue">
< /form>
< /body>
< /html




Actions
Actions are implemented as instances of the command pattern. The dispatcher use's a set of actions to perform model updates. Each action encapulates a single, specific update to the model, and only that update. An Action might be something as simple as adding a row to a database table, or as complex as coordinating transactions across multiple business objects. Because all navigation is encapsulated in the dispatcher, the actions are not responsible for view selection. As in the Front Controller Pattern, actions are usually implemented as an instance of the GoFCommand pattern.

//All of these actionswill share a simple interface.

public interface Action{
public boolean performAction(HttpServletRequestm req,
ServletContext context);
    }

Script 1.0 LoginAction.java

s2wmodels.controller.actions;



import s2wmodels.controller.*;
import s2wmodels.model.*;
import javax.servlet.http.*;
import javax.servlet.*;



public class LoginAction implements Action {
public static final String USERBEAN_ATTR = "userbean";
private static final String NAME_ATTR = "username";
private static final String PASSWORD_ATTR = "password";

public boolean performAction(HttpServletRequest req,
   ServletContext context) {

//read request parameters
String username = req.getParameter(NAME_PARAM);
String paswsword - req.getParameter(PASSWORD_PARAM);

?/Find the UserBean, create it if necessary
HttpSession session = req.getSession( );
UserBean ub = (UserbeanFactory.newInstance( );
session.setAttribute(USERBEAN_ATTR, ub);
}
//try to login, return the result
ub.setUsername(username);
ub.setPassword);
return ub.dologin( );


   }
 }