Apr 23, 2015

Java EE Notion

Enterprise Java Beans - Business layer

In J2EE, EJB  was best fit for placing the business logic (Session bean and to some extent Message driven bean). and in Java EE still EJB best fits there. 

EJB's are of two types - Session and Message-driven.
where session bean suits for creating boundary, session facade, or service facade. Message-driven beans (MDB) acts as listener to JMS Queue or Topic.
Message-driven beans are used frequently to handle requests in asynchrnous manner, but since now we can have asynchronous session bean methods, usage of message-driven beans  will be limited.

Since message-driven bean is asynchronous, some transaction attributes wont be applicable.

With time boundary will become complex -

But a boundary may be far more complex, it might be coordinating multiple components, calling backend services, sending message on queue, calling utilities, logging, etc., but a satteless session bean is still enough.  Generally the bounday will expose coarse grained (not fine granied) methods, and with time boundary will become bloated and complex.  Controls are added to make boundary leaner. I learned this pattern from book - "Real World Java EE Patterns" by Adam, that control should be a POJO and should reuse the transaction started by boundaries.

Anti-boundary
Gateway (I am not sure, if it should be called Gateway) pattern suggest direct interaction between presentation and persistence, without any indirection from boundaries.
UI should directly communicate with entities. Indeed I believe we can have entities which represent database resources and expose them as REST services and let UI consume those services.
Which I believe very simple and very sophisticated.

Boundary or Anti-boundary comes down to choice, like REST or SOAP. Some times we need boundaries and some times we want to presentation (or client) consume directly server resources. Indeed, if you ask me we need both. Developing a complete application using REST is also not easy, for example how you will implement fund transfer. But developing application with lot of complex boundaries is not feasible today and is definitely outdated even before completion.

An application can be developed using microservices and aggregators can be used over microservices to present business boundaries, which is the trend now.
Aggregator patterns like on below link -
http://blog.arungupta.me/microservice-design-patterns/

In Java EE, we need a server side Java class holding business logic, with container managed transaction, security authorization, etc. The developer concentrates on business logic, like for example the fund transfer. The developer has some basic assumptions that should be taken care by container: The fund transfer method should be transactional, and not every one is able to do fund transfer; these things should be managed by container. Session beans fit for writing logic of fund transfer; and let container manage transaction, secuity, pooling, creation, deletion, initalization, etc. 

Boundary design pattern and EJB as boundary - 
An online banking application has lot of business logic which can be encapsulated in several methods like fund transfer, account balance, account details, debit, credit, etc.  In a Java EE application or any enterprise application, we need to centralize business logic across business-tier components and services.  The access to business logic components has to be convenient, consistent, scalable, and maintainable. A dedicated remotely available transactional boundary is required.  The boundary exposes business methods, easy to consume business API, encapsulating business logic, and designed from domain perspective.  The boudary is not required to remember the client between several calls or maintain a session state for every client. Boundary should be stateless.  A stateless session bean with no interface is best suited as boundary. A remote interface can be provided if boundary will be used from another JVM.
No interface is required, bean can be injected into another components, and can be exposed as JAX-WS or JAX-RS endpoint.
EJB is just a POJO with @Stateless annotation. The annotation is enough to add default transactional boundaries and configurable security. Same EJB can be exposed to remote clients. Same EJB can be exposed as WebService with @WebService annotation. And Same EJB can be exposed to REST clients with @Path annotation. And this boundary is not required to implement any interface. 
The boundary is consumed by UI or client components, and every interaction is a business transaction (theoratically).  Transaction should be container managed and business methodsa should not explicitly deal with transactions.  By default transaction should be start and end with business method.  A stateless sesison bean (SSB) with container managed transaction (CMT) and default transaction attribute of REQUIRES_NEW is perfectly suitable for creating business boundary.

End users dont start transaction, presentation layer usually doesn't start transaction, even boundary methods dont invoke each other in same transaction, so REUIRES_NEW is best suited
transaction type for bounday. In EJB its default, and can be changed by setting the transaction attribute like below -
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public boolean fundTransfer(Transaction txn){ ..}

Servlets
Servlet
Servlet is Java class that acts as a server for web clients. Servlet can response to any kind of request but commonly used by web clients using request/response model.
Container manages the life cycle, requests, response, etc. of servlet.
Examples -
1. @WebServlet("/account")}
public class AccountServlet extends HttpServlet ... {
2.  @WebServlet(name="AccountServlet", urlPatterns={"/account", "/all"})
public class AccountServlet extends HttpServlet ... {
At least one url pattern must be declared.
A servlet is defined with @WebServlet annotation on a pojo and it must extend HttpServlet. If name is not provided, the fully qualified class name is the servlet name.

Container on receiving first request for a servelet, will load the servlet class, create instance of servlet class, calls the init method of servlet class, and invokes te service method passing request and response objects.
There onwards only service is called, but if servlet is to be destroyed then container calls destroy method of servlet class. That means we can override (optionally) init to perform any initialization and destroy to perform any cleanup.
Service method is any method that can handle client request and return response. service() method is part of GenericServlet class, which is extended by HttpServlet, which we will extend while writing our Servlet.
HttpServlet has one doXXX() method for each HTTP method: GET, POST, PUT, DELETE, and so on.
Container (Server) will call the doXXX() via service method when client sends XXX request, that is to say doGet will be called when client send GET request. We will never override service() method, instead override doXXX() method,
and mostly doGet() or doPost().
By default container will create only one instance of servlet per declaration.
If application is marked distributed, container may have one instance per JVM.
Container will instantiate multiple instancs of servlet per JVM, if servlet implements SingleThreadModel (deprecated interface).
Web container handles concurrent requests to the same servlet by concurrent execution of the service method on different threads,
unless Servlet implements SingleThreadModel where container should gaurantee only one request at a time to service method.
It is recommended to use Atomic instance variables ot synchronized blocks to avoid multithreading issues, but avoid SingleThreadModel and synchronized doGet() or doPost() methods.
Any required intialization parameters are passed using @WebInitParam.

ServletContext
ServletContext is the interface (it has got methods that) servlet uses to communicate with container. One context per web application per JVM.
"In the case of a web application marked "distributed" in its deployment descriptor, there will be one context instance for each virtual machine.
In this situation, the context cannot be used as a location to share global information (because the information won't be truly global). Use an external resource like a database instead." - Oracle docs.
ServeltContext can be used to share information between servlets. Like an object can be added as attribute to context, which can be retrieved in other servlet.
Servlets can share information like objects by maintaining them as atrributes in one scope objects: context (ServletContext), session (HttpSession), request (ServletRequest), page (JSP page).

Listeners
We can listen to Servlet lifecycle events and react to them by registering a listener class. Events like : context initialized/destroyed, attribute added/removed/replaced in context,
session creation/invalidation/activation/passivation/timeout, attribute added/removed/replaced to session, request recieved, attribute added/removed/replaced to request.

@WebServlet(
        name = "TransferServlet",
        description = "This class handles fund transfer",
        urlPatterns = "/ft"
        initParams =
         {
             @WebInitParam(name = "minBal", value = "0"),
             @WebInitParam(name = "maxLimit", value = "50000")
         }
)
public class TransferServlet extends HttpServlet {
private AtomicInteger counter; // thread safe counter, counts number of transfer
public void doGet(HttpServletRequest req, HttpServletResponse res) {
if(!(req.getParameter("amount") > Integer.parseInt(getInitParameter("maxLimit"))) {
 ....
}
}

Filter
A filter class can modify the header and/or content of request and response.
Multiple filters can be chained (by calling FilterChain.doFilter()), means filter will be callled in sequence before actually request reaches servlet or response reaches client.
Filter can add/modify/remove attribute to request, filter can change response, filter can perform logging like session log, filter can even block the request from reaching servlet (dont call doFilter()).
@WebFilter(
        urlPatterns = "/ft",
        initParams = @WebInitParam(name = "defaultCharge", value = "1"),
        description = "Filter to log and apply charges",
        dispatcherTypes = {DispatcherType.REQUEST, DispatcherType.FORWARD}    
)
public class TransferFilter implements Filter {
}
default dispatcher is REQUEST (to be used when request comes directly from client)

Asynchronous Servlet
Asynchronous Servlet was introduced in Servlet 3.0, and enhanced in Servlet 3.1 version as part of Java EE 7.
Idea is "Client sends request -> Container allocates thread (from pool) to handle request, and invokes servlet -> Servlet code calls request.startAsync and saves the AsynContext (like in list) -> Thread exits (or returns to pool) -> Connection is still open -> Some other thread uses saved AsyncContext and sends response (AsyncContext.getResponse()) and completes the process asyncContext.complete() -> Client receives the response".
So inside doGet or doPost, we will have code like below -
final AsyncContext asyncContext = request.startAsync(request, response);
asyncContext.setTimeout(10 * 60 * 1000);
list.add(asyncContext); // an option, otherwise an instance of Runnable (with AsyncContext) can be passed to a thread pool, so that another thread can handle sending response.
// Above code will be called by thread one, handling request
// Below code will be called by another thread sending response
asyncContext.getResponse().getWriter().println(htmlMessage); // an option
asyncContext.complete();

One of the new feature of Servlet 3.1 was support for Non-blocking IO (NIO).  Servlet 3.0 only supported traditional IO.
A typical usage is when we write code like below -
request.getInputStream() and read byte by byte, now if Input is blocked, then servlet is waiting. Similar situation can arise white writing OutputStream.
Below is the code which uses NIO
AsyncContext context = request.startAsync();
ServletInputStream input = request.getInputStream();
input.setReadListener(new MyReadListener(input, context));
where MyReadListener has callback methods -
onDataAvailable callback method is called whenever data can be read without blocking
onAllDataRead callback method is invoked data for the current request is completely read.
onError callback is invoked if there is an error processing the request.
Also Important is - The asynchronous behavior needs to be explicitly enabled on a servlet, i.e. add asynSupported attribute  on @WebServlet, like below -
@WebSerlet(urlPatterns="/xyzAsync", asyncSupported=)
MyAsyncServlet {
//...
}

Thread per request
Also note the HTTP 1.1 where connection can be kept alive and can be reused for multiple requests.
So at bigger level, we can assume one thread per connection.
Major improvement came with NIO library where threads can be pooled, thread will be attached to connection when request is processed, and when connection is idle thread can be recycled & connection will be placed in a channel for selectors.
So we assume its Thread per request.

Servlet Protocol Upgrade
It is mentioned in section 14.42 of  RFC 2616(url) -
"The Upgrade general-header allows the client to specify what additional communication protocols it supports and would like to use if the server finds it appropriate to switch protocols."
So, if Servlet supports any other protocol (or allows upgrade of HTTP 1.1 to some other), then client can set the "upgrade" request header with desire to upgrade to mentioned protocol.
One example is RFC 6455(url) for Web Sockets. A nice example implementation of upgrade is -
https://weblogs.java.net/blog/swchan2/archive/2013/05/07/protocol-upgrade-servlet-31-example
In the example servlet's doPost method, below line checks the header value from client
if ("isbn".equals(req.getHeader("Upgrade"))); // assume the new protocol is isbn
if above line returns true, that means client supports isbn protocol and would prefer isbn over HTTP, if at all server finds its appropriate to switch.
At server end we have to provide an protocol handler, like in the example is "ISBNHttpUpgradeHandler".
The servlet container supports upgrade, but doesn't have any knowledge about upgraded protocol. The protocol processing & handling is provided in HttpUpgradeHandler, like for example ISBNHttpUpgradeHandler.
public class ISBNHttpUpgradeHandler implements HttpUpgradeHandler {..}
HttpUpgradeHandler has init() and destroy() methods, which needs to implemented. init() will handle the connection like reading input data, and destroy will be called when client is disconnected.

Servlet & MVC
In the MVC 2 architecture, the controller is Servlet.
Initial J2EE designs used to have JSP for view, Servlet as controller, and Java Bean as model. Many servlets, JSP's, and beans, where beans can be EJB's too.
A simple J2EE architecture can be like -
http://www.javaguru.biz/struts1-framework-architecture/
Later frameworks came with a big controller servlet. Servlet is for routing, and controllers are normal Java class. Servlet routes the request to appropriate controller.
Like in Struts 1 architecture -
http://www.javaguru.biz/struts1-framework-architecture/
http://www.dzone.com/tutorials/java/struts/struts-tutorial/struts-mvc-architecture-tutorial.html
In Struts, there was only one controller servlet : ActionServlet. URLs were mapped to handlers(actions), and mapping was mentioned in struts-config.xml.
ActionServlet routes requests to handlers (actions) and ActionForm (like JavaBean) is used to persist data between requests.
Important is all those servlet objects: request, response, session, etc. are available to action.
Struts lost somewhere, but Spring MVC is still one of the most popular framework for building web applications.
Spring also uses a central controller "DispatcherServlet" which receives the request, dispatches task to HandlerMapping to select appropriate controller, and task of executing the business logic of controller to HandlerAdaptor.
Controller executes business logic, sets Model, and returns view name. DispatcherServlet dispatches the taks to resolve View based on view name to ViewHandler.
View renders the model data and returns response.
Similar is the FacesServlet. FacesServlet is the central controller, and engine of JSF application.


I draw this picture to remind myself that we can optional Filters before Servlets, we can have Listeners registered for different Events, and Servlets share ServletContext

JSF

I am not using JSF and even dont recommend, but I am Java EE fan, so I was going through the JSF. Below is the short tutorial over JSF, very helpful to those who are new and to those who have forgotten.

JSF is framework to develop web applications.
Framework has everything like
server side UI components, renderers, and tag library which makes easy to develop(or as easy as generate) pages.
page flows
APIs to manage state, events, validation, conversion, navigation, internalization, etc.
Extension capability
Framework enables creating pages by drag drop, interactive web pages and presentation oriented web application.

With recent development and advancement of javascript frameworks, we have microservices architecture or service oriented web applictaion.
A service oriented web application enable exposing resources (like DB entries) as REST services, and another application which is presentation oriented(developed in HTML, Javascript fraemwork)
will consume the services.

A web application developed using JSF has presentation layer along with server side code. So, its presentation oriented.Easiest way I found to get started with JSF is using Netbeans, where you create a Database and get rest code generated using below wizards -
"Entity Classes from Database" and then "JSF Pages from Entity Classes".
The wizard will generate the pages along with CRUD capabilities, i.e. pages for creating new resource(entry in table) in database, updating resource in database, deleting resource in database, etc.

Developing a web application involves creating a component which will handle client requests and redirect them to appropriate handler(/controller) and send response back,
along with managing page navigation. AND we need a mark up language which will process and present the text. The markup language has code(tags) for formattting (layout and style), and xHTML is one such markup language (like HTML).

A bare minimum JSF application will include an xhtml page (or two), POJO with @Named annotation (or @ManagedBean), and web.xml. Yes thats's it.Assume index.html which also happends to be the welcome-file, with submit button and gets redirected to another xhtml, like response.xhtml. welcome-file is the landing page of a web application, and specified in web.xml, like below -

    index.xhtml
User fills some text boxes in index.html, like name, same name field is mapped to name field in POJO, and name value is displayed in response.xhtml.
response.xhtml has code Hello, #{hello.name}, to display name, where name is field in POJO Hello.java (so by default hello.name).
index.html has following code for input to enter name-
                         title="My name is: "
                         value="#{hello.name}"
                         required="true"
                         requiredMessage="Error: A name is required."
                         maxlength="25" />
where h is prefix for the JSF HTML tag library whose URI is http://java.sun.com/jsf/html, so h:inputText is an example tag of that tag library.
Similarly we have other tag libraries like core (c:), and sophisticated facelets with URI http://java.sun.com/jsf/facelets and prefix of ui.
@Named annotation gaurantees default EL naming (i.e. we were able to refer name field using #{hello.name}).  Also we can apply @RequestScoped on POJO Hello, so that pojo persists for siingle request only, which was suitable for our case, where use entered a value in one xhtml, value got set in POJO and was displayed in next xhtml. We can combine @Named and @RequestScoped to create a new annotation, like @Model (such an annotation is called stereotypes).
The next xhtml to display can be mentioned in the index.xhtml, liek below -

           

and so, response.xhtml is displayed next.
The next xhml can be configured in faces-config.xml : where we can define the flow, a flow of pages, something similar to Spwing Web flow or ADF flow.

POJO which also happens to be managed bean is exactly a CDI bean. A POJO with @Named anootation is CDI bean which acts like backing bean for JSF (we dont need @ManagedBean now).
Optionally(ane mostly) CDI bean will be communicating with entities (POJO with @Entity). And flow will be defined in faces-flow.xml, so a typical design will be like below -


Though its not much of concern, but its good to know how the request is handled, or life cycle


IN JSF application we can have classes like: We can have entity (POJO), a class to manage perstence for this POJO, and a controller clas that will act as managed bean for JSF.

Rest I will suggest you sample application can be ready using Netbeans, and then you can start with -
handling page navigation, layout of pages, custom components, etc.

Java EE Architecture today
Share:

No comments

Post a Comment

Comment

© Shift, ShEkUP, Shape, and Surprise | All rights reserved.
Blogger Template Crafted by pipdig