I am working within a RESTful Web Framework that is natively script (JSP) based. The Framework has a routing mechanism that automatically sets a number Request attributes, which are then available in the JSPs (One of the attributes being a "Model" of the requested resource; which is basically just a HashMap).
The issue is 90% of the time, some amount of logic is required to be added to the JSP, be it more complex domain logic, retrieving other resource data (other Models), or scrubbing data for output.
I am looking at various establish web application design patterns for extracting domain logic out of the JSP, and keeping the JSP as logic-less as possible.
A few things to note:
Within the system im working in, the Model (the data pull from the database) is provided but the Framework (the previously mentioned HashMap); I could create my own Model wrappers around this data, but it's probably unnecessary.
JSP/Scripts are the end points for Requests - If I use a pattern that uses a Presenter/Controller-type object that returns a View bean (ViewModel?) which contains all the data the view will use, I will need to have a line in the JSP which calls the Presenter/Controller and instantiates the View bean.
Currently I've created a Presenter POJO for each Module (script), which has access to the Model (again, the Framework sets this as a Request attr), and simply instantiate it at the top of the JSP, and use it more or less like a bean.
If I understand it, correctly, I believe i've implemented the Presentation Model design pattern. [1]
Ex.
JSP looks like:
<% DemoPresenter demo = new DemoPresenter(request) %>
<%= demo.getTitle() %>
- or add it to pageContext to use w JSTL/EL -
<c:set var="demo" value="new DemoPresenter(request)"/>
${demo.title}
And the "Presenter/Controller" looks like:
public class DemoPresenter extends BasePresenter {
private String title;
public DemoPresenter(HttpServletRequest request) {
FrameworkModel model = request.getAttribute("frameworkProvidedResourceModel");
this.title = model.get("title").toUpperCase() + "!!!";
}
public getTitle() { return this.title; }
}
Any thoughts on using the Presenter obj directly in the JSP/Script, vs having it return a "logic-less" ViewModel bean that the Presenter populates w/ data? The advantage to this is I could have a single Presenter managed various "Views" of the same resource (such as Show-view, Edit-view, Summary-view, etc.) - Below is an example of how i could get various view models.
/blog/posts/1/show -> executes JSP which gets its ViewModel like so:
<% DemoDefaultViewModel default = new DemoPresenter(request).getViewModel(DemoDefaultViewModel.class); %>
/blog/posts/1/edit ->executes a JSP which gets its ViewModel like so:
<% DemoEditViewModel edit = new DemoPresenter(request).getViewModel(DemoEditViewModel.class); %>
I would like to keep a simple solution without too many extraneous pieces. I also can't get too fancy as I am working within a strict predefined framework - I just want to figure out a good way to move all my domain logic out of the JSP into more reusable, testable Java classes.
[1] http://martinfowler.com/eaaDev/PresentationModel.html
Check out struts.
I must admit to only having used the older version but the 'front controller' servlet idea seems to be what you're after . It is a special servlet to run common code and route requests.
It also has actions which can be tested outside of the web container.
The day I moved from pure JSP to struts was one of the best days of my web development life! The project started to feel organised and much easier to manage.
There are lots of MVC frameworks. For example Struts uses a front controller servlet to dispatch requests to a class (controller) depending on the resource used. The class processes the request and sends the result to the view (typically a jsp). The model is any class that represents your data. FYI, a Map is not a framework. Representing your data as a MAP only, will work, but is ugly and hard to maintain.
Without knowing your strict framework, generally accepted good practice would be to keep your business logic centralised and independent of any framework. Use your framework for plumbing only. Get your controller to mediate between your presentation and business logic, again this is just plumbing. Put your display data in the right scope (almost always the request scope) so you dont have to have scriptlets as in your example.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
I am designing a simple web-based application. I am new to this web-based domain.I needed your advice regarding the design patterns like how responsibility should be distributed among Servlets, criteria to make new Servlet, etc.
Actually, I have few entities on my home page and corresponding to each one of them we have few options like add, edit and delete. Earlier I was using one Servlet per options like Servlet1 for add entity1, Servlet2 for edit entity1 and so on and in this way we ended up having a large number of servlets.
Now we are changing our design. My question is how you exactly choose how you choose the responsibility of a servlet. Should we have one Servlet per entity which will process all it's options and forward request to the service layer. Or should we have one servlet for the whole page which will process the whole page request and then forward it to the corresponding service layer? Also, should the request object forwarded to service layer or not.
A bit decent web application consists of a mix of design patterns. I'll mention only the most important ones.
Model View Controller pattern
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 are variations based on how actions and events are handled. The popular ones are:
Request (action) based MVC: this is the simplest to implement. The (Business) Model works directly with HttpServletRequest and HttpServletResponse objects. You have to gather, convert and validate the request parameters (mostly) yourself. The View can be represented by plain vanilla HTML/CSS/JS and it does not maintain state across requests. This is how among others Spring MVC, Struts and Stripes works.
Component based MVC: this is harder to implement. But you end up with a simpler model and view wherein all the "raw" Servlet API is abstracted completely away. You shouldn't have the need to gather, convert and validate the request parameters yourself. The Controller does this task and sets the gathered, converted and validated request parameters in the Model. All you need to do is to define action methods which works directly with the model properties. The View is represented by "components" in flavor of JSP taglibs or XML elements which in turn generates HTML/CSS/JS. The state of the View for the subsequent requests is maintained in the session. This is particularly helpful for server-side conversion, validation and value change events. This is how among others JSF, Wicket and Play! works.
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.
In the below detailed explanation I'll restrict myself to request based MVC since that's easier to implement.
Front Controller pattern (Mediator pattern)
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.
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);
}
}
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.
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.
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.
Strategy pattern
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).
public interface Action {
public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception;
}
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.
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.
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.
}
}
}
Factory method pattern
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).
public static Action getAction(HttpServletRequest request) {
return actions.get(request.getMethod() + request.getPathInfo());
}
The actions in turn should be some static/applicationwide Map<String, Action> which holds all known actions. It's up to you how to fill this map. Hardcoding:
actions.put("POST/register", new RegisterAction());
actions.put("POST/login", new LoginAction());
actions.put("GET/logout", new LogoutAction());
// ...
Or configurable based on a properties/XML configuration file in the classpath: (pseudo)
for (Entry entry : configuration) {
actions.put(entry.getKey(), Class.forName(entry.getValue()).newInstance());
}
Or dynamically based on a scan in the classpath for classes implementing a certain interface and/or annotation: (pseudo)
for (ClassFile classFile : classpath) {
if (classFile.isInstanceOf(Action.class)) {
actions.put(classFile.getAnnotation("mapping"), classFile.newInstance());
}
}
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.
Other patterns
Those were the important patterns so far.
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.
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'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.
This way you can evolve bit by bit towards a component based framework.
See also:
Examples of GoF Design Patterns in Java's core libraries
Difference between Request MVC and Component MVC
Show JDBC ResultSet in HTML in JSP page using MVC and DAO pattern
What components are MVC in JSF MVC framework?
JSF Controller, Service and DAO
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.
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.
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.
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.
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.
BalusC excellent answer covers most of the patterns for web applications.
Some application may require Chain-of-responsibility_pattern
In object-oriented design, the chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain.
Use case to use this pattern:
When handler to process a request(command) is unknown and this request can be sent to multiple objects. Generally you set successor to object. If current object can't handle the request or process the request partially and forward the same request to successor object.
Useful SE questions/articles:
Why would I ever use a Chain of Responsibility over a Decorator?
Common usages for chain of responsibility?
chain-of-responsibility-pattern from oodesign
chain_of_responsibility from sourcemaking
I am quite new to Java/Servlets/Tomcat etc. but have a fairly good understanding of web apps from my days as a CGI/PHP developer.
I have a JSP index.jsp that presents a table from a database.
I have a Results.class that is a normal Java class (not a servlet) that queries a database and returns a string from a method: public static String displayAllResults()
The String being returned is an html table.
So in my index.jsp there is a line that says something like:
String table = Result.displayAllResults();
And then the table is displayed as I'd hoped - All good!
My question is this: is there any advantage/disadvantage to using normal Java classes instead of Java servlets in this manner or should I port all of my classes to servlets for added functionality??
You should really be using MVC frameworks like Spring MVC or struts2. You should always have clear abstractions:
Dao Layer
Service Layer
Business Layer
Model Objects
DTO's
Helpers/Utils
Whenever possible use EL languages like JSTL/OGNL on JSP pages. Never ever use scriptlets. If you use any of the above MVC frameworks, you'd probably never need to use Servlets directly!
Displaying grids with data from database use something like DisplayTag or Jqgrid (with Ajax calls)
It's generally considered poor practice to be invoking Java from a scriptlet in a JSP page. JSP is intended to do HTML formatting, with some extra intelligence around using the Locale and things like that. A better PHP, if you will. Database processing should be handled by a servlet.
I think understanding the purpose of Servlet, JSP, and normal classes will answer your question.
As per my understanding, JSP is used for View purpose, that is, rendering UI to the screen is role of jsp.
whereas, Servlets are used as a controller, whose role is to act as a bridge between your Views and Models.
Normal java classes can act as a Model, here you can perform some core business logic.
I have been reading a lot on MVC but really don't know if i am clear on the concepts of MVC or not
recently developed an application what i did is
1)on jsp load called a function
2)using AJAX called a servlet and servlet is there performing all the logic
3)servlet called a java bean and a java class to perform some logic and return result
4)based on the result returned form the class i am displaying an image say if result is 1 then image A ,if 0 then Image b
5)on servlets POST method i am using out.println()-->to write the complete output
6)the function on jsp after returning the call will set the innetHTML of required div by the output generated by the servlet
now say the output servlet is producing is the table
instance name|instance state
now if i want at some time to change the display for this table to say
instance state|instance name
to do the above mentioned change i have to recompile my servlet and redeploy the war
is it really a MVC?
and someone suggested me to use JSON store object of a bean containing data as JSON and then return the JSON object to the jsp
and at jsp using this object contruct the table!
any pointers on this will be of great help!!
Whether you have to redeploy usually depends on your development environment. If your using an IDE that builds automatically as you make changes, and the server is run from the IDE you are using, you may not need to rebuild the war. You can always try to view the source code to see if you need to redeploy. Back end code usually has to be redeployed.
Based on the ajax reponse obtained.
You can hide or show the images that you tend to.
How about getting the image link instead of out.print printing the bytes[] if i am not wrong.
When you want to redirect to another page, how about redirecting it from the servlet itself using response redirect.
Lets have a quick look at what is MVC?
MVC(Mode-view-controller ) as the name suggests is software architecture pattern , which encourages application to have its Model Classes (i.e domain models / DTOs) views (i.e can be JSP, JSON etc) and controller (i.e Servlet) to be as modularized as possible so that it encourages re-usability, loose-coupling between the different layers and Seperation of Concerns.
So the key idea behind this to encourage Seperation of Concerns .
Say i want to change the view from JSP to freemarker view , if MVC is tighly followed , i should be able to accomplish the change with minimum to no impact to Controller layer (i.e Servlets)
Well you see this can only be achieved if had clear layer separation in my webapp.
If i had just scattered all the functions without regard to MVC like having views generated from the Servlet, or making service level calls like accessing the DB directly from the Controller etc is bad because any change in the view or the Database layer will cause massive changes at the Servlet .
So to answer your question , your servlet should not directly produce the HTML output.
Store all the objects that would want to generate view in Request Attribute and access it in JSP
And to recompile Sevlet doesnt mean you dont follow MVC , just that by following MVC your changes are minimal and are grouped at a single place.
For now drop JSON concept , make it plain and simple
Go through this tutorial , which fairly explain you how to achieve a neat MVC
Jsp MVC tutorial.
Once you grasp , you can always add more complex things like JSON, AJAX , Asynchronous Request etc
For a web application, I need to return a model to a view.
For a mobile application or API, I want to return xml or json.
Is it possible to do all of these using a single controller method, or do I have to duplicate this and create seperate API controller's etc?
With Spring MVC 3.x you can do this with just the one controller method. The trick is to wire up the appropriate ContentNegotiatingViewResolver in your Spring config. You can configure it to return the desired content type based on file extension and/or requested mime type.
It works best for methods that only add a single model attribute to the Model, otherwise the JSON/XML starts to get a bit ugly.
I often find its simpler/nicer to implement separate controller methods for my web service requests, as you can better control the format of the JSON/XML and the code is easier to maintain in the long term.
EDIT: Just to qualify my comment above, I find that complex JSP pages where there might be up to 5-10 model attributes added to the page, that the resulting JSON tends to be quite messy and you usually find you only really want 1-2 of those in the JSON. OTOH, simple pages with 1-2 models added work quite well.
i have a question that is more design and architecture related. I am coming from a classical MVC based background and have to get my hands dirty on JSF2. I read the IBM articles on JSF2 (http://www.ibm.com/developerworks/library/j-jsf1/) and think i understand the overall concept.
I started to get in touch with JSF2 trough ROO. I have the feeling that ROO (maybe this is true for any JSF2-Type App, or maybe not) is making very strange/unclear use of beans. It is in general really not clear to me what the actual role of a Bean is! For example, if i have a view with a form that is for editing a single user-entry, i would initialize the user in a, lets call it UserBean (maybe store in in a member variable) and access this variable trough getters. If i now want to overview all users, i would again render the view in in the UserBean hold a collection of users and again access this collection trough getters. The previous description is actually the way i would do things with jsf. This means i would user the UserBean more as a statefull-service as a controller.
In a typical controller situation i would create for every type of action (list user, edit user, view user, etc) a separate controller, with specific initialized data and this way i would separated the context of the logic by controllers.
I often make use of context specific services, e.g. if i handle user's often an spread over the application, i create a user-service that handles user specific logic that is maybe to complex to be put into the itself. If i now for example look into roo generated Beans, i would find methods that programatically render forms, input fields, labels, that again store list's of users, boolean fields that indicate if data had already been loaded, single user members and a lot of methods that more look like to be put into a UserService (or whatever). I am wondering if this is the way JSF2 is intended to be used, in words: pushing everything that is related to one context into on bean, not making use of service and writing "super-controller-beans" that handle everything.
I don't really know if you get the question right, but what would maybe help me is, a hint to
a very exemplary and commendable example application that makes use of beans the way they where intended to be used in combination with jsf2 features and usecases that for example implement basic CRUD usecases around a given type of entity. (One big confusing point is, that in my case ROO always makes use of AJAX and javascript stuff like Modal-Dialogs to implement CRUD logic. I wonder if with JSF there is a more classical way to to this?[With 'classical' i mean for example URL-Based views and separated views for listing, editing and viewing entities])
a resource that enlightens typical "thats-the-way-the-good-guys-do-it" JSF-Patterns (maybe this is J2EE Patterns?).
Thanks you so much!
Please feel free the push me to concretize specific points if i am not clear!
The link for JSF2 you have posted points to JSF1.2 article. In case you want to start of with JSF2 or JSF I suggest following links.
JSF 2.0 Tutorial # mkYong.com
BalusC JSF blog
Stackoverflow wiki for jsf
I'll suggest start with plain vanilla JSF rather than ROO with JSF to get a hang of JSF.
To answer your question
First link provides you with simple jsf examples, in JSF you can have both ajax based and classical way of submitting form. In JSF 1.x versions ajax was not part and parcel of JSF it was implemented by third party component library mainly RichFaces and PrimeFaces to name few. In JSF2 there is inbuilt support for ajax, this does not apply third party components are no longer required, they still provide some extended features. I'll suggest go through this link to find differences between JSF 1.x and JSF 2.
Patterns I am not aware of as such as specific to JSF apart code can be categorized in model - view - controller. Typical case Person represents model, PersonMangedBean plays role of controller which plays central role of getting data from view(jsp/facelets) and after processing data in bean itself or service beans handles navigation to classic views may be listPersons.xhtml.
JSF managed beans are not "super-controller-beans" handling every thing in that bean. I try to categorize things the way you mentioned i.e. have a service layer where we have all business logic may be EJB or Spring managed bean and it decouples at-least business logic away from view technology JSF whereby it(service) can be reused somewhere else as a library if designed properly.
Tip: JSF is component based framework not an action based and it has lifecycle of its own, do get a grip of that life-cycle will save lots of time and proper understanding of the framework. This link though for JSF 1.x holds good for JSF2 too, for basic understanding of life-cycle.
Hope this helps.