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
<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
17
18
<mvc:annotation-driven />
19
<mvc:default-servlet-handler />
20
21
22
23
24
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
"http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
<tiles-definitions>
<definition name="DefaultTemplate"
template="/WEB-INF/views/template/SiteTemplate.jsp">
10
11
12
13
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
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
type="text/css" media="print"></link>
10
<!--[if IE]>
11
12
13
<![endif]-->
14
<style>
15
16
</style>
17
</head>
18
<body>
19
20
21
22
23
24
25
</div>
26
27
28
29
</div>
30
31
32
</div>
33
</body>
34
</html>
Header.jsp
1
<div class="span-24">
<img src="resources/images/techzoo-header.png"
</div>
Footer.jsp
1
<ul style="list-style:none;line-height:28px;">
<li>
<a href="${homeUrl}">Home</a>
</li>
8
<li>
10
11
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
15
16
@RequestMapping(value="index")
17
18
return "index";
19
20
21
@RequestMapping(value="viewPeson")
22
23
24
25
persons.put("persons", Person.createPersons());
26
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;
10
11
12
this.name = name;
13
this.email = email;
14
this.age = age;
15
}
16
17
18
19
@Override
20
21
22
return String.format(
23
24
25
26
27
28
29
30
31
32
33
34
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.
"http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
"http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
<tiles-definitions>
<put-attribute name="body"
value="/WEB-INF/views/index.jsp" />
10
</definition>
11
12
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;">
</div>
personList.jsp
1
<h4>List of Persons</h4>
<tbody>
<tr>
<th>Sr. No.</th>
<th>Name</th>
<th>Age</th>
10
<th>Email</th>
11
</tr>
12
13
varStatus="loopCounter">
14
<tr>
15
16
17
18
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)
training-tools-news)
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.
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'
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
$ docker run --rm -v "$PWD":/worker -w /worker iron/ruby:dev bundle install --standalone --clean
10
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
3
3
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.
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.
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.