I read about ControllerServlet usage in affablebean tutorial for Java EE 6, by Oracle.
It ends up with a servlet handling a lot of different URL requests, like this:
#WebServlet(name = "ControllerServlet",
loadOnStartup = 1,
urlPatterns = {
"/category",
"/addToCart",
"/viewCart",
"/updateCart",
"/checkout",
"/purchase",
"/chooseLanguage"})
public class ControllerServlet extends HttpServlet {
#EJB
private CategoryFacade categoryFacade;
#EJB
private OrderManager orderManager;
#Override
public void init() throws ServletException {
// store category list in servlet context
getServletContext().setAttribute("categories", categoryFacade.findAll());
}
/**
* Handles the HTTP <code>GET</code> method.
* #param request servlet request
* #param response servlet response
* #throws ServletException if a servlet-specific error occurs
* #throws IOException if an I/O error occurs
*/
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String userPath = request.getServletPath();
// if category page is requested
if (userPath.equals("/category")) {
// get categoryId from request
String categoryId = request.getQueryString();
if (categoryId != null) {
// get selected category
Category selectedCategory = categoryFacade.find(Short.parseShort(categoryId));
// place selected category in request scope
request.setAttribute("selectedCategory", selectedCategory);
// get all products for selected category
Collection<Product> categoryProducts = selectedCategory.getProductCollection();
// place category products in request scope
request.setAttribute("categoryProducts", categoryProducts);
}
// if cart page is requested
} else if (userPath.equals("/viewCart")) {
// TODO: Implement cart page request
userPath = "/cart";
// if checkout page is requested
} else if (userPath.equals("/checkout")) {
// TODO: Implement checkout page request
// if user switches language
} else if (userPath.equals("/chooseLanguage")) {
// TODO: Implement language request
}
// use RequestDispatcher to forward request internally
String url = "/WEB-INF/view" + userPath + ".jsp";
try {
System.out.println("Redirecting to : "+url);
request.getRequestDispatcher(url).forward(request, response);
} catch (Exception ex) {
ex.printStackTrace();
}
}
I wonder if it is good practice for a Java EE project? I'm thinking about adopting Java EE as the framework for a project, which involves a small team of programmers. I think this ControllerServlet is encouraging them to put a lot of business logic inside. The class is expected to grow terribly long with a lot of if/else if... in future.
So what would be your recommendation about such a ControllerServlet to work in a big project?
You are correct in thinking that the controller servlet will quickly grow to be unmanageable if you are handling many different actions. You'll wind up with a huge set of if or case statements following the naive approach you sketched out.
A typical solution would be a front controller pattern that dispatches url mappings to other code that actually handles the requests. There are many relatively straight forward solutions to do this (someone mentioned the command pattern) and it's a key part of most web frameworks. I would probably not write my own front controller in 2016. What with the ease of standing up annotation based servlets, I would consider structuring a very simple application (like a microservice) around a single action per servlet; handling as many of the http methods as necessary: DELETE, PUT, GET...
However, you are also probably going to need additional features such as templating, reusable UI components, fancy url parameter handling, object to json mapping (and the reverse), sub resource mapping, content negotiation, authorization, etc. To the extent that you do, consider one of the numerous java EE technologies that you can apply to the problem (JAX-RS, JSF, JSR 371) and even more numerous implementations of each.
If you exposing an api I'd look at a JAX-RS implementation like jersey For a certain kind of application that might suffice: perhaps a single page web application communicating with the back end via ajax calls.You could serve your static content with nginx for apache. For full-blown frameworks you can choose a component based approach that implements the JSF standard or an action based one that implements the mvc1 (JSR 371) spec. You can read about the differences here: https://blogs.oracle.com/theaquarium/entry/why_another_mvc_framework_in
You mentioned choosing between JSF and spring mvc, The former is component based, the latter is action based. There is currently only one implementation of JSR 371, Ozark, the reference. If this distinction is important for your choice then you might be hampered by the lack of JSR 371 implementations. But it really does seem to me that the action based approach is the future.
Related
I am trying to make an API with Jetty Server, and I have this simple GET request:
#GET
public String helloWorld(){
return "Hello world";
}
In order to make a POST request, I assume that one must save the input to the Jetty server. I have tried to research for quite a while, but found nothing.
I imagine something like this:
#POST
public void Save(String stringToSave) {
// Save to DB?
}
You could likely google this but let me give you a quick overview. A Servlet is a chunk of code that is normally run during an HTTP action - GET, POST, etc. It is the original technology of the JavaEE world, having been released in the late 1990's.
A simple Java servlet, using modern annotations, would look something like:
#WebServlet(name = "SampleServlet", urlPatterns = "/sampleServlet")
public class SampleServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// called when an HTTP POST is sent
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// called when an HTTP GET is sent
}
}
The important parts to note are that the class extends HttpServlet and that you have to write code to pull data out of the request and push it into the response. This isn't bad to do but it does have to be done.
JAX-RS is a newer standard, aimed simplifying the creation of REST services. It too is a chunk of code that runs during an HTTP interaction.
A simple example of this would be:
#Path("/sampleService")
public class SampleService{
#Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
#Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
#POST
#Path("/v1/hello")
public Response sayHello( SomeObject someobject ) {
The code here is both simpler and a bit more complex. The use of annotations helps determine the path that the service exists on a URL (in this case /sampleService/v1/hello), the HTTP method, and the Content-Type for both the request and response. Additionally, if the SomeObject object is defined correctly, the JAX-RS framework will automatically deserialize the incoming JSON or XML payload into an object for you.
The Response object contains the HTTP response code (perhaps a teapot) and a response body. In this example, the body will be automatically serialized back to the requestor in a way that matches the Accept header of the HTTP request (i.e., JSON for an application/json Accept header and XML for application/xml).
Note that while not directly related the JAX-RS framework takes advantage of the Servlet framework. Indeed in JAX-RS you can access the HttpServletRequest and HttpServletResponse object in your methods.
Which way is "better"? In general I would recommend using JAX-RS where possible as it is the newer standard and is a bit easier to implement. However, if you do any work in the JavaEE world you're very likely to run into Servlet code so it's important to understand it too.
Note that both Servlets and JAX-RS require an application server of some sort. Jetty is one of those. Another very common one is Tomcat. The application server sets up the environment for your code and listens for incoming HTTP messages. When it gets one it looks to see if it knows how to handle the URL and routes to the appropriate place. In the servlet world the server routes solely on the URL. In the JAX-RS world the server routes on the URL and, if specified by the #Consumes annotation, the HTTP Content-Type header too.
There is much more but let's start there and see if it answers what you're after.
I am capturing URLs requested for my website. I need to see what all pages were requested from my website.
To achieve this I created a basic filter, and started logging page requests from there.
Now, this filter catches all the requests specific to a page.
For e.g. abc.com/page1, abc.com/resources/myjs.js, etc.
My problem is that for each page request, subsequent resources(js,css) are requested too. I want to capture only the relevant requests.
Right now, I check for patterns like /resources to ignore such requests, but I am looking for a more clean approach.
Also, will interceptors be more useful here?
I have seen filter patterns as well. But those are not useful, since I would have to create patterns for my filter.
If you want to capture the urls accessed from your website, you can configure spring boot to generate access logs in following way until you don't want more advance information:
server.tomcat.accesslog.directory=/logs/ #absolute directory path for log files\
server.tomcat.accesslog.enabled=false #Enable access log.
server.tomcat.accesslog.pattern=any_pattern # log string format pattern for access logs.
To perform any operation based on any request pattern, you can go ahead with filters.
I'm using filters for such requirements in following way:
public class CustomFilter extends OncePerRequestFilter{
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
String url = request.getRequestURI();
if (url.startsWith("/resources/")) {
//your business logic
}
filterChain.doFilter(request,response);
}
}
I'm making a Java Web Application but I'm newbie in Java.
I have a Servlet (/locatemodules) that try to find other servlets in the server (/modules/*), currently the servlet find the name of the other servlets (/modules/logout, /modules/invoice, etc), but I need to get some properties and call methods to the discovered servlets, the properties and methods are the same in all servlets.
Calling like: discoveredServlet.getMenuItem();
getMenuItem returns some values, menuName, menuUrl, sideMenu[], sideUrl[], etc... to make a menu item in the web application dinamically, the discovered servlets has the post and get for when is called on the main menu.
I'm find Inter Servlet Communication articles, but unfourtunally doesn't work with API 2.2 and later.
How can get a solution like this?
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class Loaded extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
res.setContentType("text/plain");
PrintWriter out = res.getWriter();
ServletContext context = getServletContext();
Enumeration names = context.getServletNames();
while (names.hasMoreElements()) {
String name = (String)names.nextElement();
Servlet servlet = context.getServlet(name);
out.println("Servlet name: " + name);
out.println("Servlet class: " + servlet.getClass().getName());
out.println("Servlet info: " + servlet.getServletInfo());
out.println();
}
}
}
Servlets are the classes that are supposed to accept requests on servers and respond them.
As you are making an HTTPServlet so it is supposed to accept an http request via http methods like get and post (so you get methods doGet() and doPost() in servlets), and then servlet processes the request and sends the http response.
If you want to communicate between servers then you should set some attributes using setAttribute() method and then redirect (using response.sendRedirect()) or forward your request to another servlet and use getAttribute() method to receive values.
Servlets are not meant to be used like normal classes, that you make objects of servlet class and call its methods.
As a design principle, Servlets should only be used to receive requests from the container, invoke classes that contain business logic, and redirect to a JSP that shows the response (MVC pattern). All the business logic should be on clases that are decoupled from the HTTP protocol.
So, I think the best thing you could do, is to remove these menu related methods from your servlets, put them on POJOs, and invoke this POJOs from your servlets.
Also, remember that normally, Servlets are Singletons.
Real situation is like this: Java web server (Weblogic) recieves a request from user for which it has to send a ZIP archive in response. Archive has to be dynamically generated from some files user asked for and one HTML report generated by the server itself. I would like to reuse JSF servlets the server already uses in other cases to generate this report. So, basically, what I use is:
HttpURLConnection self = new URL ("http://me.myself.com/report.jsf?...").openConnection ();
String report_html = fetchHtmlFromConnection (self);
and then create the requested ZIP, including the generated HTML in it.
The question is, can I somehow avoid making an internal HTTP request (to report.jsf) in this scenario? That involves basically pointless (since application just "talks" to itself anyway) roundtrips through operating system, HTTPD (which might be on a different machine), etc.
I am not very familiar with JSF, but from what I understand of them you can use a technic that is also applicable to JSP pages:
Create your own HttpServletResponseWrapper (a class used by the container that lets you modify the response)
Use it to override the default Writer (that writes the rendered page to the output) and provide one that writes the output to a String or a temporary file that will feed the compressing code.
There is a nice and simple tutorial that shows you how to do that:
http://blog.valotas.com/2011/09/get-output-of-jsp-or-servlet-response.html
Then
As hinted by gyan, get a ServletRequestDispatcher from your servlet that will let you invoke the rendering of the JSF
Forward the servlet call in order to provide your own HttpServletResponseWrapper
Use your HttpServletResponseWrapper to get the rendered HTML and feed it to the zipping code.
So the zipping Servlet would be like:
TempFileRespWrapper respWrapper = new TempFileRespWrapper();
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher( "/report.jsf");
dispatcher.forward(request, respWrapper);
File f = respWrapper.getOutputPath();
addFileToZip(f);
You should have a business service layer so that a "generateReport" service could be used inside multiple presentation views (even the "zip file" one).
You could do this in standard J2EE way via EJBs or through any custom framework that let you specify injectable business services (e.g. spring).
I think the main problem here is that you can generate the report only through the client interface (http). That makes it an isolated service, not available to other parts of the application. Basically you need a refactoring.
Do not code business inside JSFs or similar. (by the way, try not using jsf at all :D )
BUSINESS LAYER PRESENTATION
generateReportService---|---jsf-HtmlReport
\__|___
| \
someOtherContentService-|----jsf-Zip
Think about request dispatcher strategy, where request/response object would be sent to the report servlet from the entry servlet. In turn report servlet would generate the report and control can be sent to next servlet, which completes the rest of zip and send process.
For constructing a RequestDispatcher object, you can use either the ServletRequest.getRequestDispatcher() method or the ServletContext.getRequestDispatcher() method.
RequestDispatcher dispatcher=getServletContext().getRequestDispatcher( "/report.jsf" );
dispatcher.forward( request, response );
The next servlet set mime type as 'application/zip' and write the zip binary to browser. The user's browser would handle the content in the form of download depending on the browser settings.
Make sure that your web server is configured to cache (generated) html and you will not have to worry about it. First request to full or partial URL will generate a call to jsf generator and later it will be fetched from web server cache.
Yes, there will be a little overhead involved
(your source -> we server -> generator page or cache)
But it is going to be easier in the end.
Tested Solution!
This solution actually get ideas already posted here (specially from #gyan).
Write a Servlet to zip
(you could use an filter for that too. For example, suppose that you have a ZipFilter. You could map the filter for all *.zip and chain that filter with a URLRewrite filter for respective .jsf URL).
public class ZipServlet
extends HttpServlet {
#Override
public void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException,
IOException {
ZipEntry zipEntry = new ZipEntry("helloWorld.html");
ZipHttpServletResponseWrapper respWrapper = new ZipHttpServletResponseWrapper(response, zipEntry);
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/helloWorld.jsf");
dispatcher.forward(request, respWrapper);
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "inline; filename=output.zip;");
response.flushBuffer();
respWrapper.getOutputStream().close();
}
}
NOTE : Yes, you should use RequestDispatcher
ZipHttpServletResponseWrapper
There's no much to say about that. From Java 7, you can use a native Class to create zip files properly. Using Decorator pattern with ZipOutputStream on top of response.getOutputStream() should be recommended way.
Remember that HttpServletResponseWrapper is a decorator. You should not use that if you don't want to reuse the target "servlet" output directly (you could use an stunt HttpServletResponse rather than use HttpServletResponseWrapper).
public class ZipHttpServletResponseWrapper
extends HttpServletResponseWrapper {
private ZipEntry entry;
private ZipServletOutputStreamWrapper streamWrapper;
private ZipOutputStream outputStream;
private PrintWriter printWriter;
public ZipHttpServletResponseWrapper(HttpServletResponse response, ZipEntry entry) {
super(response);
this.entry = entry;
}
#Override
public ServletOutputStream getOutputStream() throws IOException {
if (streamWrapper == null) {
outputStream = new ZipOutputStream(this.getResponse().getOutputStream());
outputStream.putNextEntry(entry);
streamWrapper = new ZipServletOutputStreamWrapper(outputStream);
}
return streamWrapper;
}
#Override
public PrintWriter getWriter() throws IOException {
if (printWriter == null) {
printWriter = new PrintWriter(getOutputStream());
}
return printWriter;
}
private class ZipServletOutputStreamWrapper
extends ServletOutputStream {
private ZipOutputStream outputStream;
public ZipServletOutputStreamWrapper(ZipOutputStream outputStream) {
this.outputStream = outputStream;
}
#Override
public void close() throws IOException {
outputStream.closeEntry();
outputStream.finish();
}
#Override
public void write(int b) throws IOException {
outputStream.write(b);
}
}
}
Now, the secret: mapping wisely!
Some important parts of JSF could use Filter chain (for example, myfaces from Apache use some extensions to provide some JSF components). In this case, you should specify in these filters digest FORWARD and REQUEST
<filter-mapping>
<filter-name>extensionsFilter</filter-name>
<url-pattern>*.jsf</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
I have a general question about using Servlet and JDBC.
For instance, I have a class called MyDatabaseManager, which provides functions
public boolean updateUser(User user) {...}
public boolean deleteUser(User user) {...}
public boolean inserUser(User user){...}
, these functions will access and manipulate the Database.
My question is on the Servlet implementation. I am using three Servlets (UpdateUserServlet,InsertUserServlet and DeleteUserServlet) at the moment and each Servlet calls the MyDatabaseManager instance (only one instance here, using Singleton pattern) function. (For example, UpdateUserServlet calls MyDatabaseManager.updateUser ...).
I think this is the most straightforward way of using Servlet and Database. But I am not sure if this is the correct way of doing it. For example, how is this implemented in the industry world.
People don't really use servlets directly nowadays, they use frameworks that allow you to simplify your work, but if you really want to use servlets, you can make all actions in a single one, using the other methods, doPut, doDelete and even creating your own methods. Here's a sample of how you would do it:
public abstract class BaseServlet extends HttpServlet {
#Override
protected void service(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
String method = request.getParameter("_method");
if ("form".equals(method)) {
this.doForm(request, response);
} else {
if ("delete".equals(method)) {
this.doDelete(request, response);
} else {
super.service(request, response);
}
}
}
protected void doForm(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
throw new UnsupportedOperationException();
}
}
As you can see, this Servlet uses a special field _method on forms to decide what special method to call, if the _method is not available it's going to use the usual service method and is going to call doGet or doPost.
And here's how an implementation for this servlet would look like:
public class UsersServlet extends BaseServlet {
private UsersRepository cadastro = new UsersRepository();
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
req.setAttribute("usuarios", cadastro.list());
req.getRequestDispatcher("/usuarios/listar.jsp").forward(req, resp);
}
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
User usuario = this.getUser(req);
usuario.setNome(req.getParameter("nome"));
usuario.setEmail(req.getParameter("email"));
usuario.setSenha(req.getParameter("senha"));
this.cadastro.persist(usuario);
resp.sendRedirect(req.getContextPath() + "/usuarios");
}
protected User getUser(HttpServletRequest req) {
User usuario;
if (req.getParameter("id") == null) {
usuario = new Usuario();
} else {
Long id = new Long(req.getParameter("id"));
usuario = this.cadastro.search(id);
}
return usuario;
}
#Override
protected void doDelete(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
User usuario = this.getUser(req);
this.cadastro.remover(usuario);
resp.sendRedirect(req.getContextPath() + "/usuarios");
}
#Override
protected void doForm(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
User usuario = this.getUser(request);
request.setAttribute("usuario", usuario);
request.getRequestDispatcher("/usuarios/form.jsp").forward(request,
response);
}
}
This way you can make it all in a single servlet.
Difficult to answer because there are hundreds of design patterns out there! I know a good one about Database management is called DAO (data access objects). I use this one a lot. I advice you to take a look.
Don't get me wrong, a Singleton to hold your Manager is a good idea. Pretty much that's what I usually do too. However, usually I have a DAOFactorySingleton which pretty much have the responsibility to generate all classes DAO in my app and this factory is good because I can have some DataSource rules that this factory just poll from somewhere and inject in my DAO! So, pretty much, each DAO doesn't have to care about things like JDBC connection!
Follow 2 links to explain more about DAO!
http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html
http://community.jboss.org/wiki/GenericDataAccessObjects
The second one is to use with hibernate! you can read it and is not mandatory using just with hibernate. I really like that second one, more complex though.
This is surely a matter of design choice, you can adopt a framework like Spring, Struts etc.. which make this much easier. Alternatively if you want to use the classic servlet request/response pattern, I will suggest creating a parent servlet which intercepts request and passes it on to the right method to perform the request.
Additionally you have a choice to various ORM solutions like Hibernate, JPA etc.. which you can use to handle your database access operations. Yet if you choose to stick to the classic JDBC calls, you can use Filters and Handlers to decide which calls to provide wrap database connection and operation against.
Singleton on the Database class sounds good, especially as it seems to contain update/delete/insert code.
If you're using Connection Pools, make sure you Singleton the DataSourceFactory.
Many in the industry use ORM + Dependency Injection framework + transaction manager + database pooling libraries, for example Hibernate (ORM) + Spring DI (Dependency Injection) + Spring transaction manager (transaction manager) + Apache DBCP (DB connection pooling).
Sometimes when the use of ORM cannot be justified (e.g. very simple DB schema, ORM performance overhead is prohibitive due to the nature of the app. etc.), developers might use raw JDBC. Many would still use dependency injection and DB connection pooling.
It is very rare that the use of dependency injection or DB connection pooling cannot be justified. I.e., unless it is a very rare, special app., developers in the industry do use dependency injection framework and DB connection pooling.
In this case the state that needs to be managed is managed by the DB connection pooling framework, so you should not have to worry about state management or thread safety (as long as you don't share anything between different threads yourself and follow the API of the DB connection pool framework). I.e., you won't need a singleton. If you implement your own DB connection pool, then using a singleton would make sense.
If a developer doesn't want to use any framework (e.g. creating a very simple tool), then many would just open a connection every time (for each thread). In this case, you again don't need to manage any state so you won't need a singleton.
In the industry world, we are all for simplicity. For example, for user interaction from browser, to server, to a persistence storage (database), we follow these approaches.
An MVC pattern, first and foremost. This would allow us to totally not write a Servlet for each user interaction from browser to server. What this allows us to do is to do the following:
Allow the controller to handle user request and link it to our user action (our model). This model allows us to write business logic to respond to user data.
In today's Java World, Frameworks exists that meets our MVC requirements. The one that comes out the Java box is JSF (JavaServer Faces).
For backend, we definitely use databases, but we are clever too and use ORM (Object Relational Mapping) to model our real-world problem into an Object model and how to best persist (store) these object models. Some usesERM (Entity-Relational Modelling) to design a semantic data model.
In the middle, the business logic, we add a service (as the business logic layer) doesn't want to care about where to read/write data, as long as they can see the data it wants. For this, a Service layer is added that facilitates this. In essence we have this effect.
public class ActionServlet extends HttpServlet {
//Action registration
public void init() {
ActionMapping mapping = .....; //some instatiation
mapping.setAction("/userRegistration", UserRegistrationAction.class);
//Save it in Application Scope
getServletContext().setAttribute("actionConfig", mapping);
}
private void doAction(HttpServletRequest request, HttpServletResponse response) throws Exception {
String path = request.getPathInfo();
Action action = ((ActionMapping)getServletContext().getAttribute("actionConfig")).getAction(path);
if (action == null) {
throw new Exception("No action of '" + path + "' found.");
}
action.execute(request, response);
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws Exception {
doAction(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws Exception {
doAction(request, response);
}
}
public abstract class Action {
public abstract void execute(HttpServletRequest request, HttpServletResponse response) throws Exception;
protected void dispatch(HttpServletRequest request, String path) {
RequestDispatcher dispatcher = request.getRequestDispatcher(path);
dispatcher.forward(request, response);
}
}
public class UserRegistrationAction extends Action {
public void execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
//Business Logic goes here...
//Call DAO,
UserRegistrationDAO dao = ; //Some DAO instantation
User user = createUserFromForm(request);
dao.save(user);
dispatch(request, "success");
}
}
As for persistence, Java 5 & higher comes with JPA. You can use any form of ORM that you want, depending on your project scope. There's Hibernate (which also supports JPA) or if you want to, write your own DAO.
One more thing, all these processes are tedious to glue together. Fortunately, we have frameworks that helps us make our beautiful example above much easier. Frameworks like JBoss Seam does this and it fully uses Java specifications. For now, go for the simple design models and MVC (for learning purposes). As you get accustomed to the architecture, use frameworks.