Začátkem roku 2014 proběhl průzkum, ve kterém se komunita měla vyjádřit k tomu, co by se mělo stát součástí Java EE 8. Více než 60% respondentů odpovědělo, že Java EE by mělo podrorovat vedle JSF i jinou formu MVC pro webové aplikace [1].
Následně započaly práce na JSR-371 nazvaném MVC: Model-View-Controller API [2]. A právě na nové MVC API se v tomto článku podíváme.

K čemu to je

Můžete namítnout, že v JEE už jeden MVC framework pro webové aplikace máme: JSF. Autoři vysvětlují, že se jedná o trochu jiné MVC.
JSF je zaměřeno na vytváření komponent, které jsou využívány IoC frameworkem. Nové MVC API ponechává vývojářům větší kontrolu, neboť aplikační kód funguje na úrovni HTTP požadavků a odpovědí - prostě tak, jak to známe ze Spring MVC.
Pro podrobnější vysvětlení viz [3].

Začínáme psát kód

Vydání Java EE 8 je plánováno až na první pololetí roku 2017, ale my si můžeme nové API vyzkoušet již nyní. Práce na referenční implementaci jsou totiž v plném proudu a i když do finální verze specifikace jistě dojde ke změnám, základní principy zůstanou zachovány.
Zmíněná implementace nese název Ozark a je ke stažení zde: [4]. Pokud používáte Gradle, stačí přidat do build.gradle

1
compile group:'org.glassfish.ozark', name: 'ozark', version: '1.0.0-m02'

a můžeme začít vyvíjet. Pro spuštění potřebujeme samozřejmě vhodný JEE server. Autoři Ozarku testují své dílo s GlassFish 4.1 Nightly Sept 15, 2015, takže my použijeme totéž [6].

Controller

Autoři specifikace MVC API nezačínali na zelené louce a nepokoušeli se znovu vynalézat kolo. Specifikace využívá CDI a v podstatě pouze rozšiřuje existující specifikaci JAX-RS. Pokud se podíváme na typický controller pro operace CRUD, je to jasně vidět:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
@Controller @Path("projects")
public class ProjectController {
@Inject
Models models;
@Inject
ProjectRepository projectRepository;
@GET
public String list() {
models.put("projects", projectRepository.findAll());
return "projects.jsp";
}
@Path("/new") @GET
public String showCreate() {
return "editProject.jsp";
}
@Path("/new") @POST
public String create(@BeanParam Project project) {
projectRepository.save(project);
return "redirect:projects";
}
@Path("/{id}") @GET
public String get(@PathParam("id") Integer id) {
models.put("project", projectRepository.get(id));
return "editProject.jsp";
}
@Path("/{id}") @POST
public String update(@BeanParam Project project) {
projectRepository.save(project);
return "redirect:projects";
}
@Path("/{id}/remove") @GET
public String delete(@PathParam("id") Integer id) {
projectRepository.delete(id);
return "redirect:projects";
}
}

Většina anotací v controlleru je převzatá z JAX-RS:

Model je do controlleru injectován pomocí CDI. Takže jedinými novinkami jsou

  • anotace Controller, která oznamuje, že třída je MVC controllerem
  • rozhraní Models, což je pouze mapa, kterou controller naplní hodnotami. Tyto hodnoty jsou potom k dispozici ve view
  • návratová hodnota typu String, která identifikuje view, které bude použito pro renderování modelu.

Zdrojové kody celé demo aplikace včetně view najdete zde: [6]

Model a view

Controller má dvě možnosti, jak předat model do view:

  1. Pomocí mapy “Models”, jak je to popsáno výše.
  2. Naplněním pojmenovaného (@Named) beanu, který je potom do view injectován pomocí CDI. Implementace MVC nemusí tuto možnost podporovat, je pouze doporučená.

Na view není nic zvláštního. Implementace musí podporovat JSP a Facelety, další technologie (například Thymeleaf) budou volitelné.
View pro metodu list() z našeho controlleru může vypadat například takto:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Projects</title>
</head>
<body>
<h1>Projects</h1>
<ul>
<c:forEach items="${projects}" var="project">
<li><a href="projects/${project.id}">${project.id} - ${project.name}</a></li>
</c:forEach>
</ul>
<a href="projects/new">Create</a>
</body>
</html>

Srovnání se Spring MVC

Jestliže znáte Spring MVC, nové JEE MVC API vás ničím nepřekvapí. Následující obrázek hovoří za vše:

Závěr

Nové MVC je něco, co ve standardním JEE chybělo. Sympatická je snaha maximálně využít existující specifikace (především JAX-RS) a stavět na nich.
Uvidíme, jak se nové API rozšíří, až se objeví první servery, které budou implementaci JSR-371 obsahovat.

Odkazy

Comments