Friday, February 1, 2013

Head First Servlets and JSP

Chapter 1 & 2


1- in servlet we start a new light weight thread for each request, not a process like CGI
2- Servlets dont have a main() method, the container takes care of calling the servlet
3- The container provides lifecycle management, multithreading, security services to servlet.

How Container Handles a Request
1-the http request comes to the container
2- the container creates a HttpServletRequest request and HttpServletResponse response objects
3- the container find the correct servlet to call based on the url and create (or allocate) a thread for the request, it also passes the request and response objects to these threads
4- the container calls the servlet's service() method.
5- the service() method calls doGet() or doPost()
6- the doGet() generates the page and put it in  a response object.
7- the containers convert the response object to HTTP response and send it back to client
8- the container deletes the request and response objects.

How to map between URL and Servlet
sure the mapping done by deployment descriptor, the container reads and understand the descriptor and does the mapping


the first thing you map the url that the client see to servlet-name
then you map the servlet-name to the servlet class


Servlet, JSP and MVC



the controller is the servlet
the view is JSP
the model is POJO

Web container, EJB Container and JEE Application Server



Web Container: handles Servlet & JSP, TOMCAT is Web Container
EJB Container: Handles EJB
JEE Application Server: handles both of them


Chapter 3 & 4 MVC & Request-Response



When we work with servlets we should know these important interfaces and classes



and usually the servlet extends HttpServlet

Servlet Lifecycle
the life cycle is very easy, the servlet is either initialized or doesnt exist.


to understand more, the Container does the following


Firstly the container will load the servlet class,
then it will call the default constructor
then it will call the init() method
then service()
and when it finds appropriate it calls the destroy()



very important to understand that the container load only one instance of each servlet (there is a case with multiple instances with SingleThreadModel we will talk about it later), and create one thread for each request.



2 Important objects created by the container and passed to the servlet
1- ServletConfig: each servlet has one ServletConfig object
2- ServletContext: each web application has one ServletContext object (should be called AppContext)

Init() and constructor
as you can see the container calls the constructor then the Init() method. the question here is why we have a constructor and Init() methods, why dont we have just the constructor.

The first important thing, the init() method takes a parameter which is ServletConfig, which is created by the container and passed to the servlet.
you can say that we can build a constructor with argument why dont we do that. Actually the Container create the servlet class dynamically using reflection, in JDK 1.0 (when the Servlet was created) we werent be able to create a class dynamically using a constructor with argument, Thats why designers added the Init() method. the second reason, you want to force the inherited class to implement the Init() method, you cannot FORCE THE INHERITED CLASS TO IMPLEMENT A CONSTRUCTOR.

Request & Response




GET & POST
as we know Post has body and it is not idempotent
Get has no body and it is Idempotent

Redirect vs Dispatch
in redirect you send the response to the client with 301, the client send another request.
with dispatch you do the things on the server side:

response.sendRedirect()

or




Chapter 5 Attributes & Listners


Servlet Config
in order not to hard code some values, you can add these values in web.xml like this

later, we can read these values using

The container reads this information once, you need hotdeploy if you want to change these values

Servlet config is available only for the mentioned servlets, (e.g. BeerParamTests in the previous example), in order to make something global you should define context param, context param are available for the whole website 



now you can read this value wherever you want
getServletContext().getInitParameter("adminEmail")

So, we have one servletConfig object for each servlet (including jsp as a jsp page is converted to servlet) and one servletContext for the whole app.

Listeners
the idea of listeners is like interceptors, when something happens go and call them.
we have different type of listeners

1- ServletContextListener: this listener is used if you want to be notified if a context param is created or destroyed.

example of using this listener: unfortunately, in context param you can add only string values, you cannot add objects, so you can use the Listener to be triggered when a new context param is added and then add the object as attribute:


the listener should be defined in web.xml


list of listeners

Attributes Scopes

VERY IMPORTANT
Context Attributes are not thread safe, so you need to synchronize them if you want


Session Attributes also not thread safe:


Request Attribute are thread safe.

SingleThreadModel
you can define a servlet to implement SingleThreadModel, then the servlet will not receive concurrent requests, the container will send the requests one by one.


Chapter 6 Sessions & Cookies



1- The container takes care of sessions
2- HttpSession s = request.getSession();
is used to get a session or to create a new session.
3- you can check if (session.isNew()) to check if the session is new
4- you can use request.getSession(false) to return a session only if it was created before otherwise it returns null.
5- the container adds jsessionid to cookie.
6- if a user doesnt enable cookies, then you can add jsessionid to the query string, you can do that by using
response.encodeUrl("THE URL");
the encodeUrl() will add the session information

7- never do something like
String sessionId = request.getParameter("jsessionid"); 

always read the session form request.getSession();

Session Interface
the session interface has important methods like:
getCreationTime()
getLastAccessTime()
setMaxInteractiveInterval(): this is to set timeout for a specific session
invalidate();

Session timeout
to set session timeout you can add the following to web.xml

Cookies
some functions that you may use them when it comes to cookies

1- Cookie x = new Cookie("userName","hassan")
2- x.setMaxAge(30*60)
3- response.addCookie(x);
4- request.getCookies()

Distributed Systems Cluster and ServletContext, ServletConfig and Session
when we have a multiple machine in cluster, each machine will have a ServletContext and ServletConfig, however the session information are shared among all machines.
The session will be migrated from machine to another

Session Listeners
there are number of listeners that can be used with sessions
1- HttpSessionListners: will listen to when the session is created or destroyed
2- HttpSessionActivationListener: this is used when session is moved from one machine to another in a cluster, sessionDidActivate and sessionWillPassivate
3- HttpSessionBindingListener: this one you add it to a class, so it will be notified when a class object is added to a session or removed

public class Car implements HttpSessionBindingListener {
   public void valueBound()
   public void valueUnBound()
}

4- HttpSessionAttributeListener: will listen to when a new attribute is added or removed from a session, attributeAdded and attributeRemoved and attributeReplaced


Chapter 7 JSP


1- all JSP pages will be converted by the container to Servlets.
2- in JSP we use
<% %> to write scriptlet: <% int x =5; %>
<%=  %> to write expressions, <%= x %> this will be converted to out.print(x);
as you can see we dont add ; in <%= x %>
<%@  %> to write directives <%@page import ="foo.*" %>



Important 
we know that the container create one instance of a servlet, and then create multiple threads.

so if you have

public class xxx extends HttpServlet {
int counter = 0;

public void doGet() {
  counter ++;
}
}

the counter value will be saved between request as it is an instance variable for the class. (sure this is not thread safe, we are just talking about saving the value).

As we mentioned before, JSP will be translated to Servlet, if you wirte something like

<% int counter =0 ;%>

this will be translated to
public void doGet() {
int counter =0;
}


however if you want to define a counter as instance variable you should write

<%! int counter = 0; %>

then it will be translated to

public class xxx extends HttpServlet {
int counter =0;
public void doGet() { }
}

you can even define a method

<%! int doubleCheck() {return true;} %>

/////////////////////////

we know that the first jsp request is slow because the container will do the compilation and transformation to servlet upon the first request.

JSP Methods
as the JSP pages will be converted to a class, 3 methods are important in this class and you can override them
jspInit(): will be called by servlet's init() method
jspDestroy(): will be called by servlet's destroy() method
jspService(): will be called by servlet's service() method.

JSP and web.xml
As JSP will be a servlet, you can define it in the web.xml


as you can see, we defined some init-param for the jsp, and we used <jsp-file>

now you can override the jspInit() method in JSP.


JSP Attributes
as we saw before, for servlet we have application attributes, session and request.
in JSP we have also PAGE attributes which can be set using pageContext

the PAGE attributes are available between JSP pages.
you can set
pageContext.setAttribute("one",1);

you can get:
pageContext.getAttribute("one");

in addition you can get and set all other attributes from pageContext:
pageContext.setAttribute("one", 1, PageContext.APPLICATION_SCOPE)
pageContext.setAttribute("one", 1, PageContext.SESSION_SCOPE)

Some Directive:
<%@ page ... > : to import a page
<%@ taglib ...>: to import tags
<% include file="x.html" %> : to do something like a master page.

JSP Expression Language
rather than writing something like <% application.getAttribute("mail") %>
you can use expression language, which is written like this ${}
${applicationScope.mail}

How to disable scripting in JSP
to disable scripting in JSP you should do that in web.xml


How to disable Expression Language
to disable EL, in the whole application, add this to web.xml


if you want to disable EL in one page, you can write this

<%@ page isELIgnored = "true" %>



Chapter 8 Scriptless JSP


in this chapter we will talk how you can right standard action with no scripting inside JSP pages.

for example to read an attribute in JSP page you may write:

as you can see we cand use
<jsp:useBean>:

the id="person" is basically the request.setAttribute("person", p). and also it is the bean id


<jsp:getProperty>: we use it to get a bean property value,

important: if there was no attribute for "person", jsp:useBean will create an empty bean.

and also you can set a proerty
<jsp:setProperty name="person" property="name" value="Fred" />

you can do this:

as you can see, jsp:setProperty is inside jsp:useBean, which means if the bean wasnt set (the attribute "person" wasnt there) do a setProperty

jsp:useBean and Polymorphism 
lets say you have
abstract class person {}
public class Employee extends Person{}.

if you write
<jsp:useBean id="person" class="foo.Person" scope="request"/>
you will get an exception, because Person is an abstract class.

in order to do a polymophic useBean

<jsp:useBean id ="person" type="foo.Preson" class="foo.Employee" scope="request"/>
as you can see we use type and class

Send Requests Directly to JSP page:



the request now will go directly to the jsp page not to the servlet.
in the JSP page you can read the inputText property:



as you can see we are using script to read the "userName"

in order to write the code above scriptless:


as you can see we are using param attribute


Standard Action and Objects
as you can see in the previous examples, you can read string and integer attributes, however how can we read Objects attribute.

lets say we have a servlet and the servlet adds this attribute:



we added a person attribute, inside the person attribute we have a dog

now, if you want to get the dog name for example you can write this in JSP


however if you want to do it without scripting:


the code above will return the dog object not its name, and you cannot write "dog.name"

standard actions with no scripting is good for string and integer attribute. however in such a case you should use Expression Language



as you can see ${person.dog.name} which means person.getDog.getName().

EL dot (.) operator
the EL we saw with . operator works for objects and java.util.map.
for example when you write ${person.dog}

if person is a bean, this will be translated to person.getDog().
if person is a java.util.map, this will return person.getValue("dog") which means returns the value for the key "dog"

EL [] operator 
you can use [] with EL, for example ${person["dog"]}. however this could be used for multiple purposes

1- if person is a bean, it will be translated to person.getDog()
2- if person is a map, it will return the value for the key "dog"
3- if person is an array, and you write ${person[0]} it will return the first element
4- if person is a List, and you write ${person[0]} it will return also the first element

EL implicit objects
there are some implicit objects that you can use in your EL code
these objects are



for example you can get a request parameter like this


you can read header information

Use your function with EL
you can write your function and use it in EL
1- define a class with static method
2- define a Tag Library Description
3- import the TLD
4- use the function



Master Pages and Include

1- so as we mentioned before you can define a master page and include it in other pages,
2- the master page should be without <html><body> tags

you can include the page by

<%@ include file="Header.jsp" %>: this will behave like copying what you have in Header.jsp to the current page. (if the container is not new, it may not noticed the changes in Header.jsp and you have to restart the app, however we dont have this problem with Tomcat)

<jsp:include page="Header.jsp"/>: this actually will add dynamic code which will create a request to header.jsp each time ( alot of overhead ).

you can pass parameter to the included page like this



and use the attribute in the included page:

<strong> ${param.subTitle} </strong>


<jsp:forward> 
you can use <jsp:forward> to forward your request, for example if the user is not logged in do a forward



very important to know that when <jsp:forward> executes it clears the buffer, which means all the rendered stuff before <jsp:forward> will be cleared.


Chapter 9 Scriptless using JSTL (Java Standard Tag Library)



we will talk here about using the Tagging library,

c:out example:

imagine you want to output <b></b> as text, you should write

or you can write a function for that and start using it



however with the tag library you can write



c:foreach example:






c:if example:




c:choose example




c:set example:




c:remove example:




c:url example
you use c:url to encode the url so the sessionid will be added


Define an error Page
1- add a jsp file (e.g. errorPage.jsp) and add the follwoing:

2- now in any page you can reference this error page.



3- you can also apply this to all pages by adding this to the web.xml

this will catch all exceptions

you can also write:


c:catch

How to Understand a TLD file
when you get an TLD file from someone you should understand the follwoing things:



as you can see you have URI, tagName and Tag attriutes

as you can see also, we have <tag-class> which is the class that does all the job, in this case the class is foo.AdvisorTaghandler

and the class will be like this:



Chapter 10 Custom Tag Development


1- Before, we were using <jsp:include> and <c:import> to add reusable pages, however with <jsp:include> and <c:import> you should create request parameters in order to pass them.


2- we can do the same thing with  tags, the same jsp file (the one we want to reuse), we can change the extension from jsp to .tag. with tags you pass parameters as attributes


the figure above shows how you can create a tag


now in order to pass parameters you wirte

<myTags:Header subTitle="asdfasdf" />

and you read this value from the taf file like this

<strong>${subTitle}</strong>

3- as you remeber we add the attribute for tags in TLD, however tag files have special directive called attribute:


4- for complex tags, you can define them as a java class


5- SkipPageException, inside the tag you can throw SkipPageException, this exception will not render the rest of the page.

Other information about Tags are in the chapter, you can read it 


Chapter 11 Deploying your web app & Chapter 12  Web Security




you cannot access anything under Web-INF or Meta-INF directly


Servlet initialization 
servlet initialized when they are called you can change this behaviour like this




WEB Security
when we talk about security we are talking about
1- Authentication
2- Authorization
3- Confidentiality
4- Data Integrity

NOTE: In security we talk about REALM, simply it means where the authentication information are stored. for example in tomcat you can store the authentication information in tomcat-users.xml, tomcat will load this information to memeory. However it is better to implement this information in the deployment descriptor.

Authorization
to do it in tomcat-users.xml and in the deployment descriptor like this:


and you should set the Authentication Method in the DD

<login-config>
  <auth-method>BASIC</auth-method>
</login-config>

so as you can see the first thing you do is defining the roles in DD, now to assign these roles to a url we define a security-constraint:


as you can see we set a url-pattern and http-method and auth-contraint

of-course you can define multiple constraint, and if there is a conflict different roles will apply.

Programmatic Security
it is better to define security in xml, however you can do that in code


3 important functions when we talk about security:
1- isUserInRole
2-getUserPrincipal(): used in JEE
3- getRemoteUser(): is not used alot

Authentication
we have 4 types:

1- BASIC: uses HTTP specification, weak as there is  no encryption we just use base64, and it is an http standard so it is supported by all browsers
2- DIGEST: uses HTTP specificaiton, it is strong but not SSL, it is optional for browsers or the container to support it.
3- CLIENT-CERT: j2ee specification, uses a certificate to encrypt, it is strong
4- FORM: j2ee specification, weak as no encryption.

so in BASIC, DIGEST and CLIENT-CERT, we basically uses the browser to handle the Authentication, in FORM we are using our own form.

when see that the method is weak it means you should use HTTPs with this method.

Integrity and confidentiality
when we talk about integrity it means that the data must not changed along the way
when we talk about confidentiality, it means that the data must not be seen by anybody

you can set this value by





Permitted values

  • NONE - no special transport guarantees (this is the default if there is no user-data-constraint defined)
  • INTEGRAL - data must be sent in a way that guarantees it cannot be changed during transmission (ie: data is checksummed, SSL achieves this)
  • CONFIDENTIAL - data must be sent in a way that guarantees it canot be observed (or changed) during transmission (ie: data is encrypted, SSL achieves this)

so basically what tomcat does, if a request comes and it is not secure, it will send 301 redirect to https address so the browser can do the request again.




Chapter 13 Wrapper & Filters



Filters are managed by the container like servlets


you define a filter by implementing the Filter interface.

we use the chain.doFilter() to move to the next filter.

then you add the filter information in the DD


filters will be in the order appears in the DD

you can also specify if you want the filter to work in case of REQUEST of FORWARD ...

AFTER SERVLET FILTER
lets say you want to run a filter after the servlet is executed, you can add this code after chain.doFilter().


FILTER and SERVLET and RESPONSE
we were talking about the after servlet filter, lets say you want to compress the response, you cannot simply do that on the response object you have in the filter, because the stream will be written by the servlet, so inorder to do that you should wrap the response in a different response object, send it to the servlet, then compress it.

here is the filter code.



and you define the the new response class like this



Chapter 14 Enterprise Design Pattern


JNDI & RMI
with JNDI and RMI we solve 2 issues:
1- how to find or locate a remote object (JNDI)
2- how to call a method in a remote object (RMI).

so lets say you have an object and you want to make it available for remote clients, what you should do is creating a proxy for this object (a stub), register it in JNDI.
now, the client will do a search in JNDI and retrieve the Proxy (the stub), and deal with the proxy as it is the real object. The stub will handle all the underline communication.


Business Delegate Design Pattern


as you can see you have a business delegate for each business functionality, this business delegate contact JNDI to get the stub and do the call

as you can see we have alot of code duplication, all business delegate deal with JNDI, thats why we have a Service Locator pattern

Service Locator Pattern




as you can see we have an object, ServicLocator, which is responsible for all JNDI calls


Data Transfer Object Pattern

lets take a loot to a REMOTE MVC Structure where the model is on another Machine


1- as you can see, firstly you register in JNDI,
2- the business deligate call the service locator to return a stub.
3- the stub calls the remote method and return the result WHICH IN THIS CASE A CUSTOMER OBJECT, HOWEVER WE ARE RETURNING NOW A STUB TO THE CUSTOMER OBJECT.
4- add the Customer Stub to the Request
5- the view will read the Customer Stub
6- now, in the view for every single information in the Customer Stub, a remote call will be created.

THIS IS AN OVERHEAD,

Thats why we have something called Data Transfer Object, rather than returning a Customer Stub, we return a Customer POJO, we serialize this object and return it back, in that case we dont have to do a remote call every time.


and here is the big picture of
Business Tier Patterns



Improving the MVC Controller With Struts
basically the controller should do 3 things:

howerver, this is alot, the idea here is why dont we make the things Declarative (i.e. define it in XML file), we can for example put the validation information in xml file, then we can set the view and model information in XML file:

this is what Struts do, it makes the controller declaritive:


The Key Components in Struts are:

Summary of the patterns

















No comments:

Post a Comment