• Anasayfa
  • Eğitimler
    • JavaScript Eğitimi
    • Angular 2 Eğitimi
    • React.js Eğitimi
    • Java 8 Eğitimi
    • Java EE 7 Eğitimi
    • Spring Framework Eğitimi
    • Git Eğitimi
  • Online Eğitimler
    • Online React.js Eğitimi
    • Online Angular 2 Eğitimi
    • Online Spring Boot Eğitimi
  • Referanslar
  • Hakkında
  • İletişim
KodEdu
  • Anasayfa
  • Eğitimler
    • JavaScript Eğitimi
    • Angular 2 Eğitimi
    • React.js Eğitimi
    • Java 8 Eğitimi
    • Java EE 7 Eğitimi
    • Spring Framework Eğitimi
    • Git Eğitimi
  • Online Eğitimler
    • Online React.js Eğitimi
    • Online Angular 2 Eğitimi
    • Online Spring Boot Eğitimi
  • Referanslar
  • Hakkında
  • İletişim

First Look at JSR 371, MVC 1.0 Spesification and Ozark RI

  • Posted by Kodedu
  • Categories backend, Genel, Uncategorized, Yazılar, Yazılım
  • Date 20 Şubat 2015

The newly JSR 371 MVC 1.0 spesification is coming. This spesification will bring us an alternative way to apply MVC to Java EE ecosystem in action-based manner.

MVC 1.0 spesification grows up under Java EE 8 umbrella and it’s RI (Reference Implementation) is Ozark.

In this blog, i want to introduce to you current state of MVC 1.0 and Ozark, and want to give some examples.

There is a conversation about MVC 1.0 will be based on Servlet or Jax-RS ? In both way, there is advantages and disadvantages. If you follow up Servlet, you may develop and shape spec and ri apis in detail. If you follow up JaX-RS, you may use of its current features. For now, it seems Jax-RS way will win, but not certain.

If you already have practice with any action-based MVC frameworks (e.g. Spring MVC), you can easly adapt on MVC 1.0 and Ozark. I think following picture clears how MVC 1.0 and Ozark works.

ozark mvc.png
Figure 1. How MVC 1.0 Works
View
View side can be any template kind. For example, JSP, Facelets, Freemarker, Handlerbars, Thymeleaf and so on. MVC 1.0 supports two view type: JSP and Facelts by default. But, you can use any View technology by developing your own ViewEngine.
Models
Models is an basically HashMap. You put your programming data to it. After that, ViewEngine will merge it with View.
MVC 1.0 Models Interface
public interface Models extends Map<String, Object>, Iterable<String> {

}
ViewEngine
Now, you have a View technology and Models data object. View document has some placeholder to demonstrate Model datas. For example;
JSP placeholder
<div>${person.name}</div>
Facelets placeholder
<h:outputLabel value="#{person.name}"/>
Handlebars placeholder
<div>{{person.name}}</div>
Thymeleaf placeholder
<div th:text="${person.name}"></div>

Those are all basically does same thing. If you provide a Person object has a name property to those views, you can have a rendered view.

ViewEngine’s task is to merge Data and View. By default, Ozark contains two ViewEngine classes. JspViewEngine and FaceletsViewEngine. For example we can look at inside of ViewEngine and JspViewEngine.

ViewEngine Interface
public interface ViewEngine {
    boolean supports(String view);  (1)
    void processView(ViewEngineContext context) throws ViewEngineException;  (2)
}
1 ViewEngine will support or not.
2 Render phase.
@Priority(1000)
public class JspViewEngine implements ViewEngine {

    private static final String VIEW_BASE = "/WEB-INF/"; (1)

    @Inject
    private ServletContext servletContext;

    public boolean supports(String view) {
        return view.endsWith("jsp") || view.endsWith("jspx"); (2)
    }

    public void processView(ViewEngineContext context) throws ViewEngineException {
        Models models = context.getModels(); (3)
        HttpServletRequest request = context.getRequest();
        HttpServletResponse response = context.getResponse();
        Iterator rd = models.iterator();

        while(rd.hasNext()) {
            String e = (String)rd.next();
            request.setAttribute(e, models.get(e)); (4)
        }

        RequestDispatcher rd1 = this.servletContext.getRequestDispatcher("/WEB-INF/" + context.getView());

        try {
            rd1.forward(request, response);  (5)
        } catch (IOException | ServletException var7) {
            throw new ViewEngineException(var7);
        }
    }
}
1 JSP files location
2 This views supports files has jsp or jspx extension
3 Access Models object
4 Set each model values to current Request attribute list
5 Forward JSP view with their model attributes.

Developing an ViewEngine is easy as you see above.

Controller
We can then combine View, Models and ViewEngine parts with JaxRS Controller. There is a new @javax.mvc.Controller annotation that marks a JaxRS resource class/method to produce a view document.
@Path("/")
@Controller (1)
public class HomeController {

    @Inject (2)
    private Models models;

    @GET
    @Path("/home1")
    public String home1() {
        return "/index.jsp"; (3)
    }

    @GET
    @Path("/home2")
    @View("/index.xhtml") (4)
    public void home2() {}

    @GET
    @Path("/home3")
    public Viewable home3() {
        return new Viewable("index.hbs"); (5)
    }

    @GET
    @Path("/home4")
    public Viewable home4() {
        return new Viewable("index.html",HandlebarsViewEngine.class); (6)
    }

    @GET
    @Path("/home5")
    public Response home5() {
        return Response
               .ok()
               .entity(new Viewable("index.thyme"))
               .build(); (7)
    }

}
1 Marks this class as a MVC 1.0 Controller. All under methods will render a View document.
2 We can access a RequestScoped Models implementation via CDI (Context and Dependency Injection)
3 Renders index.jsp with current Models object.
4 Renders index.xhtml with current Models object.
5 Renders index.hbs with current Models object.
6 Renders index.html with current Models object and provided HandlebarsViewEngine class.
7 Renders index.thyme with current Models object.

As you see above, there are many ways to declare which view document will be rendered. We did’t put any model value to View yet. Let’s do it.

Imagine we have a Person class like below.

public class Person {

    private String name;
    private String surname;
    private Integer age;

    // getters, setters and constructors.
}

We can visualize this kind of objects with the following Handlebars View.

person.hbs
<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>Person View</title>
</head>
<body>
    <div>{{person.name}}</div>
    <div>{{person.surname}}</div>
    <div>{{person.age}}</div>
</body>
</html>

And we need to combine them;

@GET
@Path("/")
public class PersonController {

    @Inject
    private Models models;

    @Path("/person")
    @Controller
    public String person() {

        Person person =new Person(); (1)
        person.setName("Hüseyin");
        person.setSurname("Akdoğan");
        person.setAge(35);

        models.put("person",person); (2)

        return "person.hbs"; (3)
    }

}
1 Create a new model object
2 Put it to global Models Map
3 Return view document name

And then, we need write a ViewEngine implementation for Handlebars template system.

@Priority(Priorities.DEFAULT)
public class HandlebarsViewEngine implements ViewEngine {

    @Inject
    private ServletContext servletContext;

    @Override
    public boolean supports(String view) {
        return view.endsWith(".hbs"); (1)
    }

    @Override
    public void processView(ViewEngineContext context) throws ViewEngineException {

        Models models = context.getModels();
        String viewName = context.getView();
        if (!viewName.startsWith("/"))
            viewName = "/" + viewName;

        try (PrintWriter writer = context.getResponse().getWriter();
             InputStream rs = servletContext.getResourceAsStream(viewName);
             InputStreamReader in = new InputStreamReader(rs, "UTF-8");
             BufferedReader buf= new BufferedReader(in);) {

            String viewContent = buf.lines().collect(Collectors.joining()); (2)

            Handlebars handlebars = new Handlebars();
            Template template = handlebars.compileInline(viewContent); (3)
            template.apply(models, writer); (4)

        } catch (IOException e) {
            throw new ViewEngineException(e);
        }

    }
}
1 Template name should end with .hbs extension
2 Read content of current view
3 Compile Handlebars template
4 Write rendered content to PrintWriter of HttpServletResponse

Now, project structure of this project seems like below.

project structure.png
Figure 2. Project Structure

You can deploy this app to Glassfish v4.1 to test. After deployment follow the http://localhost:8080/mvc/app/person URL and see rendered Handlebars view.

result.png

You can download the Source Code here.

Hope to see you again.

  • Share:
author avatar
Kodedu

Previous post

Java 8 LongAdder vs AtomicLong
20 Şubat 2015

Next post

Java ServiceLoader Nedir? SPI (Service Provider Interface) Nasıl Yazılır?
23 Şubat 2015

You may also like

api-logo
Swagger Nedir? Neden kullanılır?
10 Ekim, 2018
spring-cli-logo
Spring CLI ile Spring Boot Projeleri Hazırlamak
21 Ağustos, 2017
eureka_architecture
Spring Cloud Netflix ve Eureka Service Discovery
3 Temmuz, 2017

    1 Comment

Leave A Reply Cevabı iptal et

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

E-posta listesine kayıt olun!






Gözde yazılar

Netmera ile Röportaj
18Haz2012
Spring CLI ile Spring Boot Projeleri Hazırlamak
21Ağu2017
Performans, Yük ve Stres Testleri
26Ağu2012
CDI – @Produces, @New ve @PostConstruct Notasyonları
22Tem2013

Son Yazılar

  • Java’da Record’lar 27 Ocak 2020
  • Swagger Nedir? Neden kullanılır? 10 Ekim 2018
  • Spring CLI ile Spring Boot Projeleri Hazırlamak 21 Ağustos 2017
  • Spring Cloud Netflix ve Eureka Service Discovery 3 Temmuz 2017
  • Online React.js Eğitimi ardından (15-25 Mayıs 2017) 31 Mayıs 2017

Son Yorumlar

  • Coupling ve Cohesion Kavramları Nedir? için Hilal
  • Naïve Bayes Sınıflandırma Algoritması için Rahman Usta
  • Naïve Bayes Sınıflandırma Algoritması için Mete
  • YAML Nedir? Neden YAML Kullanmalıyız? için kara
  • JWT (JSON Web Tokens) Nedir? Ne işe yarar? için Furkan

Get Java Software

Arşivler

Bizi takip edin

React.js Eğitimi Başlıyor
11-22 Eylül, 2017
Eğitmen
Rahman Usta
İletişim

merhaba@kodedu.com

  • Hakkında
  • Gizlilik Politikası
  • İletişim
  • Referanslar
Kodedu Bilişim Danışmanlık
Cemil Meriç mah. Çelebi sok.
No:16/3 Ümraniye/İSTANBUL
Tel: 0850 885 38 65
Alemdağ V.D.: 8960484815

KODEDU © Tüm hakları saklıdır.