Anda di halaman 1dari 20

(/)

/ Integration Zone (/enterprise-


integration-training-tools-news)
Over a million developers have joined DZone. Sign In / Join
Spring
MVC Tiles 3 Integration Tutorial
(/users/292164/tousif.html) by Tousif Khan (/users/292164/tousif.html) Jul. 18, 14 Integration Zone (/enterprise-integration-
REFCARDZ (/REFCARDZ) GUIDES (/GUIDES) ZONES (/PORTALS) | MORE
training-tools-news)

Like (0) Comment (0) Save Tweet 47.95k Views

The Integration Zone is brought to you in partnership with Red Hat. (/go?
i=87830&u=https%3A%2F%2Fdzone.com%2Fasset%2Fdownload%2F26631) Use these flashcards (/go?
i=87830&u=https%3A%2F%2Fdzone.com%2Fasset%2Fdownload%2F26631) along with the popular open source integration
framework Apache Camel as an easy reference during the design and development of integration projects.

One of the areas in which Spring MVC has advance compares to other frameworks is in the separation of view
technologies. In this post, i will show how to integrate Apache Tiles 3 with Spring MVC. Apache Tiles is a free open-
source template engine for java web frameworks. Its based on Composite pattern and used to simplify the
development of user interfaces.

Create a spring configuration XML file which add bean definition for TilesConfigurar and TilesView.
1

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"

xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p"

xmlns:mvc="http://www.springframework.org/schema/mvc"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.2.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-3.2.xsd

10

http://www.springframework.org/schema/mvc

11

http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd

12

http://www.springframework.org/schema/tx
13

http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">

14

15

<context:annotation-config />

16

<context:component-scan base-package="org.techzoo.springtiles.controller" />

17

18

<mvc:annotation-driven />

19

<mvc:default-servlet-handler />

20

<mvc:resources mapping="/resources/**" location="/resources/" />

21

22

<bean id="viewResolver" class="org.springframework.web.servlet.view.tiles3.TilesViewResolver"/>

23

24

<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">

25

<property name="definitions">

26

<list>

27

<value>/WEB-INF/layouts/layouts.xml</value>

28

<value>/WEB-INF/layouts/views.xml</value>

29

</list>

30

</property>

31

</bean>

32

33

</beans>
Now create a tiles definition xml file which contains tiles template definitions. I have created two xml files, one for
tiles base template and another for tiles body definition but you can combine it in one.
1

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE tiles-definitions PUBLIC

"-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"

"http://tiles.apache.org/dtds/tiles-config_3_0.dtd">

<tiles-definitions>

<definition name="DefaultTemplate"

template="/WEB-INF/views/template/SiteTemplate.jsp">

<put-attribute name="title" value="Home" />

10

<put-attribute name="header" value="/WEB-INF/views/template/header.jsp" />

11

<put-attribute name="menu" value="/WEB-INF/views/template/menu.jsp" />

12

<put-attribute name="body" value="" />

13

<put-attribute name="footer" value="/WEB-INF/views/template/footer.jsp" />


<put-attribute name="footer" value="/WEB-INF/views/template/footer.jsp" />

14

</definition>

15

16

</tiles-definitions>

Create a template jsp which include the common pages (like header, footer, menu etc.). I have used Blueprint css
framework to create a grid for layout.
1

<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Spring MVC - Tiles Integration tutorial</title>

<link rel="stylesheet" href="resources/css/screen.css"

type="text/css" media="screen, projection"></link>

<link rel="stylesheet" href="resources/css/print.css"

type="text/css" media="print"></link>

10

<!--[if IE]>

11

<link rel="stylesheet" href="resources/css/ie.css"

12

type="text/css" media="screen, projection">

13

<![endif]-->
14

<style>

15

body{ margin-top:20px; margin-bottom:20px; background-color:#DFDFDF;}

16

</style>

17

</head>

18

<body>

19

<div class="container" style="border: #C1C1C1 solid 1px; border-radius:10px;">

20

<!-- Header -->

21

<tiles:insertAttribute name="header" />

22

<!-- Menu Page -->

23

<div class="span-5 border" style="height:400px;background-color:#FCFCFC;">

24

<tiles:insertAttribute name="menu" />

25

</div>

26

<!-- Body Page -->

27

<div class="span-19 last">

28

<tiles:insertAttribute name="body" />

29

</div>

30

<!-- Footer Page -->

31

<tiles:insertAttribute name="footer" />

32

</div>

33

</body>

34

</html>
Header.jsp
1

<div class="span-24">

<img src="resources/images/techzoo-header.png"

width="950" style="padding-top:10px;" />

</div>

Footer.jsp
1

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>

<ul style="list-style:none;line-height:28px;">

<li>

<spring:url value="/index" var="homeUrl" htmlEscape="true" />

<a href="${homeUrl}">Home</a>

</li>
8

<li>

10

<spring:url value="/viewPeson" var="personListUrl" htmlEscape="true" />

11

<a href="${personListUrl}">Person List</a>

12

</li>

13

14

</ul>

As you can see, In you main template jsp we have inserted body attribute but in tiles-def xml file that body attribute is
blank. This is because spring controller will render this portion using its view rendering mechanism.

Create a Controller which has two action (index and viewPeson) . The return value of every controller will be mapped
with each tiles definition which is associated with jsp to render as body in template.
1

ackage org.techzoo.springtiles.controller;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import org.springframework.stereotype.Controller;

import org.springframework.ui.Model;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMapping;

10

import org.springframework.web.servlet.ModelAndView;

11

import org.techzoo.springtiles.vo.Person;

12

13

@Controller

14

public class SpringTilesController {

15

16

@RequestMapping(value="index")

17

public String index() {

18

return "index";

19

20

21

@RequestMapping(value="viewPeson")

22

public ModelAndView viewPersons(Model model) {

23

Map<String, List<Person>> persons =

24

new HashMap<String, List<Person>>();

25

persons.put("persons", Person.createPersons());

26

return new ModelAndView("personList", persons);

27

28

29

}
A Person VO class just to show a list of person in personList.jsp.
1

ckage org.techzoo.springtiles.vo;

import java.util.ArrayList;

import java.util.List;

public class Person {

private String name, email;

private int age;

10

11

public Person(String name, String email, int age) {

12

this.name = name;

13

this.email = email;

14

this.age = age;

15

}
16

17

//getter, setters methods

18

19

@Override

20

public String toString()

21

22

return String.format(

23

"Person [name = %s, email = %s, age = %d]",

24

name, email, age);

25

26

27

public static List<Person> createPersons() {

28

List<Person> persons = new ArrayList<Person>();

29

persons.add(new Person("Tousif", "tousif@mail.com", 32));

30

persons.add(new Person("Asif", "asif@mail.com", 28));

31

persons.add(new Person("Ramiz", "ramiz@mail.com", 26));

32

persons.add(new Person("Rizwan", "rizwan@mail.com", 32));

33

persons.add(new Person("Amol", "amol@mail.com", 33));

34

persons.add(new Person("Ramdas", "ramdas@mail.com", 31));

35

return persons;

36

37

}
Your second tiles defination xml (views.xml) will looks similar to following. Both the tile defination index and
personList is extending DefaultTemplate.

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE tiles-definitions PUBLIC

"-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"

"http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
"http://tiles.apache.org/dtds/tiles-config_3_0.dtd">

<tiles-definitions>

<definition name="index" extends="DefaultTemplate">

<put-attribute name="body"

value="/WEB-INF/views/index.jsp" />

10

</definition>

11

12

<definition name="personList" extends="DefaultTemplate">

13

<put-attribute name="body"

14

value="/WEB-INF/views/personList.jsp" />

15

</definition>

16

17

</tiles-definitions>

index.jsp
1

<div style="margin:10px;">

<h3>SpringMVC - Tiles3 Integration tutorial</h3>

<p>By:- Tousif Khan</p>


4

</div>

personList.jsp
1

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<div style="margin: 10px;">

<h4>List of Persons</h4>

<table style="width: 600px" class="reference">

<tbody>

<tr>

<th>Sr. No.</th>

<th>Name</th>

<th>Age</th>

10

<th>Email</th>

11

</tr>

12

<c:forEach var="person" items="${requestScope.persons}"

13

varStatus="loopCounter">

14

<tr>

15

<td><c:out value="${loopCounter.count}" /></td>

16

<td><c:out value="${person.name}" /></td>

17

<td><c:out value="${person.email}" /></td>

18

<td><c:out value="${person.age}" /></td>

19

</tr>
20

</c:forEach>

21

</tbody>

22

</table>

23

</div>

Output:

The Integration Zone is brought to you in partnership with Red Hat. (/go?
i=87829&u=http%3A%2F%2Fwww.redhat.com%2Fen%2Fabout%2Fblog%2Fyour-integration-architecture-may-be-holding-you-
back-3-considerations-fixing-it%3Fsc_cid%3D701600000011i4LAAQ) Discover how your integration architecture may be
holding you back and 3 considerations for fixing it. (/go?
i=87829&u=http%3A%2F%2Fwww.redhat.com%2Fen%2Fabout%2Fblog%2Fyour-integration-architecture-may-be-holding-you-
back-3-considerations-fixing-it%3Fsc_cid%3D701600000011i4LAAQ)

Topics: JAVA, ENTERPRISE-INTEGRATION, SPRING MVC, SPRING, SPRING INTEGRATION

Published at DZone with permission of Tousif Khan , DZone MVB . (http://www.techzoo.org/spring-framework/spring-mvc-tiles-3-integration-tutorial.html)


Opinions expressed by DZone contributors are their own.
Get a Job, Container: A Serverless Workflow with Iron.io
(/users/1229985/fortyfivan.html) by Ivan Dwyer (/users/1229985/fortyfivan.html) Apr 05, 16 Integration Zone (/enterprise-integration-

training-tools-news)

Like (1) Comment (0) Save Tweet 1,622 Views

The Integration Zone is brought to you in partnership with 3scale (/go?


i=83830&u=http%3A%2F%2Fwww.3scale.net%2F%3Futm_campaign%3Ddzintegration%26utm_source%3Ddzoneint%26utm_content%3D
Take control of your APIs and get a free t-shirt when you complete the 3step Challenge (/go?
i=83830&u=http%3A%2F%2Fpages.3scale.net%2F3step-challenge-dzoneint.html).

My previous post, Distinguished Microservices: It's in the Behavior (https://dzone.com/articles/distinguished-


microservices-its-in-the-behavior), made a comparison between two types of microservices real-time requests (app-
centric) and background processes (job-centric). As a follow up, I wanted to take a deeper look at job-centric
microservices as they set the stage for a new development paradigm serverless computing.

Of course, this doesn't mean we're getting rid of the data center in any form or fashion it simply means that we're
entering a world where developers never have to think about provisioning or managing infrastructure resources to
power workloads at any scale. This is done by decoupling backend jobs as independent microservices that run
through an automated workflow when a predetermined event occurs. For the developer, it's a serverless experience.

Operational abstraction has been a key tenet of the cloud since day one, and the advancements across the entire stack
have continued to provide developers with the ammo to ship applications more effectively. What sets this serverless
pattern apart lies in the nature of the workloads. When we push an app to the cloud, we do so thinking about where it
will live and how it will run. This is because it has a known ip address and open port to accept incoming requests. On
the other hand, when we build a job, we do so only thinking about when it will execute. Even though there is compute
involved, it's completely outside of the development lifecycle, thus making the paradigm "serverless".

In our history of operating a job processing platform at Iron.io (http://www.iron.io), we've seen a wide range of
production-grade use cases across our diverse customer base. Some common examples that fit this model well
include:

Data/File Processing: Heavy lifting workloads such as crunching a large data set, encoding a multimedia file, or
filtering a stream of time series data points.
Backend Transactions: Offloading individual user or device actions to the background such as processing a
credit card or sending an email.
ETL Pipelines: Data extraction, processing, and delivery of data such as analyzing machine data for an IoT
system.

If we break this down, what we really have here is age old programming techniques, modernized with cloud native
technologies, wrapped up with a bow through new architectural patterns. While many of the associated concepts
have existed for some time, it's been the convergence of a few parallel evolutions to get the cloud ecosystem to where
it is today:

Microservices: Decoupling application components as individual services that perform a single responsibility
enables workload independence and portability.
Containers: Building, deploying and running code within a lightweight, containerized runtime ensures
consistency from development to production.
Event-Driven: Breaking apart from the traditional request/response model allows for workflows that can react to
dynamic environments automatically.
DevOps: Automated resource provisioning, configuration, and management brings it all together at the
infrastructure layer to abstract away everything but the API.
infrastructure layer to abstract away everything but the API.

The Software Development Lifecycle


To be effective, these patterns require a new approach to the development process. At the forefront is container
technologies such as Docker, which provide a myriad of benefits in terms of clarity and consistency. Iron.io was an
early adopter of Docker (https://www.iron.io/how-docker-helped-us-achieve-near/), and has since made it the primary
method (https://www.iron.io/microcontainers-tiny-portable-containers/) for working with the platform. To get started
with Iron.io follow along with our Quick Start (http://dev.iron.io/worker/getting_started/) guide.

As a basic example, we'll take the simple task of sending an email using the Sendgrid (http://www.sendgrid.com) API
and package it up as an Iron.io job. By taking the input as a payload and requiring the API key as a environment
variable, the job becomes portable enough to run through a serverless lifecycle independently.
1

require_relative 'bundle/bundler/setup'

require 'iron_worker'

require 'sendgrid-ruby'

client = SendGrid::Client.new(api_key: 'SENDGRID_APIKEY')

mail = SendGrid::Mail.new do |m|

m.to = IronWorker.payload["to"]

m.from = IronWorker.payload["from"]

10

m.subject = IronWorker.payload["subject"]

11

m.text = IronWorker.payload["text"]

12

end

13

14

res = client.send(mail)

15

puts res.code

16

puts res.body
Build: When the job is ready to build, specify the runtime by writing a Dockerfile
(https://docs.docker.com/engine/reference/builder/) that sets the executable, dependencies, and any additional
configuration needed for the process. For this Ruby example, we will also include a Gemfile and run the bundler
before building the Docker image to vendor the dependencies.
1

FROM iron/ruby

WORKDIR /app

ADD . /app

ENTRYPOINT ["ruby", "email.rb"]

$ docker run --rm -v "$PWD":/worker -w /worker iron/ruby:dev bundle install --standalone --clean

10

$ docker build -t fortyfivan/sendemail:0.0.1 .

Upload: The Docker image from the build is then uploaded to a registry where it can be pulled on demand. This can
be to a third party image repository such as Docker Hub (http://hub.docker.com), Quay.io (http://quay.io), or a private
registry. Once uploaded, the image is registered with an Iron.io project via the CLI.
1

$ docker push fortyfivan/sendemail:0.0.1

3
3

$ iron register fortyfivan/sendemail:0.0.1

The image on Docker Hub

Set: Once the image is uploaded, you can set the triggers to determine when the job should execute. Events come in
many forms from an API request, on a system change, within code, from a webhook url, on a schedule, or from a
notification. For this example, we'll use the Iron.io API to schedule the job to run daily at 8AM.

A Scheduled Job On Iron.io

Configure: Each job is an API endpoint in itself. It's important to configure the behavior so your jobs don't "go rogue".
With Iron.io, you can properly set access controls, resource allocation, concurrency allowances, error handling,
alerting, rate limiting, and more.
Job Configuration on Iron.io

Inspect: Background jobs can have a tendency to fall to the back of mind (no pun intended). While the underlying
system is maintenance-free, your code is still being executed, so you should have insight into its activity by monitoring
status and performance in real-time and after the fact.

The result of a Job on Iron.io

Operational Lifecycle
Even though the end-to-end operations are abstracted away from the developers, it's still worth knowing what's
happening behind the scenes. When an event triggers an Iron.io job, the following process takes place:

1. Queue Job: The job is posted to a message queue, which acts as the temporary store, holding the job in a persisted
state until completed. The message includes the job metadata, runtime parameters, and any payload data to be
passed into the job process itself.
2. Get Job: Worker nodes are continually monitoring queues for jobs. When capacity is available, the worker pops a
job off the queue and pulls the associated Docker image from its registry if a cached version of the image isn't
already on the machine.
3. Execute Process: The worker then runs the container with its given resource allocation. When the process is
complete, the container is gracefully stopped and the resources are freed up for another job.
4. Capture Results: The container's stdout/stderr logs are captured and delivered back to the system for dashboard
4. Capture Results: The container's stdout/stderr logs are captured and delivered back to the system for dashboard
display. If the process fails or timeouts, the job is placed back in the queue where it can be retried or canceled.

It's Not Quite NoOps


What this trend truly represents is the continued importance around developer empowerment, so that businesses can
keep pace with the ever-changing world around them. Serverless computing doesn't remove the need for
infrastructure or operations, but it does keep it out of mind. Fire away.

The Integration Zone is brought to you in partnership with 3scale (/go?


i=83831&u=http%3A%2F%2Fwww.3scale.net%2F%3Futm_campaign%3Ddzintegration%26utm_source%3Ddzoneint%26utm_content%3D
Learn how API providers have changed the way we think about integration in The Platform Vision of API Giants (/go?
i=83831&u=http%3A%2F%2Fpages.3scale.net%2Fplatform-vision-of-giants-dzp.html).

Topics: CONTAINERS, MICROSERVICES, BATCH PROCESSING, ETL

Anda mungkin juga menyukai