I am in the middle of creating my own custom MVC web framework for a project. This project has very old code base where one JSP page directly submits a form to another JSP whereas the paths are also hardcoded. Now it is a big project and putting Struts or JSF will take considerable amount of time.
So my suggestion is to build a small custom MVC framework and convert many existing page flows into it and also encourage them to develop newer applications using this new MVC frameworks.
I would like to review this with all of you whether it makes sense or we should directly go to the standard MVC frameworks.
My idea
1. Create one front controller servlet which will have URL pattern like /*.sm
2. This servlet reads one config file and creates a map whose key is requestedURI and value is the class name of the command bean.
3. upon intercepting any action request it reads the parameter map (request.getParameterMap()). This servlet refers the already built map, understand whose command bean is to be invoked? Creates an instance of this command bean.
4. pass the parameter map to this command bean and calls execute method.
5. if any exception is found, front controller servlet forwards the request to one global error page
6. if everything is fine, it then forwards the request to the expected URI (by removong .sm and replace it with .jsp)
Do you think I am missing anything here? I know I can make it more fancy by providing error page per request page in the config file or so but those can be done later as well.
I think that you will end up reinventing the wheel rolling your own MVC framework. I know that it is tempting to make your own, since you won't have to get used to a new API but instead create your own and you can more easily adapt it to your specific usecases. But since it seems to be a very long lived application you will have to consider the fact, that your own framework (which may now be state of the art) will be legacy in a couple of years, too.
And that's where adapting one of the popular frameworks comes in handy. The creators of a new framework usually want others to move, too, so they will (or should) offer easy integration or migration options away from the frameworks they think they are doing better (Spring is a good example since it e.g. seamlessly integrates with existing Struts applications and you can gradually move your application without putting the old one into trash). Additionally most current frameworks are very versatile (which can sometimes be a problem since they need more time to get into it) and can be adapted to almost all usecases.
So I would recommend to review the existing solutions carefully (you can learn a lot from their design decisions and errors, too) and only start making your own if none of them matches your requirements.
Related
I'm developing a Web app (unfortunately a legacy one) in java (that runs on tomcat) with a very small, but not well organized (at least on this particular project), group and let me start by saying we have not much of experience in servlets programming.
The issue is the folloing.
I'm having kind of a trouble as the amount of servlets keep growing and growing while we implement new functions in this webapp. We don't have a project to follow and structure. Just the clint who randomly asks for new functionality out of the blue.
I would just say our web.xml is a mess. I think we should avoid to pollute the web.xml so much with new servlet every time (right now is about 800 lines and it's becoming hard to maintain), but i'm not sure about what i should do about it.
I'm exploring different possibilities, but we can't afford to explore too much so i would like to hear some idea or best practies from people with more experience than us.
I was thinking that maybe we should use CORBA ore something like that to implenet some kind of RPC. So while grouping common functionalities in a few bunch of servlets we could tame the chaos. Could it be a good idea?
What i have in mind is something like a few servlets that pose as entry points for the requests. I would like to group them by the type of response they give. So for example i have a servlet that serves me json after calling some other class that actually do the job to extract data ore manipulating data. Or again i would have a servlet that serves me files, files that another class or servlet produce. And so on. Am i looking at the problem in the right way?
I took a looked at some framework like DWR (Direct Web Remoting) but we would need to integrate it with a legacy webapp with ugly jsp pages full of scriptlet and we can't afford to jump into full ajax web pages in the limited time we have for the project.
We would need something more lightweight.
The more i search for a solution the more i get confused and overwelmed by the possibilities i find (REST, ORB, RPC, JSON-RPC...), so i ask for your help. Thanks in advance for every answers and tips.
You should definitely look into the Spring framework which is the de-facto standard for Java web development nowadays: http://projects.spring.io/spring-framework/
The Play Framework is also an interesting framework, giving you a Ruby-like development cycle: https://www.playframework.com/
Hello many of your points are valid so you can use new frameworks like spring or struts but it needs huge change over as many new levels will get added/introduced.But if you want to just get ride of many servlets you can/should use MVC architecture like framework in addition to that use a central level controller(a main servlet)-this will just take the request and checks in it (like switch case) as soon as switch case matched that helper class / utility class should called via instance or statically after that the response should also from that helper/utility class and should be sent to the main controller and that main controller will send it to respective jsps/html.
Regarding to the best way to design a system using spring-mvc (REST services) and jQuery . I think exists the following approaches.
One war file in which you have spring services and jQuery stuff, with this approach we have all the domain objects available to be used with spring-mvc, we can create initial jsp pages and then refresh some elements using jQuery calls to our services.
Two war files, one having the spring services and the other contains spring-mvc stuff and jquery, in this case the creation of pages could be done by jsp pages and also refresh elements with jquery calls to our services, but to make this possible we need to have a common library of domain objects to be used in the second war, also internally use restTemplate in some controllers that need to be created (It sounds like duplicate code).
Have one war file running the REST services and a other “package” without any java or spring stuff only jquery, it means all the call and information retrieval must to be done using jquery, initial jsp pages creation cannot be done with this option and all the content are obtained via REST services. (no need of use internal controllers to call services by java)
Thinking about it I realized that one and second have the following disadvantages.
Have services and web stuff in the same war file sound like a bad idea thinking in SOA, the movement of this war will result in move unneeded jquery and web stuff.
Have jsp and jquery stuff mixed not sound like a good idea but I think is a common practice (I wonder why?), using this I think we need to create some controllers in the second war to initially create the web pages, go using restTemplate to obtain initial information and then update or refresh using jquery calls. It feels that a have a controller just to retrieve data to the services, why don’t go directly …
I just want to implement the third approach but the question is: there is any disadvantages that I’m not seeing or any
advice that I should know before use that approach? Also there is any suggestion to handle this kind of systems it will be great to hear something from you, coming from java and jquery developers
I agree with you that version 3 gives you the most flexibility and is what you would typically see in the design world.
Treat the rest and the front end as separate applications entirely. If done correctly, you can have a very robust application capable of proper agility.
Version 1: Load the page in an initial controller call, and use jquery to make subsequent service calls. All code exists within one package.
The disadvantage is tight coupling. You are now restricted to the language of your api, and no longer providing a service based approach to your data and services.
I have seen this version applied mostly when the application developer cares more about async front end calls than a SOA based language.
Version 2: Have a war containing Spring Services, and a war for the JS.
The issues with this method can be overcome with the use of a jar instead of another server application. Though this approach is commonly used, the draw backs are still reliance on external packaging.
Using a jar that contains all the code to hit databases and create domain objects separate from the code that the controllers use to serialize and respond to web requests creates a very clean way to manage your api, however this creates a complexity and an extra component that can be avoided using version 3. It also gives the same odd behavior you see in version 1.
I have seen this approach taken by teams developing pure api applications. I have not seen this done on teams that also require a front end component. Method one or three has been used in these cases.
Version 3: Create an application that deals with just the front end responsibility Create an application that handles the server side responsibility.
In both version 2 and version 3, separate your service calls from your http calls. Make them different because it allows modularity.
For instance, we need to respond to http Requests
#Controller
class MyController{
#Autowired
private MyService service;
#GET
public String getData(String dataId){
return service.getData(dataId);
}
}
and we need to respond to active mq requests
Message m = queueReceiver.receive();
if (m instanceof DataRequest) {
DataRequest message = (DataRequest) request;
queueSender.send(service.getData(request.getDataId())); //service call
} else {
// Handle error
}
Also, it gives you the ability to manage what you need to handle on the http side different from your service side.
#GET
public String getData(HttpRequest request, String dataId){
if(!this.handleAuth(request)){
throw new 403();
}
try{
return service.getData(dataId);
catch(Exception e){
throw new WrappedErrorInProperHttpException(e);
}
}
This allows your service layer to handle tasks meaningful to just those services without needing to handle all the http crap. And lets you deal with all the HTTP crap separate from your service layer.
So, yeah, this is what I understood.
Servlet is just an intermediary responsible for finding out what the parameters in the request mean. These parameters are given to the .java file. It is a mere intermediary
.java file is the Model which does business logic
View is the JSP that will do the presentation
Did I get that right?
The Model View Controller pattern is not specific to Java or Servlet technology. There are many non-java MVC implementations, and in Java, there are non-Servlet implementations (Swing is an example).
In Java, when using Servlet-based MVC, usually an MVC framework is used. There are two main categories here: action based and component based, the difference being that action based frameworks listen each registered URL independently while component based frameworks keep a component tree and maintain server-side state.
Action based frameworks are Spring MVC, Struts 1+2, Stripes, Play etc. Component based frameworks are Wicket, JSF 1 & 2, Tapestry etc.
Your diagram gets close to the truth, but there are a few subtle misconceptions.
First, it doesn't make sense to speak of .java files. Java source files are totally irrelevant to a deployed web application, it uses compiled .class files only, and the JavaVM can be programmed in many different languages, so the application doesn't care whether the .class files were compiled from Java, Scala, Groovy, JRuby, Clojure, AspectJ or anything else as long as they comply to the Java Class File specification.
Second, while JSP has long been the default view technology in Java Servlet technology, it's far from the only one. Other technologies include Facelets, Velocity, Freemarker etc., and there's also nothing to stop you from writing data directly to a request from a controller without a dedicated view technology (although this is usually not advisable).
Basically, what MVC stands for is a system where there is separate code for business logic (the M), the view technology (V) and the Controller that ties things together. In a well-organized MVC architecture, the M part is so well encapsulated that the same business logic can also be executed through other channels (e.g. web services, direct library access etc.). Also, it should be possible to switch view technologies through configuration from the outside without editing the actual controller logic.
I would advise you to read the docs for the Spring MVC framework, it is to my knowledge the most robust (and also easy-to-use) MVC framework out there, and the tooling support is also great (in either InteliJ Idea or the Eclipse-based SpringSource Tool Suite).
When you are talking about MVC, then all three layers should be separated from each other.
In web application :
1: A controller should be responsible handling the user request then filtering & executing the appropriate actions and then forward the generated response to the client.
2: A model consist of your Business logic,beans & Pojo classes. This should deal with you logic ,perform some operation and renders the generated result to some kind of persistent object or DTO's.
3: A view is consist of your GUI, some presentation-logic , it should be separated from your back-end ,ultimately you are showing an encapsulated form of result to your client i.e. what a client actually needed.
There are two types of MVC: MVC1(Push-MVC) and MVC2(Pull-MVC)
Pull-MVC and Push-MVC are better understood with how the view layer is getting data i.e. Model to render. In case of Push-MVC the data( Model) is constructed and given to the view layer by the Controllers by putting it in the scoped variables like request or session. Typical example is Spring MVC and Struts1. Pull-MVC on the other hand puts the model data typically constructed in Controllers are kept in a common place i.e. in actions, which then gets rendered by view layer. Struts2 is a Pull-MVC based architecture, in which all data is stored in Value Stack and retrieved by view layer for rendering.
I have been handed a large Spring - Hibernate project and have been told to go through the code and figure out how it works.
I have been able to run the project in JBoss and access pages locally, but I have no idea how to figure out how the program is layed out, as I have no web programming experience.
I have been told that it is "pretty simple" and is a "normal Spring-Hibernate project."
Any idea where to begin?
Well, for starters, you'll really need to learn at least the basics of how these frameworks operate. Here's a tutorial on Spring MVC, and here's a Hibernate tutorial.
You'll need to identify the classes that create the various layers; there are certainly going to be Controller classes (which take a web request and figure out how to construct the response) and DAO classes (Data Access Objects, which manage saving and retrieving data).
There will probably be JSP files which describe the views; that is, what the user sees. The HTML code that builds the actual web pages should be here.
My suggestion: pick one simple page and follow it through. Where's the JSP that sets up the HTML for that page? Where's the controller it gets POSTed to? Does that controller call a service class or a DAO? A validator? Etc. -- type in one bit of data and follow it all the way through. It will help to have an IDE that shows you the structure of the application, and allows you to go into debug mode and step through the code.
Good luck!
I need to implement quite big system in Seam. I'm considering the way of designing the architecture. If it's good to use page controllers or application controllers or front controller or every each of them. If it's helpful to use backend bean or maybe there's no need to do that. If you have any suggestion or link to helpful article I will appreciate it.
Thanks a lot!
Daniel Mikucki
If you need to learn a lot about Seam for a project, I recommend you get the Seam In Action book, which is the best on the subject.
To answer your question, personally I prefer to use the pull-MVC style in Seam, where you refer to data in your view templates that Seam takes care of initialising, as needed, using #Factory methods. However, there is more than one way to do it in Seam, so it is worth reading about the alternatives first, hence the book recommendation.
Alternatively, build a few Seam applications first to throw away before you try to build one 'right' :)
Daniel,
It is good practice to use a front controller, most people aren't aware of that design pattern.
It is a really good design pattern to use because it ensures you are accessing the application through a single entry point. You can monitor everything that comes and goes easily with less configuration. You reduce the amount of possible code duplication because there is a single entry point. In addition to having less code to maintain, the code should be easier to follow since there is only one way in. You can then easily follow the execution flow of the application.
Unfortunately for Seam, there isn't really a front controller pattern. I haven't spent as much time as I would like to develop my own, but security and audit-ability are my number one focus.
As far as page / application controllers go, in Seam, you have more contexts or scopes available. Event, Page, Conversation, Session, Application, to name most of them.
If you're developing a controller or in Seam, a page action, most of the time, it will be event based. That is the shortest lived scope. If you have page flows, you would then use conversational-scoped components.
Take a look at the examples in the source code. You can do a lot with very little code, it is amazing, but at the same time, there is a lot going on that may take a while to pick up on.
The n-tier design that most places follow doesn't necessarily apply here. For most of my pages, I define a query that I'll use in XML (entity query), then I'll inject it into my page action and call it there. So instead of having a controller, service, dao, and entity classes, you end up with simply a page action, the queries, and entity classes. You can cut out the service and dao layers in most cases.
Your whole definition of a service might change too. For me, a service is a service provider such as notification, security (auditing), exception handling, etc. all of these services run in the background and are not tied to a particular http request.
Walter
Daniel,
I have used one controller per page, one service and one dao per entity.
Use case logic goes in the controller
Entity specific business logic goes in entity service.
Actions which span multiple entities you can create a facade service - something which sits between controller and entity services
While the above is a good and practical approach, ideally:
you could break out any non MVC code from controller into its own service class, ie. 1 service class per page
you should only access the entity dao via the entity service.
Here's how the control would flow:
Ideally:
UI
-> PageController.java
-> PageService.java
-> EntityService.java
-> EntityDao.java
Practically, you could trim down a few layers:
UI -> PageController.java -> EntityService.java
Or for actions touching multiple entities:
UI -> PageController.java -> Facade.java -> Entity1Service.java,Entity2Service.java
PageController.java would be a Seam #Component and in your ui you can refer it as:
#{pageController} and pull the data from the view.
In architecture, the most important thing is how you layer things in the stack is avoid circular dependencies between layers. For example, Entity Service should not reference Controller and so on.
The other important thing is to be consistent about layering in the entire application. Use code generators if you can to keep your code consistent across the application, it really pays off for large projects. Look into Clickframes if you are interested in code generation (Clickframes generates starter code for Seam apps with full JPA/valdiation/security support which you can then modify). See this Seam demo build with Clickframes if interested.