Web Application Frameworks (English)

Z FI WIKI
Přejít na: navigace, hledání


Templates and Web Applications

Web frameworks were established to facilitate the development of Java Web applications. They are an extension of the basic layer for handling the HTTP protocol Servlety. Usually such framework resolve problems typical of web applications, which are

  • Controlling the data flow within the application
  • Generating web pages from templates

These solutions may or may not be independent.

There are a set of tools designed to generate web pages:

that can be combined with different management frameworks

To control the data flow:

There are frameworks that provide solutions for both problems:

Template Generation

Combination of data and templates

Freemarker overview.png

The pages created dynamically in Web applications are typically formed by merging templates containing static text and symbols to insert the proper data at runtime. JSP and FreeMarker are using the same syntax for this purpose derived from JavaScript. The template looks like the following:

<html>
 <head>
  <title>${titul}</title>
 </head>
 <body>
 Jste ${uzivatel.jmeno} a máte na účtu č. ${uzivatel.ucet.cislo} celkem ${uzivatel.ucet.stav} Kč
 </body>
</html>

The advantage of JSP is that it is integrated in any servlet container. The advantage of FreeMarker is that the template can be used to generate not only web pages, but also e-mails or static files.

Data tags are simple data structures, using a combination of hash tables (associative arrays indexed strings),sequences (classical fields indexed numbers) and scalar values​​ (strings, integers, Boolean, temporal data). For the template above, the following data structure can be defined (JSON notation):

{
  "titul": "Stav účtu",
  "uzivatel": {
    "jmeno": "Pepa Novák",
    "ucet": {
      "cislo": "1234567/0100",
      "stav":  10000000
    } 
  }
}


In addition to adding data labels, it is still necessary to control structures for conditional branching, loops, escaping HTML characters and the like. JSP uses JSP tags, especially standardized tag library JSTL.

Example of a for loop in JSP/JSTL:

<c:forEach items="${uzivatel.deti} var="dite">
  ${dite.jmeno}
</c:forEach>

and in FreeMarker:

<#list uzivatel.deti as dite>
  ${dite.jmeno}
</#list>

Uniform appareance of a website

The usual requirement for a website is to have a uniform appearance, ie, header, footer, navigation menu, area with ads etc. and only change the parts that are required to change on every new loaded page.

Include

The simplest way to do this is to use a simple insertion of one template into another, ie a directive include.

In JSP we can use the @include command that inserts another JSP page at compile time:

 
<%@include file="hlavicka.jsp" %>
 
<!-- body of the website -->
 
<%@include file="paticka.jsp" %>

<jsp:include> is a JSP tag that inserts another JSP page or servlet at Run-time by calling getRequestDispatcher(stranka).include(request,response):

 
<jsp:include page="hlavicka.jsp"/>
 
<!-- body of the website -->
 
<jsp:include page="paticka.jsp"/>


When there is the necessity to perform complex changes, it may be necessary to edit the existing templates.

Tiles

There are better solutions. One of the pioneer solutions in this sense is the Tiles framework, which was originally a separate project, then gained popularity as part of the framework Apache Struts, and today is again independent, see Tiles 3.0.

With Tiles it is possible by using a special configuration file to define the basic structure that contains parts common to all sites with areas that can be designated for the changing content. The site is modelled by means of a main area ( called 'body').

Stripes Layout Tags

Main Article: Stripes Layout Tags

An even better solution is the Stripes framework, that does not require a special configuration file. Just create a JSP page as a page template file in a fixed location, such as / layout.jsp:

 
<%@ taglib prefix="f" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="s" uri="http://stripes.sourceforge.net/stripes.tld" %>
 
<s:layout-definition>
 <html>
 <head>
   <title><f:message key="${klicTitulkuStranky}"/></title>
   <link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/default.css"/>
 </head>
 <body>
  ... menu atd. ...
  <s:layout-component name="contents"/>
 </body>
</html>
</s:layout-definition>

and JSP paged can refer to this template:

 
<%@ taglib prefix="s" uri="http://stripes.sourceforge.net/stripes.tld" %>
<s:layout-render name="/layout.jsp" klicTitulkuStranky="seznam">
  <s:layout-component name="contents">
      ... content ...
  </s:layout-component>
</s:layout-render>


In essence mark <s:layout-render> calls the tag <s:layout-definition> that prints the output of your body and replaces the tag <s:layout-component> for the content of the respective areas in the calling Lines.

All attributes of the tag <s:layout-render> are passed to the template as attributes so that you can use them.


Localization i18n

Web applications should be able to communicate with its users in their own language, thus be internationalized. If you are using JSP, a quite sufficient solution is using the the JSTL library, with the support of the i18n standard libraries included in the JDK.

 
<%@ taglib prefix="f" uri="http://java.sun.com/jsp/jstl/fmt" %>
 
<f:setBundle basename="Texty" />
 
<f:message key="ted_je_prave" />: 
 
<f:formatDate value="${ted}" type="both" dateStyle="full" timeStyle="full" timeZone="${zona}" />

The ResourceBundle can be either defined at each page using the tag <f:setBundle>, or the setting can me made global for the entire application using the initialization parameter file WEB-INF/web.xml:

 
    <context-param>
        <param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
        <param-value>cz.muni.fi.pa165.ukazka.Texty</param-value>
    </context-param>

Control Flow in web applications

The users interact with the applications by clicking on the hyperlinks and referral forms. Applications must then address how to react, for example when a form is displayed again needs to care about visualizing eventual errors and redirect to the next page, and so on.

A usual requirement is that the information entered in the page stays in the page and the user has not to enter it over and over again. The data is also necessary to perform the data validation.

Framework addressing those problems provide an integrated solution.

MVC framework for building web applications

The idea of ​​MVC is that the functionality of the application has to be separated into a model while functionality of the user interface is to be represented in a View Controller. At least, this is the expected pattern of implementation, for example, using Apache Struts no one prevents us to write all the functionality of the application directly when implementing the actions. But such design goes against the principles of MVC and will be reflected in poor maintainability of the application.

The recommended procedure for making web applications is:

  • First create a Model, without a user interface, and test its functionality with unit tests
  • Choose a framework for creating Controller web applications (e.g. Stripes or Spring MVC)
  • If possible, choose a technology for creating View (like JSP + JSTL, or FreeMarker)
  • Create the user interface

ArchWebAplikace.PNG

Frameworks for building Web applications

We give an overview of frameworks for creating Web applications. They can be divided into two large families - frameworks aimed at processing HTTP requests and frameworks focused as visual components.

Frameworks for Java are dozens, see for example the list http://java-source.net/open-source/web-frameworks.

Web frameworks history.png


The visual components consist of site components, responding to events, like an application with a graphical interface comprised of graphical components (buttons, scrollbars, selection sheets, etc.) in response to events such as mouse movements, mouse clicks, pressing keys.

(Why the bias against JSF?)

In contrast, the frameworks focused on processing HTTP requests give us total control over the exact appearance of the site and all HTTP traffic, but are a little more challenging to develop with.

Frameworks for processing HTTP requests

In these frameworks, the HTTP request is mapped to Java code that processes the request, prepares data and call a system to render the page.

Mapping the Request to Java code

In Stripes the HTTP request is mapped to a public method that returns a Resolution in classes that implement the interface ActionBean.

The mapping is set using the annotation @UrlBinding, which may include with a special tag ${event} the name of the method and other tags {prom} for variables, or their respective setProm() method. On the call, the set methods are converted to normal URL parameters.

 
/* ukázka Stripes */
 
@UrlBinding("/seznam/{event}/{id}")
public class Seznam implements ActionBean {
 
    private ActionBeanContext ctx;
    public ActionBeanContext getContext() { return ctx; }
    public void setContext(ActionBeanContext ctx) { this.ctx = ctx; }
 
    @DefaultHandler 
    public Resolution zobrazVsechny() {
        this.seznam = ...;
        return new ForwardResolution("/seznam.jsp");
    }
 
    public Resolution smazat() {
        smazPolozku(id);
        return new RedirectResolution(this);
    }
 
 
    private List<Polozka> seznam;
 
    public List<Polozka> getSeznam() {
        return seznam;
    }
 
    private int id;
    public void setId(int id) {
        this.id = id;
    } 
}

In Spring the MVC HTTP request is mapped to the public methods of classes marked with a @Controller annotation.

The mapping is specified using the @RequestMapping annotation that can contain special marker {arg} for the name argument to be mapped with the annotation @PathVariable. Alternatively, it is possible to use the argument with the annotation @RequestParam for normal URL parameters.

The view to display is determined by the return value of type String.

 
/* ukázka Spring MVC */
 
@Controller
@RequestMapping("/seznam")
public class Seznam {
 
    @RequestMapping("/zobrazVsechny")
    public String zobrazVsechny(Model model) {
        List<Polozka> seznam = ...;
        model.addAttribute("seznam", seznam);
        return "seznam";
    }
 
    @RequestMapping("/smazat/{id}")
    public String smazat(@PathVariable int id) {
        smazPolozku(id);
        return "redirect:/seznam";
    }
 
}

There are still the HttpServletRequest and HttpServletResponse objects available, but because of unit testing it is recommended not to use them directly. However, if we want to do this in Stripes it is obtained from ActionBeanContext and in SpringMVC by using NativeWebRequest:

 
 /* Stripes */
 
 public Resolution neco() {
     String a = getContext().getRequest().getParameter("a");
     getContext().getResponse().addHeader("X-my-header","1");
     //...
 }
 
 /* Spring MVC */
 
 public String neco(NativeWebRequest request) {
     String a = request.getNativeRequest(HttpServletRequest.class).getParameter("a");
     request.getNativeResponse(HttpServletResponse.class).addHeader("X-my-header","1");
     //...
 }

Choosing the View

The View in Stripes is determined by the implementation of the Resolution, while in Spring MVC the method must select a logical name, which then the ViewResolver converts to the selected view.


Stripes built-in implementations of the Resolution:

In SpringMVC the method can return a simple string, and must provide an implementation ViewResolver mapping names to JSP pages:

 
    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setPrefix("/WEB-INF/views/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }

Or you can return different types of objects (see Supported method return types), that are treated specially (see Resolving views with the ViewResolver interface).

JSP Support

Both frameworks, Stripes and Spring MVC, provide a library of JSP tags to ease the implementation.

 
<%@ taglib prefix="stripes" uri="http://stripes.sourceforge.net/stripes.tld" %>
 
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<%@taglib uri="http://www.springframework.org/tags" prefix="spring" %>

Data Validation

Both frameworks, Stripes and Spring MVC, provide support for type conversion and validation of input data entered by the user. For example, to check whether the required parameter is the actual number or whether it is a string of a certain maximum length.

Spring MVC uses a rather complicated system of validating the business layer, see details 6. Validation, Data Binding, and Type Conversion.

In contrast, Stripes provides a simple validation of the presentation layer using annotations such as

 
    @ValidateNestedProperties(value = {
            @Validate(on = {"save"}, field = "surName", mask = User.SURNAME_MASK, required = true),
            @Validate(on = {"save"}, field = "givenName", mask = User.GIVENNAME_MASK, required = true),
            @Validate(on = {"save"}, field = "mail", converter = EmailTypeConverter.class, required = true),
    })
    private User user;

Frameworks based on visual components

Apache Wicket

Apache Wicket similar to Tapestry.

Tapestry

A popular framework focused on the visual component is Tapestry, and is the subject of a separate topic. It is worth noting that Tapestry was awarded a prize in 2006: Duke's Choice Award for innovation.

JSF

Java Server Faces is a technology promoted by Sun, and the latest version is integrated directly into JavaEE and the EL language. See JSF.

Portlets

This is a philosophically different approach to building applications where the entire web server is called a portal and is composed of independent applications generating the page. See Java Portlets.

Links