Download - Spring and Web Content Management
![Page 1: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/1.jpg)
© 2013 SpringOne 2GX. All rights reserved.
Spring & WebContent Management
Tobias Mattsson & Daniel LippMagnolia International
![Page 2: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/2.jpg)
2
![Page 3: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/3.jpg)
3
![Page 4: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/4.jpg)
4
![Page 5: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/5.jpg)
Sr. Software Engineer, MagnoliaLead developer of Magnolia’s Spring integration
Spring Framework user since 2005
Tobias Mattsson
5
![Page 6: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/6.jpg)
Daniel LippSr. Software Engineer, Magnolia
17 years of experience as software architect and Java developerGrateful to Spring for inspiring improvements to JEE 6
![Page 7: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/7.jpg)
®
7
![Page 8: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/8.jpg)
8
![Page 9: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/9.jpg)
@magnolia_cms#magnolia_cms
9
![Page 10: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/10.jpg)
SpringSpring MVC
Code, beautiful codeDependency Injection
IntegrationsBusiness logic
10
![Page 11: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/11.jpg)
CMSSecurityMulti-lingualUser interfaceImage manipulationContent versioning
11
![Page 12: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/12.jpg)
CMSSecurityMulti-lingualUser interfaceImage manipulationContent versioning
SpringSpring MVC
Code, beautiful codeDependency Injection
IntegrationsBusiness logic
12
![Page 13: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/13.jpg)
USES IFRAMES
LIKE IT'S 1999 13
![Page 14: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/14.jpg)
Magnolia + Spring = Blossom 14
![Page 15: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/15.jpg)
@Template
15
or, "How Blossom is Built"
![Page 16: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/16.jpg)
TEMPLATEREQUEST CONTENT
CMS
16
![Page 17: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/17.jpg)
TEMPLATEREQUEST CONTENT
CMS + Blossom
17
CONTROLLER
MODEL
VIEW
![Page 18: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/18.jpg)
Page Template
@Controller
@Template(id="myModule:pages/main", title="Main")public class MainTemplate {
@RequestMapping("/main")
public String render(ModelMap model) {
return "pages/main";
}
}
18
![Page 19: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/19.jpg)
PAGES CONTAIN 0:n AREAS
19
PAGE
![Page 20: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/20.jpg)
PAGES CONTAIN 0:n AREAS
19
PAGE
AREA
AREA
AREA
![Page 21: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/21.jpg)
PAGES CONTAIN 0:n AREAS
19
PAGE
AREA
AREA
AREA
AREAS HAVE 0:n COMPONENTSCOMPONENT
COMPONENTEtiam porta sem malesuada magna mollis euismod. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit.
COMPONENTEtiam porta sem malesuada magna mollis euismod. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed posuere consectetur est at lobortis.
COMPONENT
![Page 22: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/22.jpg)
Area Template
@Controller
@Template(id="myModule:pages/main",title="Main Template")
public class MainTemplate {
@Controller
@Area("main") public static class MainArea {
@RequestMapping("/main/mainArea")
public String render() {
return "areas/main";
}
...
20
![Page 23: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/23.jpg)
Component Template
@Controller
@Template(id="myModule:components/shoppingCart", title="Shopping Cart")@TemplateDescription("Shopping cart")
public class ShoppingCartComponent {
@RequestMapping("/shoppingCart")
public String handleRequest() {
...
return "components/shoppingCart";
}
...
21
![Page 24: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/24.jpg)
Views 22
![Page 25: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/25.jpg)
Rendering an Area
FreeMarker[@cms.area name="main" /]
JSP<cms:area name="main" />
23
![Page 26: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/26.jpg)
Rendering Components in an Area
FreeMarker[#list components as component] [@cms.component content=component /][/#list]
JSP<c:forEach items="${components}" var="component"> <cms:component content="${component}" /></c:forEach>
24
![Page 27: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/27.jpg)
About Magnolia CMS100% Java/J2EE compliantBest of breed open technology stack, including:
JSR-283 / JCR 2.0Vaadin / GWTServlet APIHTML5
Highly Customizable
25
![Page 28: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/28.jpg)
Java Content Repository
26
“… defines an abstract model and a Java API for data storage and related services commonly used by content-oriented applications.” – JSR-283
![Page 29: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/29.jpg)
Magnolia
JCR API
Persistence Manager
Jackrabbit Hierarchical content repository
In memoryDatabaseFile system
or or
27
![Page 30: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/30.jpg)
Why JCR?
28
Hierarchical
Event Notification(Observation)
Role-basedsecurity
Locking
Fine-grained contentand large binaries
Full-textSearch
StructuredQueries
ReferentialIntegrity
TransactionalSchema-less or Strongly-typed
Versioning
![Page 31: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/31.jpg)
29
Dialogs
![Page 32: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/32.jpg)
30
GWT with server-side stateComponent-based UICross-browser compatibility (via GWT)Rich component libraryFast development pace
![Page 33: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/33.jpg)
Fluent Builder-style API
@TabFactory("Content")public void contentTab(UiConfig cfg, TabBuilder tab) {
tab.fields( cfg.fields.text("heading").label("Heading"), cfg.fields.richText("body").label("Text body"), cfg.fields.websiteLink("categoryLink").label("Link"), cfg.fields.basicUpload("image").label("Image"), cfg.fields.checkbox("inlineImage").label("Inline Image") );}
31
![Page 34: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/34.jpg)
Page Template with Dialog
@Controller
@Template(title="Article", id="myModule:pages/article")public class ArticleTemplate {
@TabFactory("Content") public void contentTab(UiConfig cfg, TabBuilder tab) {
tab.fields(cfg.fields.text("title").label("Title")); }
}
32
![Page 35: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/35.jpg)
Page Template with Dialog
@Controller
@Template(title="Article", id="myModule:pages/article")public class ArticleTemplate {
@TabFactory("Content") public void contentTab(UiConfig cfg, TabBuilder tab) {
tab.fields(cfg.fields.text("title").label("Title")); }
} <title>${content.title}</title><!-- In the view -->
32
![Page 36: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/36.jpg)
@Controller@Template(title="Article", id="myModule:pages/article")public class ArticleTemplate {
@Area("main") @Controller public static class MainArea {
@TabFactory("Content") public void contentTab(UiConfig cfg, TabBuilder tab) {
tab.fields(
cfg.fields.text("heading").label("Heading"), cfg.fields.text("border").label("Border width") );
Area Template with Dialog 33
![Page 37: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/37.jpg)
@Controller@Template(title="Article", id="myModule:pages/article")public class ArticleTemplate {
@Area("main") @Controller public static class MainArea {
@TabFactory("Content") public void contentTab(UiConfig cfg, TabBuilder tab) {
tab.fields(
cfg.fields.text("heading").label("Heading"), cfg.fields.text("border").label("Border width") );
Area Template with Dialog 33
![Page 38: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/38.jpg)
@Controller@Template(title="Article", id="myModule:pages/article")public class ArticleTemplate {
@Area("main") @Controller public static class MainArea {
@TabFactory("Content") public void contentTab(UiConfig cfg, TabBuilder tab) {
tab.fields(
cfg.fields.text("heading").label("Heading"), cfg.fields.text("border").label("Border width") );
Area Template with Dialog 33
<div id="main" style="border:${content.border}px solid #000"> <h2>${content.heading}</h2> <c:forEach items="${components}" var="component"> <cms:component content="${component}" /> </c:forEach></div> <!-- In the view -->
![Page 39: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/39.jpg)
Component Template with Dialog
@Controller
@Template(title="Text", id="myModule:components/text")
public class TextComponent {
@RequestMapping("/text")
public String render() {
return "components/text";
}
@TabFactory("Content")
public void contentTab(UiConfig cfg, TabBuilder tab) {
tab.fields(
cfg.fields.text("heading").label("Heading"), cfg.fields.richText("body").label("Text body")
34
![Page 40: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/40.jpg)
Component Template with Dialog
@Controller
@Template(title="Text", id="myModule:components/text")
public class TextComponent {
@RequestMapping("/text")
public String render() {
return "components/text";
}
@TabFactory("Content")
public void contentTab(UiConfig cfg, TabBuilder tab) {
tab.fields(
cfg.fields.text("heading").label("Heading"), cfg.fields.richText("body").label("Text body")
34
<h1>${content.heading}</h1><p>${cmsfn:decode(content).body}</p><!-- In the view -->
![Page 41: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/41.jpg)
YouTube Video Component
@Controller@Template(title="YouTube Video", id="myModule:components/youtube")@TemplateDescription("Embed a YouTube video")
public class YoutubeComponent {
@RequestMapping("/youtube") public String render(Node node, ModelMap model) throws RepositoryException { model.put("videoId", node.getProperty("videoId").getString()); return "components/youtube"; }
@TabFactory("Content") public void contentTab(UiConfig cfg, TabBuilder tab) { tab.fields( cfg.fields.text("videoId").label("Video ID") ); }}
35
![Page 42: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/42.jpg)
YouTube Video Component
@Controller@Template(title="YouTube Video", id="myModule:components/youtube")@TemplateDescription("Embed a YouTube video")
public class YoutubeComponent {
@RequestMapping("/youtube") public String render(Node node, ModelMap model) throws RepositoryException { model.put("videoId", node.getProperty("videoId").getString()); return "components/youtube"; }
@TabFactory("Content") public void contentTab(UiConfig cfg, TabBuilder tab) { tab.fields( cfg.fields.text("videoId").label("Video ID") ); }}
35
<iframe width="100%" height="400" src="//www.youtube.com/embed/${videoId}" frameborder="0" allowfullscreen></iframe><!-- In the view -->
![Page 43: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/43.jpg)
Dialogs and the Class Hierarchy
public abstract class BasePageTemplate { @TabFactory("Meta") public void metaTab(UiConfig cfg, TabBuilder tab) { tab.fields(
cfg.fields.text("metaAuthor").label("Author"), cfg.fields.text("metaKeywords").label("Keywords"), cfg.fields.text("metaDescription").label("Description") ); }}
36
![Page 44: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/44.jpg)
Dialogs and the Class Hierarchy
public abstract class BasePageTemplate { @TabFactory("Meta") public void metaTab(UiConfig cfg, TabBuilder tab) { tab.fields(
cfg.fields.text("metaAuthor").label("Author"), cfg.fields.text("metaKeywords").label("Keywords"), cfg.fields.text("metaDescription").label("Description") ); }}
36
<head> <meta name="description" content="${content.metaDescription}"/> <meta name="keywords" content="${content.metaKeywords}" /> <meta name="author" content="${content.metaAuthor}" /></head> <!-- In the view -->
![Page 45: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/45.jpg)
Dynamic Dialog
@Template(id="myModule:components/bookCategory", title="Book category")
@TemplateDescription("A list of books in a given category.")@Controllerpublic class BookCategoryComponent { @Autowired private SalesApplicationWebService service;
@RequestMapping("/bookcategory") public String render(ModelMap model, Node content) throws RepositoryException { String category = content.getProperty("category").getString(); model.put("books", service.getBooksInCategory(category)); return "components/bookCategory"; } @TabFactory("Content") public void contentTab(UiConfig cfg, TabBuilder tab) { Collection<String> categories = service.getBookCategories(); tab.fields( cfg.fields.select("category").label("Category").options(categories) ); }}
37
![Page 46: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/46.jpg)
Dynamic Dialog
...
@TabFactory("Content")public void contentTab(UiConfig cfg, TabBuilder tab) {
Collection<String> categories = service.getBookCategories();
tab.fields(
cfg.fields.select("category").label("Category").options(categories)
);}
...
38
![Page 47: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/47.jpg)
Input Validation
...
public void contentTab(UiConfig cfg, TabBuilder tab) {
tab.fields(
cfg.fields.text("name").label("Name").required(), cfg.fields.text("email").label("Email")⏎ .validator(cfg.validators.email()) );
}
...
39
![Page 48: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/48.jpg)
Page Template Availability
@Controller@Template(title="Article", id="myModule:/pages/article")public class ArticleTemplate {
...
@Available public boolean isAvailable(Node node) { return node.getPath().startsWith("/articles/"); }}
40
![Page 49: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/49.jpg)
Available Components
@Controller
@Area("promos")
@AvailableComponentClasses({TextComponent.class, ShoppingCartComponent.class})public static class PromosArea {
@RequestMapping("/main/promos")
public String render() {
return "areas/promos";
}
}
41
![Page 50: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/50.jpg)
Area Inheritance
@Controller
@Area("promos")
@Inherits@AvailableComponentClasses({TextComponent.class,
ShoppingCartComponent.class})
public static class PromosArea {
@RequestMapping("/main/promos")
public String render() {
return "areas/promos";
}
}
42
![Page 51: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/51.jpg)
SERVLETCONTAINER
RENDERINGFILTER
RENDERINGENGINE
BLOSSOM DISPATCHERSERVLET CONTROLLER
43
How Blossom Works
![Page 52: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/52.jpg)
Magnolia Server
Dat
a
Wor
kflo
w
STK Mod
ules
Magnolia Core
Cus
tom
m
odul
e
Cus
tom
m
odul
e
DM
S Imag
ing
Cus
tom
Th
eme
Module JAR - templates - resources
44
![Page 53: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/53.jpg)
Web container (Tomcat)
Web Archive
Magnolia CMS
Filter chain CMS
Context Security Cache Aggregation
Hierarchical content repository
Content
Custom filter
RequestRendering
Rendering engine
Response
45
![Page 54: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/54.jpg)
Form Submission
/* Standard annotations omitted */
public class ContactFormComponent { @RequestMapping(value="/contact", method=RequestMethod.GET) public String viewForm(@ModelAttribute ContactForm contactForm) { return "components/contactForm";
}
@RequestMapping(value="/contact", method=RequestMethod.POST) public String handleSubmit(@ModelAttribute ContactForm contactForm, ⏎
BindingResult result) {
new ContactFormValidator().validate(contactForm, result);
if (result.hasErrors()) {
return "components/contactForm"; }
return "redirect:/home/contact/thankyou.html";
}
46
![Page 55: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/55.jpg)
But wait a minute …
47
Caused by: org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalStateException at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:894) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778) at javax.servlet.http.HttpServlet.service(HttpServlet.java:617) at info.magnolia.module.blossom.render.BlossomDispatcherServlet.forward(BlossomDispatcherServlet.java:123) at info.magnolia.module.blossom.render.BlossomTemplateRenderer.render(BlossomTemplateRenderer.java:78) ... 92 moreCaused by: java.lang.IllegalStateException
… the response has been sent.
![Page 56: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/56.jpg)
Controller Pre-execution
48
C M V
PAGE
C M V
Area
C M V
Component
C M V
Component
C M V
Component
C
![Page 57: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/57.jpg)
CPE Implementation 49
Code in View
<form>
<blossom:pecid-input /> <input type=”text” name=”email” />
...
HTML Output
<form>
<input type=”hidden” name=”_pecid” value=”ff6cefa6-d958-47b1-af70-c82a414f17e1” /> <input type=”text” name=”email” />
...
![Page 58: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/58.jpg)
Spring Web MVC+
Content
50
![Page 59: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/59.jpg)
Spring Web Flow
51
REQUEST LANDINGPAGE
SPRING WEB FLOW
![Page 60: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/60.jpg)
Spring Web Flow
52
REQUEST LANDINGPAGE
FORMSUBMIT?
SPRING WEB FLOW
![Page 61: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/61.jpg)
Deployment & Scaling 53
![Page 62: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/62.jpg)
Author
MagnoliaPublic A
Magnolia
Public B
Magnolia
Firewall
Activate
Internal Network Internet
Load
Bal
ance
r
JCR
JCR
JCR
54
![Page 63: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/63.jpg)
55
Backend Application
DB
Author
Magnolia
JCR
Public
Magnolia
JCRPublic
Magnolia
JCR
Clustering
![Page 64: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/64.jpg)
Dealing with Change 56
![Page 65: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/65.jpg)
Filter Chain in JCR
57
![Page 66: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/66.jpg)
Configuring Spring Beans 58
<blossom:observed-bean
default-class="com.sample.DiscountService"
path="/modules/myModule/beans/discountService" />
![Page 67: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/67.jpg)
example.com/vanity
59
![Page 68: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/68.jpg)
Changing Resources Live
60
CSSFreeMarkerImagesJavascriptViews
![Page 69: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/69.jpg)
What Do You Win? 61
![Page 70: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/70.jpg)
62
![Page 71: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/71.jpg)
63
![Page 72: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/72.jpg)
64
ShorterLearning
Curve
MVC
Use ExistingSpring Apps &Components
@Annotations
LooseCoupling
DependencyInjection
Code-drivenDialogs
Test-drivenDevelopment
SpringIdiomsSecurity
Scalability
Mobile& Touch
FasterDevelopment
FasterDevelopment
Cycles
Staging
Maglev
![Page 73: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/73.jpg)
64
ShorterLearning
Curve
MVC
Use ExistingSpring Apps &Components
@Annotations
LooseCoupling
DependencyInjection
Code-drivenDialogs
Test-drivenDevelopment
SpringIdiomsSecurity
Scalability
Mobile& Touch
FasterDevelopment
FasterDevelopment
Cycles
Staging
Questions?
Maglev
![Page 74: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/74.jpg)
Want to Learn More?
65
Talk to us in the exhibit hall
Attend Blossom Q & A webinar on Sept. 26http://magnolia-cms.com/blossom-qa
Visit http://magnolia-cms.com/springDashboard for all things Spring in Magnolia
![Page 75: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/75.jpg)
Thank You!
66
![Page 76: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/76.jpg)
Image Credits
67
#2: "Long Drive" by Nicholas A. Tonelli (CC-BY 2.0)#3: "Sluggish" by Nicholas A. Tonelli (CC-BY 2.0)#4: Still from "The Matrix"#7: "South Beach Miami Sunset" by Justin Ornellas (CC-BY 2.0)#14: "HBW - Magnolia Edition" by Nana B Agyei (CC-BY 2.0)#16: "Worker" designed by James Fenton from The Noun Project#16: "Database" designed by Ed Jones from The Noun Project#16: "Document" designed by Timur Zima from The Noun Project#22: "Three levels" by Paolo Fefe (CC-ND 2.0)#43:"Headset" designed by Benoît Bâlon from The Noun Project#43: "Engine" released into the Public Domain#43: "Flower" designed by Danilo Gusmão Silveira from The Noun Project#43: "Video Game Controller" designed by "Michael Rowe" from The Noun Project#51: "Anvil" designed by Masrur Mahmood from The Noun Project#52: "Hand" designed by Mikhail Bazilevsky from The Noun Project#53: "NYC Steam" by Don O'Brien (CC-BY 2.0)#56: "Floods 2013: Riverfront Ave" by Ryan Quan (CC-SA 2.0)#61: "3 Strikes for £2.50" by Julian Frost (CC-BY 2.0)
![Page 77: Spring and Web Content Management](https://reader033.vdocuments.us/reader033/viewer/2022061111/54552d33b1af9f39378b474b/html5/thumbnails/77.jpg)
68
Trademarks
Other trademarks are the property of their respective owners.
MagnoliaThe Pulse are trademarks of
Magnolia International Limited.}