Rectangle 27 0

java Design Patterns web based applications?


Map<String, Action>
actions
actions.put("POST/register", new RegisterAction());
actions.put("POST/login", new LoginAction());
actions.put("GET/logout", new LogoutAction());
// ...
for (ClassFile classFile : classpath) {
    if (classFile.isInstanceOf(Action.class)) {
       actions.put(classFile.getAnnotation("mapping"), classFile.newInstance());
    }
}
for (Entry entry : configuration) {
    actions.put(entry.getKey(), Class.forName(entry.getValue()).newInstance());
}
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    try {
        Action action = ActionFactory.getAction(request);
        String view = action.execute(request, response);

        if (view.equals(request.getPathInfo().substring(1)) {
            request.getRequestDispatcher("/WEB-INF/" + view + ".jsp").forward(request, response);
        }
        else {
            response.sendRedirect(view); // We'd like to fire redirect in case of a view change as result of the action (PRG pattern).
        }
    }
    catch (Exception e) {
        throw new ServletException("Executing action failed.", e);
    }
}
public class LoginAction implements Action {

    public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        User user = userDAO.find(username, password);

        if (user != null) {
            request.getSession().setAttribute("user", user); // Login user.
            return "home"; // Redirect to home page.
        }
        else {
            request.setAttribute("error", "Unknown username/password. Please retry."); // Store error message in request scope.
            return "login"; // Go back to redisplay login form with error.
        }
    }

}
public interface Action {
    public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception;
}
public static Action getAction(HttpServletRequest request) {
    return actions.get(request.getMethod() + request.getPathInfo());
}

Sign up for our newsletter and get our top new questions delivered to your inbox (see an example).

@AndreyBotalov: check source code of MVC frameworks like JSF, Spring MVC, Wicket, Struts2, etc. They are all open source.

@masato: You could do this in for example a static initializer block.

@masato: by the way, if you'd like to retrieve them from web.xml, then you could use a ServletContextListener for this. Have the factory implement it (and register as <listener> in web.xml) and do the filling job during contextInitialized() method.

A bit decent web application consists of a mix of design patterns. I'll mention only the most important ones.

As a side note, hobbying around with a homegrown MVC framework is a very nice learning exercise, and I do recommend it as long as you keep it for personal/private purposes. But once you go professional, then it's strongly recommended to pick an existing framework rather than reinventing your own. Learning an existing and well-developed framework takes in long term less time than developing and maintaining a robust framework yourself.

Depends. Easiest is to just do it right in the Action implementation the same way as with normal servlets (see also servlets wiki for a basic example, which you're free to refactor further into some Validator interface). But you could also do it before invoking the action, but this is more complex as it requires the validation rules being known on a per-view basis. JSF has covered this by offering required="true", validator="customValidatorName", etc in the XHTML markup.

Do the job which the "post_servlet" should do in the action instead. You shouldn't have more than one servlet. Business stuff should be done in action classes. If you'd like it to be a new request, then return to a different view which would cause a redirect and do the job in the new action associated with the GET request.

Executing the action should return some identifier to locate the view. Simplest would be to use it as filename of the JSP. Map this servlet on a specific url-pattern in web.xml, e.g. /pages/*, *.do or even just *.html.

First, the Controller part should implement the Front Controller pattern (which is a specialized kind of Mediator pattern). It should consist of only a single servlet which provides a centralized entry point of all requests. It should create the Model based on information available by the request, such as the pathinfo or servletpath, the method and/or specific parameters. The Business Model is called Action in the below HttpServlet example.

Here's an example of a LoginAction which (as its name says) logs in the user. The User itself is in turn a Data Model. The View is aware of the presence of the User.

In case of prefix-patterns as for example /pages/* you could then invoke URL's like http://example.com/pages/register, http://example.com/pages/login, etc and provide /WEB-INF/register.jsp, /WEB-INF/login.jsp with the appropriate GET and POST actions. The parts register, login, etc are then available by request.getPathInfo() as in above example.

In the below detailed explanation I'll restrict myself to request based MVC since that's easier to implement.

Keep in mind to create a "do nothing" Action for the case there's no mapping. Let it for example return directly the request.getPathInfo().substring(1) then.

Or configurable based on a properties/XML configuration file in the classpath: (pseudo)

Or dynamically based on a scan in the classpath for classes implementing a certain interface and/or annotation: (pseudo)

The Action should follow the Strategy pattern. It needs to be defined as an abstract/interface type which should do the work based on the passed-in arguments of the abstract method (this is the difference with the Command pattern, wherein the abstract/interface type should do the work based on the arguments which are been passed-in during the creation of the implementation).

The ActionFactory should follow the Factory method pattern. Basically, it should provide a creational method which returns a concrete implementation of an abstract/interface type. In this case, it should return an implementation of the Action interface based on the information provided by the request. For example, the method and pathinfo (the pathinfo is the part after the context and servlet path in the request URL, excluding the query string).

The core (architectural) design pattern you'd like to use is the Model-View-Controller pattern. The Controller is to be represented by a Servlet which (in)directly creates/uses a specific Model and View based on the request. The Model is to be represented by Javabean classes. This is often further dividable in Business Model which contains the actions (behaviour) and Data Model which contains the data (information). The View is to be represented by JSP files which have direct access to the (Data) Model by EL (Expression Language).

Then there's the Composite pattern for the case that you'd like to create a component based view which can be attached with the model and whose behaviour depends on the state of the request based lifecycle. In JSF terms, this is what the UIComponent represent.

Then there's the State pattern for the case that you'd like to add an extra abstraction layer to split the tasks of gathering the request parameters, converting them, validating them, updating the model values and execute the actions. In JSF terms, this is what the LifeCycle is doing.

Then, there are variations based on how actions and events are handled. The popular ones are:

This way you can evolve bit by bit towards a component based framework.

To get a step further, you could use the Facade pattern to create a Context class which in turn wraps the request and response objects and offers several convenience methods delegating to the request and response objects and pass that as argument into the Action#execute() method instead. This adds an extra abstract layer to hide the raw Servlet API away. You should then basically end up with zero import javax.servlet.* declarations in every Action implementation. In JSF terms, this is what the FacesContext and ExternalContext classes are doing. You can find a concrete example in this answer.

When you're using suffix-patterns like *.do, *.html, etc, then you could then invoke URL's like http://example.com/register.do, http://example.com/login.do, etc and you should change the code examples in this answer (also the ActionFactory) to extract the register and login parts by request.getServletPath() instead.

You may want to make the Exception more specific with a custom exception like ActionException. It's just a basic kickoff example, the rest is all up to you.

Note
Rectangle 27 0

java Design Patterns web based applications?


1) An action which is used is called every time the HTML page is refreshed. The action should populate the data in the form when the page is first loaded and handles interactions between the web UI and the business layer. If you are using the jsp page to modify a mutable java object a copy of the java object should be stored in the form rather than the original so that the original data doesn't get modified unless the user saves the page.

2) The form which is used to transfer data between the action and the jsp page. This object should consist of a set of getter and setters for attributes that need to be accessible to the jsp file. The form also has a method to validate data before it gets persisted.

3) A jsp page which is used to render the final HTML of the page. The jsp page is a hybrid of HTML and special struts tags used to access and manipulate data in the form. Although struts allows users to insert Java code into jsp files you should be very cautious about doing that because it makes your code more difficult to read. Java code inside jsp files is difficult to debug and can not be unit tested. If you find yourself writing more than 4-5 lines of java code inside a jsp file the code should probably be moved to the action.

I have used the struts framework and find it fairly easy to learn. When using the struts framework each page of your site will have the following items.

Note: In struts 2 the Form object is referred to as a Model instead but works the same way as I described in my original answer.

Note
Rectangle 27 0

java Design Patterns web based applications?


I would not, though, start writing raw Servlet classes. The work they do is very predictable and boilerplate, something that framework does very well. Fortunately, there are many available, time-tested candidates ( in the alphabetical order ): Apache Wicket, Java Server Faces, Spring to name a few.

In the beaten-up MVC pattern, the Servlet is "C" - controller.

Its main job is to do initial request evaluation and then dispatch the processing based on the initial evaluation to the specific worker. One of the worker's responsibilities may be to setup some presentation layer beans and forward the request to the JSP page to render HTML. So, for this reason alone, you need to pass the request object to the service layer.

Note
Rectangle 27 0

java Design Patterns web based applications?


IMHO, there is not much difference in case of web application if you look at it from the angle of responsibility assignment. However, keep the clarity in the layer. Keep anything purely for the presentation purpose in the presentation layer, like the control and code specific to the web controls. Just keep your entities in the business layer and all features (like add, edit, delete) etc in the business layer. However rendering them onto the browser to be handled in the presentation layer. For .Net, the ASP.NET MVC pattern is very good in terms of keeping the layers separated. Look into the MVC pattern.

The servlet should be the controller if you use MVC.

can you go a bit explicit in what should go in servlet?

Note
Rectangle 27 0

java Design Patterns web based applications?


Map<String, Action>
actions
actions.put("POST/register", new RegisterAction());
actions.put("POST/login", new LoginAction());
actions.put("GET/logout", new LogoutAction());
// ...
for (ClassFile classFile : classpath) {
    if (classFile.isInstanceOf(Action.class)) {
       actions.put(classFile.getAnnotation("mapping"), classFile.newInstance());
    }
}
for (Entry entry : configuration) {
    actions.put(entry.getKey(), Class.forName(entry.getValue()).newInstance());
}
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    try {
        Action action = ActionFactory.getAction(request);
        String view = action.execute(request, response);

        if (view.equals(request.getPathInfo().substring(1)) {
            request.getRequestDispatcher("/WEB-INF/" + view + ".jsp").forward(request, response);
        }
        else {
            response.sendRedirect(view); // We'd like to fire redirect in case of a view change as result of the action (PRG pattern).
        }
    }
    catch (Exception e) {
        throw new ServletException("Executing action failed.", e);
    }
}
public class LoginAction implements Action {

    public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        User user = userDAO.find(username, password);

        if (user != null) {
            request.getSession().setAttribute("user", user); // Login user.
            return "home"; // Redirect to home page.
        }
        else {
            request.setAttribute("error", "Unknown username/password. Please retry."); // Store error message in request scope.
            return "login"; // Go back to redisplay login form with error.
        }
    }

}
public interface Action {
    public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception;
}
public static Action getAction(HttpServletRequest request) {
    return actions.get(request.getMethod() + request.getPathInfo());
}

@AndreyBotalov: check source code of MVC frameworks like JSF, Spring MVC, Wicket, Struts2, etc. They are all open source.

@masato: You could do this in for example a static initializer block.

@masato: by the way, if you'd like to retrieve them from web.xml, then you could use a ServletContextListener for this. Have the factory implement it (and register as <listener> in web.xml) and do the filling job during contextInitialized() method.

A bit decent web application consists of a mix of design patterns. I'll mention only the most important ones.

As a side note, hobbying around with a homegrown MVC framework is a very nice learning exercise, and I do recommend it as long as you keep it for personal/private purposes. But once you go professional, then it's strongly recommended to pick an existing framework rather than reinventing your own. Learning an existing and well-developed framework takes in long term less time than developing and maintaining a robust framework yourself.

Depends. Easiest is to just do it right in the Action implementation the same way as with normal servlets (see also servlets wiki for a basic example, which you're free to refactor further into some Validator interface). But you could also do it before invoking the action, but this is more complex as it requires the validation rules being known on a per-view basis. JSF has covered this by offering required="true", validator="customValidatorName", etc in the XHTML markup.

Do the job which the "post_servlet" should do in the action instead. You shouldn't have more than one servlet. Business stuff should be done in action classes. If you'd like it to be a new request, then return to a different view which would cause a redirect and do the job in the new action associated with the GET request.

Executing the action should return some identifier to locate the view. Simplest would be to use it as filename of the JSP. Map this servlet on a specific url-pattern in web.xml, e.g. /pages/*, *.do or even just *.html.

First, the Controller part should implement the Front Controller pattern (which is a specialized kind of Mediator pattern). It should consist of only a single servlet which provides a centralized entry point of all requests. It should create the Model based on information available by the request, such as the pathinfo or servletpath, the method and/or specific parameters. The Business Model is called Action in the below HttpServlet example.

Here's an example of a LoginAction which (as its name says) logs in the user. The User itself is in turn a Data Model. The View is aware of the presence of the User.

In case of prefix-patterns as for example /pages/* you could then invoke URL's like http://example.com/pages/register, http://example.com/pages/login, etc and provide /WEB-INF/register.jsp, /WEB-INF/login.jsp with the appropriate GET and POST actions. The parts register, login, etc are then available by request.getPathInfo() as in above example.

In the below detailed explanation I'll restrict myself to request based MVC since that's easier to implement.

Keep in mind to create a "do nothing" Action for the case there's no mapping. Let it for example return directly the request.getPathInfo().substring(1) then.

Or configurable based on a properties/XML configuration file in the classpath: (pseudo)

Or dynamically based on a scan in the classpath for classes implementing a certain interface and/or annotation: (pseudo)

The Action should follow the Strategy pattern. It needs to be defined as an abstract/interface type which should do the work based on the passed-in arguments of the abstract method (this is the difference with the Command pattern, wherein the abstract/interface type should do the work based on the arguments which are been passed-in during the creation of the implementation).

The ActionFactory should follow the Factory method pattern. Basically, it should provide a creational method which returns a concrete implementation of an abstract/interface type. In this case, it should return an implementation of the Action interface based on the information provided by the request. For example, the method and pathinfo (the pathinfo is the part after the context and servlet path in the request URL, excluding the query string).

The core (architectural) design pattern you'd like to use is the Model-View-Controller pattern. The Controller is to be represented by a Servlet which (in)directly creates/uses a specific Model and View based on the request. The Model is to be represented by Javabean classes. This is often further dividable in Business Model which contains the actions (behaviour) and Data Model which contains the data (information). The View is to be represented by JSP files which have direct access to the (Data) Model by EL (Expression Language).

Then there's the Composite pattern for the case that you'd like to create a component based view which can be attached with the model and whose behaviour depends on the state of the request based lifecycle. In JSF terms, this is what the UIComponent represent.

Then there's the State pattern for the case that you'd like to add an extra abstraction layer to split the tasks of gathering the request parameters, converting them, validating them, updating the model values and execute the actions. In JSF terms, this is what the LifeCycle is doing.

Then, there are variations based on how actions and events are handled. The popular ones are:

This way you can evolve bit by bit towards a component based framework.

To get a step further, you could use the Facade pattern to create a Context class which in turn wraps the request and response objects and offers several convenience methods delegating to the request and response objects and pass that as argument into the Action#execute() method instead. This adds an extra abstract layer to hide the raw Servlet API away. You should then basically end up with zero import javax.servlet.* declarations in every Action implementation. In JSF terms, this is what the FacesContext and ExternalContext classes are doing. You can find a concrete example in this answer.

When you're using suffix-patterns like *.do, *.html, etc, then you could then invoke URL's like http://example.com/register.do, http://example.com/login.do, etc and you should change the code examples in this answer (also the ActionFactory) to extract the register and login parts by request.getServletPath() instead.

You may want to make the Exception more specific with a custom exception like ActionException. It's just a basic kickoff example, the rest is all up to you.

Note
Rectangle 27 0

java Design Patterns web based applications?


IMHO, there is not much difference in case of web application if you look at it from the angle of responsibility assignment. However, keep the clarity in the layer. Keep anything purely for the presentation purpose in the presentation layer, like the control and code specific to the web controls. Just keep your entities in the business layer and all features (like add, edit, delete) etc in the business layer. However rendering them onto the browser to be handled in the presentation layer. For .Net, the ASP.NET MVC pattern is very good in terms of keeping the layers separated. Look into the MVC pattern.

The servlet should be the controller if you use MVC.

can you go a bit explicit in what should go in servlet?

Note
Rectangle 27 0

java Design Patterns web based applications?


1) An action which is used is called every time the HTML page is refreshed. The action should populate the data in the form when the page is first loaded and handles interactions between the web UI and the business layer. If you are using the jsp page to modify a mutable java object a copy of the java object should be stored in the form rather than the original so that the original data doesn't get modified unless the user saves the page.

2) The form which is used to transfer data between the action and the jsp page. This object should consist of a set of getter and setters for attributes that need to be accessible to the jsp file. The form also has a method to validate data before it gets persisted.

3) A jsp page which is used to render the final HTML of the page. The jsp page is a hybrid of HTML and special struts tags used to access and manipulate data in the form. Although struts allows users to insert Java code into jsp files you should be very cautious about doing that because it makes your code more difficult to read. Java code inside jsp files is difficult to debug and can not be unit tested. If you find yourself writing more than 4-5 lines of java code inside a jsp file the code should probably be moved to the action.

I have used the struts framework and find it fairly easy to learn. When using the struts framework each page of your site will have the following items.

Note: In struts 2 the Form object is referred to as a Model instead but works the same way as I described in my original answer.

Note
Rectangle 27 0

java Design Patterns web based applications?


Map<String, Action>
actions
actions.put("POST/register", new RegisterAction());
actions.put("POST/login", new LoginAction());
actions.put("GET/logout", new LogoutAction());
// ...
for (ClassFile classFile : classpath) {
    if (classFile.isInstanceOf(Action.class)) {
       actions.put(classFile.getAnnotation("mapping"), classFile.newInstance());
    }
}
for (Entry entry : configuration) {
    actions.put(entry.getKey(), Class.forName(entry.getValue()).newInstance());
}
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    try {
        Action action = ActionFactory.getAction(request);
        String view = action.execute(request, response);

        if (view.equals(request.getPathInfo().substring(1)) {
            request.getRequestDispatcher("/WEB-INF/" + view + ".jsp").forward(request, response);
        }
        else {
            response.sendRedirect(view); // We'd like to fire redirect in case of a view change as result of the action (PRG pattern).
        }
    }
    catch (Exception e) {
        throw new ServletException("Executing action failed.", e);
    }
}
public class LoginAction implements Action {

    public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        User user = userDAO.find(username, password);

        if (user != null) {
            request.getSession().setAttribute("user", user); // Login user.
            return "home"; // Redirect to home page.
        }
        else {
            request.setAttribute("error", "Unknown username/password. Please retry."); // Store error message in request scope.
            return "login"; // Go back to redisplay login form with error.
        }
    }

}
public interface Action {
    public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception;
}
public static Action getAction(HttpServletRequest request) {
    return actions.get(request.getMethod() + request.getPathInfo());
}

@AndreyBotalov: check source code of MVC frameworks like JSF, Spring MVC, Wicket, Struts2, etc. They are all open source.

@masato: You could do this in for example a static initializer block.

@masato: by the way, if you'd like to retrieve them from web.xml, then you could use a ServletContextListener for this. Have the factory implement it (and register as <listener> in web.xml) and do the filling job during contextInitialized() method.

A bit decent web application consists of a mix of design patterns. I'll mention only the most important ones.

As a side note, hobbying around with a homegrown MVC framework is a very nice learning exercise, and I do recommend it as long as you keep it for personal/private purposes. But once you go professional, then it's strongly recommended to pick an existing framework rather than reinventing your own. Learning an existing and well-developed framework takes in long term less time than developing and maintaining a robust framework yourself.

Depends. Easiest is to just do it right in the Action implementation the same way as with normal servlets (see also servlets wiki for a basic example, which you're free to refactor further into some Validator interface). But you could also do it before invoking the action, but this is more complex as it requires the validation rules being known on a per-view basis. JSF has covered this by offering required="true", validator="customValidatorName", etc in the XHTML markup.

Do the job which the "post_servlet" should do in the action instead. You shouldn't have more than one servlet. Business stuff should be done in action classes. If you'd like it to be a new request, then return to a different view which would cause a redirect and do the job in the new action associated with the GET request.

Executing the action should return some identifier to locate the view. Simplest would be to use it as filename of the JSP. Map this servlet on a specific url-pattern in web.xml, e.g. /pages/*, *.do or even just *.html.

First, the Controller part should implement the Front Controller pattern (which is a specialized kind of Mediator pattern). It should consist of only a single servlet which provides a centralized entry point of all requests. It should create the Model based on information available by the request, such as the pathinfo or servletpath, the method and/or specific parameters. The Business Model is called Action in the below HttpServlet example.

Here's an example of a LoginAction which (as its name says) logs in the user. The User itself is in turn a Data Model. The View is aware of the presence of the User.

In case of prefix-patterns as for example /pages/* you could then invoke URL's like http://example.com/pages/register, http://example.com/pages/login, etc and provide /WEB-INF/register.jsp, /WEB-INF/login.jsp with the appropriate GET and POST actions. The parts register, login, etc are then available by request.getPathInfo() as in above example.

In the below detailed explanation I'll restrict myself to request based MVC since that's easier to implement.

Keep in mind to create a "do nothing" Action for the case there's no mapping. Let it for example return directly the request.getPathInfo().substring(1) then.

Or configurable based on a properties/XML configuration file in the classpath: (pseudo)

Or dynamically based on a scan in the classpath for classes implementing a certain interface and/or annotation: (pseudo)

The Action should follow the Strategy pattern. It needs to be defined as an abstract/interface type which should do the work based on the passed-in arguments of the abstract method (this is the difference with the Command pattern, wherein the abstract/interface type should do the work based on the arguments which are been passed-in during the creation of the implementation).

The ActionFactory should follow the Factory method pattern. Basically, it should provide a creational method which returns a concrete implementation of an abstract/interface type. In this case, it should return an implementation of the Action interface based on the information provided by the request. For example, the method and pathinfo (the pathinfo is the part after the context and servlet path in the request URL, excluding the query string).

The core (architectural) design pattern you'd like to use is the Model-View-Controller pattern. The Controller is to be represented by a Servlet which (in)directly creates/uses a specific Model and View based on the request. The Model is to be represented by Javabean classes. This is often further dividable in Business Model which contains the actions (behaviour) and Data Model which contains the data (information). The View is to be represented by JSP files which have direct access to the (Data) Model by EL (Expression Language).

Then there's the Composite pattern for the case that you'd like to create a component based view which can be attached with the model and whose behaviour depends on the state of the request based lifecycle. In JSF terms, this is what the UIComponent represent.

Then there's the State pattern for the case that you'd like to add an extra abstraction layer to split the tasks of gathering the request parameters, converting them, validating them, updating the model values and execute the actions. In JSF terms, this is what the LifeCycle is doing.

Then, there are variations based on how actions and events are handled. The popular ones are:

This way you can evolve bit by bit towards a component based framework.

To get a step further, you could use the Facade pattern to create a Context class which in turn wraps the request and response objects and offers several convenience methods delegating to the request and response objects and pass that as argument into the Action#execute() method instead. This adds an extra abstract layer to hide the raw Servlet API away. You should then basically end up with zero import javax.servlet.* declarations in every Action implementation. In JSF terms, this is what the FacesContext and ExternalContext classes are doing. You can find a concrete example in this answer.

When you're using suffix-patterns like *.do, *.html, etc, then you could then invoke URL's like http://example.com/register.do, http://example.com/login.do, etc and you should change the code examples in this answer (also the ActionFactory) to extract the register and login parts by request.getServletPath() instead.

You may want to make the Exception more specific with a custom exception like ActionException. It's just a basic kickoff example, the rest is all up to you.

Note
Rectangle 27 0

java Design Patterns web based applications?


IMHO, there is not much difference in case of web application if you look at it from the angle of responsibility assignment. However, keep the clarity in the layer. Keep anything purely for the presentation purpose in the presentation layer, like the control and code specific to the web controls. Just keep your entities in the business layer and all features (like add, edit, delete) etc in the business layer. However rendering them onto the browser to be handled in the presentation layer. For .Net, the ASP.NET MVC pattern is very good in terms of keeping the layers separated. Look into the MVC pattern.

The servlet should be the controller if you use MVC.

can you go a bit explicit in what should go in servlet?

Note
Rectangle 27 0

java Design Patterns web based applications?


1) An action which is used is called every time the HTML page is refreshed. The action should populate the data in the form when the page is first loaded and handles interactions between the web UI and the business layer. If you are using the jsp page to modify a mutable java object a copy of the java object should be stored in the form rather than the original so that the original data doesn't get modified unless the user saves the page.

2) The form which is used to transfer data between the action and the jsp page. This object should consist of a set of getter and setters for attributes that need to be accessible to the jsp file. The form also has a method to validate data before it gets persisted.

3) A jsp page which is used to render the final HTML of the page. The jsp page is a hybrid of HTML and special struts tags used to access and manipulate data in the form. Although struts allows users to insert Java code into jsp files you should be very cautious about doing that because it makes your code more difficult to read. Java code inside jsp files is difficult to debug and can not be unit tested. If you find yourself writing more than 4-5 lines of java code inside a jsp file the code should probably be moved to the action.

I have used the struts framework and find it fairly easy to learn. When using the struts framework each page of your site will have the following items.

Note: In struts 2 the Form object is referred to as a Model instead but works the same way as I described in my original answer.

Note