I need to get a few things cleared up. I have been looking for an answer for this one, but I can't seem to find a good answer to my specific questions (eg. this question was nibbling on the answer: Difference between servlet and web service).
To my understanding, there are different ways you can implement the "request handling", aka "Controller", in an "MVC oriented" web application, two of them being:
A Java specific Servlet (ie. one you create by clicking new ->
Servlet, in eclipse for example), used as a "Controller". This one
extends HttpServlet and you use methods like doGet and doPost etc.
A Spring MVC annotated #Controller class (yes, using a DispatcherServlet). With this one you use the #RequestMethod GET/POST etc.
Now to my questions...
When do you use one or the other?
Are there any general advantages to use one method over the other? (Like, is one method recommended over the other in general?)
[EDIT]: Emphasized keywords
If you're a student interested in learning the language then I would stick with servlets for now. It's possible to write a web app using just servlets but in practice you'll probably want to look at JSP's too.
A JSP is a convenient way to write a servlet that allows you to mix html with scripting elements (although it's recommended to avoid Java code in your jsp in favour of tags and el expressions). Under the covers it will be compiled as a servlet but it avoids you having to use lots of messy print statements.
It's important to have at least a basic understanding of servlets and JSP's. Spring MVC is one of many frameworks built on top of servlets to try make the task of writing a web application a bit easier. Basically all requests are mapped to the DispatcherServlet which acts as a front controller.
The DispatcherServlet will then call the controller whose annotations match the incoming request. This is neater than having to write these mappings yourself in the web.xml (although with servlet 3.0 you can annotate servlets now). But you also get many other benefits that can be used like mapping form fields to an object, validating that object with jsr303 annotations, map inputs and outputs to xml or json etc etc. Plus it's tightly integrated with core spring so you can easily wire in your services for the controller to call.
It's worth noting that there are a plethora of competing frameworks built on top of servlets. Spring MVC is one of the most popular so it's not a bad choice to look into.
A Servlet and a Spring MVC Controller can be used to do the same thing but they act on different level of a Java Application
The servlet is a part of the J2EE framework and every Java application server (Tomcat, Jetty, etc) is built for running servlets. Servlet are the "low level" layer in the J2EE stack. You don't need a servlet.jar to run you application because it's prepackaged with the application server
A Spring MVC controller is a library built upon the servlet to make things easier. Spring MVC offers more built-in functionalities such as form parameter to controller method parameter mapping, easier handling of binary form submissions (i.e. when your form can upload files). You need to package the required jars to your application in order to run a Spring MVC Controller
You should use a servlet when you need to go "low level", and example could be for performance reason. Spring MVC performs good but if it has some overhead, if you need to squeeze out all you can from your application server (and you have already tuned the other layers such as the db) go with a servlet. You can choose a servlet if you want to understand the foundation of the J2EE web specifications (i.e. for educational purposes)
In all the other cases you can/should choose a web framework. Spring MVC is one of them; with Spring MVC you don't need to reinvent the wheel (i.e binary form management, form parameter to bean conversion, parameter validation and so on).
Another plus of Spring MVC is that in one class you can easily manage input from different urls and methods, doing the same in a servlet is possible but the code is more complicated and less readable.
My opinion is that Spring MVC is good for building rest services and managing simple applications (i.e web application with simple forms). If you need to manager very complex forms with Ajax, nested forms, and an application with both session and page state my advice is to switch to a component based framework (like apache wicket for example).
JSF and JSP aswell as Spring MVC builts upon Servlets. The problem this that servlets are not very "nice" to work with because you have to write direct html.
If you are able to use mordern web technologies I would just use servlets in positions that need direct http output like writing an image from a database to http.
Using SpringMVC or JSF which work with a Dipatcherservlet or FacesServlet is just faster and more fun. They parse your files and send it through a servlet.
Related
I'm really new to JSP and Servlets and all that jazz, and I'm confused about how to approach it.
Right now my main confusion is as follows:
It seems there are two ways to get a web page to display on the screen in a Java EE/JSP project:
Create an HTML page with the extension .jsp and in the web.xml file, map it to a url pattern (let's assume just /)
Create a Java class that extends Servlet, override the doGET() method to return a string of HTML code and map to this Java class in the web.xml.
My JSP project requires a decent amount of Java code to perform logic and login/logout operations. I've read that it's bad practice to inlcude Java code inside JSP pages as it becomes impossible to reuse, hard to keep track of, messy etc. I want to include much of code in Java, which will feel much more natural for me.
How should I build my project (assuming it's a simple beginner project in which I want to employ the best practices for organization, testing etc in preparation for building a larger project)? How can cleanly deploy web pages from inside Java classes, rather than having many JSP pages containing bits of Java code?
The pattern I've used in the past is to:
1) Write the servlet to perform whatever logic is necessary and to construct a reasonable number of serializable java objects to hold all of the data you want to be rendered via HTML.
2) The servlet stores those objects into the HTTP request and forwards the request and response objects to a JSP:
request.getRequestDispatcher("/some.jsp").forward(request, response);
3) The JSP can access the java objects in the request and merge the data with the static HTML to complete the request.
This is exactly the problem MVC pattern solves.
You do all your complex logic in the Controller (simple Java class, or a Servlet), then pass the data to View (JSP, Velocity, Freemarker, anything that can process the data and make a HTML).
There are several implementations of MVC for Java most popular being Spring MVC and Struts. Alternatively, you can just use your servlet for all your logic and then manually forward the request to a JSP for processing:
request.getRequestDispatcher("/index.jsp").forward(request,response);
If your are looking for best practices in clean separation of java code from the presentation, you might as well use a MVC Framework (Spring MVC or Struts are well know examples) that will help you to cleanly separate :
view layer (JSP)
controller layer
service layer
domain objects
persistence layer
It may be hard to begin with, but you will find nice tutorials through official sites and google.
If you want to only use servlets and JSP, the common rule is to have all logic and Java code in servlets, and that those servlets simply forward to JSP pages that will do the view part. The communication between then is done with request attributes (and of course, session and application context attributes.
Good luck ...
To manage bit of java code, you can use Scriptlet.
Also mentioned in other answers, you can use jsp:forward or response.sendRedirect
to call web pages.
Also see What is the difference between jsp:forward and response.sendRedirect
I'm not sure where you heard that its bad practice to include Java code in the HTML(JSP) files but in order to have a dynamically data driven website, Java is what you would use in the HTML(JSP). Keep in mind, all of your front end design will be in the HTML using JSP, and all of the your logic for handling requests and redirectors and passing data will be managed in the servlets using Java.
Your servlets can pass data, whether it be from a database or other data source, to the front end and your JSP will just help in displaying that data. It's called JSP for a reason. You can write Java in it.
The best approach for designing websites in Java is to use the MVC pattern that way it helps seperate all of the core functions of the site and can easily be scaled and managed.
Do you have any code that you have to show what you have done so far?
I am supposed to redesign a web application that was originally created in JSP. However, I have two important requirements that this application should meet.
This new web application shall be able to keep its existing direct URL structure, that looks like this: http://existingurl.org/appname/file.jsp?id=0000000000001&optionalParams=something
It shall Support Javascript and AJAX (But I think that this one is not really a problem nowadays)
My first choice was spring MVC due to its popularity, but as far as I know the URL structure in Spring MVC would not support the file.jsp part of the URL. In Spring the URL would look like this:
http://existingurl.org/appname/file/id/0000000000001?optionalParams=something because it tends to hide the extension.
Is there any way to support this direct URL from my first requirement with Spring MVC? Or would you recommend me any other framework?
Spring mvc will absolutely let you keep your mapping. You can map it how you like!
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 am trying to familiarize myself with JavaEE. I am a bit confused as to what the purpose of each "component" (for lack of a better word) is: Session Beans and Servlets, and how they properly interact with a web application (client-side JavaScript).
In an attempt to understand this I am building a simple web application. What is the preferred way to use each component to build something similar to the following:
User visits a "Log in" page
User inputs data and clicks submit. I then send an request with AJAX to log in the user.
The server side then validates the user input and "logs" the user in (returns user profile, etc.)
When sending the request, do I send it to a Servlet (which uses an EJB), or to a Session Bean through WSDL? How do I go about maintaining a "state" for that user using either method? I assume with Session Beans it's as simple as annotating it with #Stateful.
Also, I assume the requests sent from the client side must be in SOAP format. How easy is it to use something more lightweight (such as JSON)? While I would prefer to use something lightweight, it's not necessary if SOAP makes development faster/easier.
The Java Enterprise Edition tutorial address pretty much all of the topics you bring up; what's the purpose with the different kind of bean types, how do I implement web services, how do I implement authentication, etc.
I highly recommend you take the time to build the sample application, especially if you're completely new to the Java Enterprise Edition (Java EE). It is important you build up a good understanding of the core concepts because it can be hard to know what to focus on in the beginning due to the breadth and depth of technologies and standards that comprise Java EE.
One thing to keep in mind is that while Java EE certainly tries to support best practice and enable design and development of secure enterprise applications that perform and scale well, it does not prescribe or limit enterprise applications to follow one particular protocol, data format, and enterprise application design pattern. Some protocols and formats are better supported out of the box by the core framework implementations, and some choices are vendor-dependent, but very few specific technology choices are locked into the specification.
To answer some of your specific questions, Java EE has great support for SOAP, but it does not preference nor limit web services to the SOAP protocol. With JAXB and JAX-RS it is just as easy to develop RESTful web services that accept and return XML or JSON, or both. It's up to you to decide whether you need to use SOAP, REST, or another protocol.
It's also your choice whether you want to use frameworks like JAX-RS or explicitly develop Servlets to handle HTTP requests and responses. In many cases, JAX-RS will have everything you need, meaning you'll be able to implement your web services as plain old Java methods with a few annotations without ever having to bother with marshalling and unmarshalling contents and parameters.
Similarly, with JAXB it's up to you whether you want to use WSDL or not. It's great if you have WSDL definitions, but no problem if you don't.
In many cases you will typically maintain state using the Java Persistence Architecture framework (JPA), and access and manipulate such data through stateless session beans. Developers new to Java EE are often tempted to use stateful session beans to maintain state that is better managed in the persistent storage. The tutorial takes you through the different kinds of bean types and their purpose.
Web services (WSDL, SOAP, etc.) are usually used for communications between applications.
Inside a single web app, you usually make simple GET/POST requests, using AJAX or not, and receive either a full HTML page, or a fragment of HTML (AJAX), or XML or JSON data (AJAX). The browser usually talks to a servlet, but it's rare to use servlets directly.
The usual way is to use a framework on top of servlets. The frameworks can be divided in two big categories : action-based frameworks (Stripes, Spring MVC, Struts, etc.) or component-based frameworks (JSF, Wicket, Tapestry, etc.).
In a n-tier application, all of the above technologies are supposed to only contain the presentation layer. This presentation layer talks to a business layer, where the real business logic happens, where transactions are used to access databases, messaging systems, etc. This business layer is where EJBs are used.
You can create basic architecture as follows :
Create EAR instread two different Project like EJB Jar and Web Application WAR
You can create servlets which will call some delegate class which has logic to reffer the EJB
Either by calling it as remote call/ Either by Using #EJB annotation in the Delegation Class.
ServletClass {
do/post(){
DelegateClass d = new DelegateClass();
d.callMethod(withParam);
}
}
DelegateClass {
#EJB
EJBlocalinterface ejbintance;
void callMethod(DefinPrarm){
ejbinstance.callEJBMethod();
}
}
#Statelss
EJBbeanClass implements EJBlocalinterface{
void callEJBmethod(someParam){
}
}
In our application, we structure different web applications by Servlet. There are many, many Servlets and Filters in our applications.
We already use different frameworks but not for this particular legacy web application. One issue is that one application/servlet is completely separate from another.
If you were to redesign your application that used this legacy design, how would you fix the issue where you have your application broken by too many servlets.
I was considering some kind of "Servlet Manager" that would group a bunch of servlets and then invoke the proper servlet when appropriate.
Spring has the facility to delegate requests to existing legacy Servlets (using ServletWrappingController or ServletForwardingController), if that is what you so desire.
So you could have a Spring DispatcherServlet sitting at the front of your legacy servlets, making full use of Spring's request routing facilities. Spring could also give you the facility for more easily sharing stuff between the servlets, but putting shared components in the servlet context for you.
Lookup the page controller / front controller pattern. It boils down to having a single servlet which controls the requests. Inside the servlet you need to lookup the action (just a business/domain object) associated with the particular request and then execute it.
Basic pseudo-example:
protected void processRequest(request, response) {
Action action = ActionFactory.getAction(request);
action.execute(request, response);
}
You could use the original url-patterns to return the desired Action. The ActionFactory could hold a Map<String, Action> wherein the key is less or more the original url-pattern. You could use request.getPathInfo() to determine the url-pattern. You could maintain those url-Action pairs in an xml or properties file or just adhere special naming conventions for classes implementing Action. The Action implementations can then use the "original" servlet coding.
However, if you're open for using an existing framework, then I would recommend just adopting one.