Post on 09-Jul-2015
description
CONFIGURAR CON SPRING UN API NO
BASADO EN SPRING
Jose María Arranz Santamaría
Madrid (España) 17-18 Febrero 2011
1
EL PROBLEMA
2
EL PROBLEMA
• Spring nació como una herramienta de configuración e integración de tecnologíasdispares
• No siempre podemos esperar que dichastecnologías dispares se configurennecesariamente con Spring
¡Para eso existe Spring!
3
EL PROBLEMA
• ItsNat es un framework web Java que tiene su propio sistema de configuración
• ItsNat se configura de la forma más potente y flexible que existeA través de llamadas a métodos
• Desde el día 0 se concibió para poder ser “sobrecargado” con APIs de más alto nivel, por ejemplo con… ¡Spring!
4
5
TRANQUILO ¡ESTA NO SERÁ UNA CLASE DE ItsNat!
6
APRENDEREMOS ALGUNOS TRUCOS DE Spring
7
PERO HAY QUE CONOCER CÓMO SE CONFIGURA ItsNat PARA APLICAR
Spring
8
EJEMPLO ItsNat “PURO”: el servlet• ItsNat no define un servlet concreto, el usuario
debe crear uno (o más)– Se configura en el método init
• La inmensa mayoría de los flags de configuración usados son opcionales (coinciden con el valor por defecto)
public class servlet extends HttpServletWrapper
{
public void init(ServletConfig config) throws ServletException
{
super.init(config);
ItsNatHttpServlet itsNatServlet = getItsNatHttpServlet();
ItsNatServletConfig itsNatConfig =
itsNatServlet.getItsNatServletConfig();
ItsNatServletContext itsNatCtx =
itsNatConfig.getItsNatServletContext();
9
EJEMPLO ItsNat “PURO” : el servlet
• ItsNatHttpServlet, ItsNatServletConfigy ItsNatServletContext son los objetos raíz de configuración en ItsNat
itsNatCtx.setMaxOpenDocumentsBySession(6);
String serverInfo = getServletContext().getServerInfo();
boolean gaeEnabled = serverInfo.startsWith(
"Google App Engine");
itsNatCtx.setSessionReplicationCapable(gaeEnabled);
itsNatCtx.setSessionSerializeCompressed(false);
itsNatCtx.setSessionExplicitSerialize(false);
10
EJEMPLO ItsNat “PURO” : el servletitsNatConfig.setDebugMode(true);
itsNatConfig.setClientErrorMode(
ClientErrorMode.SHOW_SERVER_AND_CLIENT_ERRORS);
itsNatConfig.setLoadScriptInline(true);
itsNatConfig.setFastLoadMode(true);
itsNatConfig.setCommMode(CommMode.XHR_ASYNC_HOLD);
itsNatConfig.setEventTimeout(-1);
itsNatConfig.setOnLoadCacheStaticNodes("text/html",true);
itsNatConfig.setOnLoadCacheStaticNodes("text/xml",false);
itsNatConfig.setNodeCacheEnabled(true);
11
EJEMPLO ItsNat “PURO” : el servletitsNatConfig.setDefaultEncoding("UTF-8");
itsNatConfig.setUseGZip(UseGZip.SCRIPT);
itsNatConfig.setDefaultDateFormat(
DateFormat.getDateInstance(DateFormat.DEFAULT,Locale.US));
itsNatConfig.setDefaultNumberFormat(
NumberFormat.getInstance(Locale.US));
itsNatConfig.setEventDispatcherMaxWait(0);
itsNatConfig.setEventsEnabled(true);
itsNatConfig.setScriptingEnabled(true);
itsNatConfig.setUsePatternMarkupToRender(false);
itsNatConfig.setAutoCleanEventListeners(true);
12
EJEMPLO ItsNat “PURO” : el servlet• Ahora registramos en el servlet un templatecore_example.xhtml con su procesador de carga CoreExampleLoadListener
– Ejemplo sencillo de página HTML con AJAX
String pathPrefix = getServletContext().getRealPath("/");
pathPrefix += "/WEB-INF/pages/manual/";
ItsNatDocumentTemplate docTemplate;
docTemplate = itsNatServlet.registerItsNatDocumentTemplate(
"manual.core.example","text/html",
pathPrefix + "core_example.xhtml");
docTemplate.addItsNatServletRequestListener(
new CoreExampleLoadListener());
13
EJEMPLO ItsNat “PURO” : el servlet
• Y otro ejemplo de generación de página XMLdocTemplate = itsNatServlet.registerItsNatDocumentTemplate(
"manual.core.xmlExample","text/xml",
pathPrefix + "xml_example.xml");
docTemplate.addItsNatServletRequestListener(
new CoreXMLExampleLoadListener());
• Que a su vez inserta un template fragment
– Los template fragment no tienen procesadorItsNatDocFragmentTemplate docFragTemplate;
docFragTemplate = itsNatServlet.registerItsNatDocFragmentTemplate(
"manual.core.xmlFragExample","text/xml",
pathPrefix + "xml_fragment_example.xml");
14
EJEMPLO ItsNat “PURO”
• <root>/WEB-INF/pages/manual/core_example.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>ItsNat Core Example</title></head>
<body>
<h3>ItsNat Core Example</h3>
<div itsnat:nocache="true"
xmlns:itsnat="http://itsnat.org/itsnat">
<div id="clickableId1">Clickable Elem 1</div>
<br />
<div id="clickableId2">Clickable Elem 2</div>
</div>
</body>
</html>
15
EJEMPLO ItsNat “PURO”
• CoreExampleLoadListener es un mero lanzador del gestor del documento en cada carga de página
public class CoreExampleLoadListener
implements ItsNatServletRequestListener
{
public CoreExampleLoadListener() {}
public void processRequest(ItsNatServletRequest request,
ItsNatServletResponse response)
{
ItsNatHTMLDocument itsNatDoc =
(ItsNatHTMLDocument)request.getItsNatDocument();
new CoreExampleDocument(itsNatDoc);
}
}
16
EJEMPLO ItsNat “PURO”
• CoreExampleDocument gestiona el estado de la página recibiendo los eventos AJAX
public class CoreExampleDocument implements EventListener
{
protected ItsNatHTMLDocument itsNatDoc;
protected Element clickElem1;
protected Element clickElem2;
public CoreExampleDocument(ItsNatHTMLDocument itsNatDoc)
{
this.itsNatDoc = itsNatDoc;
load();
}
...
17
EJEMPLO ItsNat “PURO”
18
EJEMPLO ItsNat “PURO”
• <root>/WEB-INF/pages/manual/xml_example.xml
<?xml version='1.0' encoding='UTF-8' ?>
<discs>
<itsnat:include name="manual.core.xmlFragExample"
xmlns:itsnat="http://itsnat.org/itsnat" />
<cdList>
<cd>
<title>Tittle</title>
<artist>Artist</artist>
<songs>
<song>Song Pattern</song>
</songs>
</cd>
</cdList>
</discs>
19
EJEMPLO ItsNat “PURO”
• <root>/WEB-INF/pages/manual/xml_fragment_example.xml
<?xml version='1.0' encoding='UTF-8' ?>
<root>
<title>CD List</title>
<subtitle>in XML</subtitle>
</root>
20
EJEMPLO ItsNat “PURO”• CoreXMLExampleLoadListener : como en XML
no hay AJAX no necesitamos una clase wrapper de documento. Se incluye el template fragmentmanual.core.xmlFragExample
public class CoreXMLExampleLoadListener
implements ItsNatServletRequestListener
{
public CoreXMLExampleLoadListener() { }
public void processRequest(ItsNatServletRequest request,
ItsNatServletResponse response)
{
ItsNatDocument itsNatDoc = request.getItsNatDocument();
Document doc = itsNatDoc.getDocument();
Element discsElem = doc.getDocumentElement();
...
21
EJEMPLO ItsNat “PURO”
22
ItsNat Springization
23
OBJETIVOS
1. Un único servlet genérico reutilizable: itsnatspring.itsnatservlet
2. La configuración se realizará totalmente en un archivo XML de Spring en el classpath:
itsnatex/spring.xml
3. Las únicas clases del usuario serán las clases contenedoras del documento ItsNat (=página): itsnatex.CoreExampleDocument
itsnatex.CoreXMLExampleDocument
24
CONSECUENCIAS
• Además del servlet genérico reutilizable necesitaremos una serie de clases de utilidad también genéricas y reutilizables
• Dichas clases quedarán incompletas, sólo cubriremos las necesidades de este ejemplo
– ItsNat tiene más métodos de configuración
25
EL SERVLET
package itsnatspring;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import org.itsnat.core.http.HttpServletWrapper;
import org.itsnat.core.http.ItsNatHttpServlet;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.GenericApplicationContext;
public class itsnatservlet extends HttpServletWrapper
{
public void init(ServletConfig config) throws ServletException
{
super.init(config);
ItsNatHttpServlet itsNatServlet = getItsNatHttpServlet();
GenericApplicationContext rootContext = new GenericApplicationContext();
ItsNatBeansRegistryUtil.registerSingletons(rootContext, itsNatServlet);
rootContext.refresh();
26
EL SERVLET
String springXMLPath = config.getInitParameter("spring_config");
if (springXMLPath == null)
throw new RuntimeException("spring_config initialization
parameter is not specified in web.xml");
ApplicationContext context =
new ClassPathXmlApplicationContext(
new String[] {springXMLPath},rootContext);
}
}
• Se registran como singleton los objetos de configuración de ItsNat en un ApplicationContext genérico raíz y se carga en otro nuevo nuestro XML Spring
27
ItsNatBeansRegistryUtilpackage itsnatspring;
import org.itsnat.core.ItsNatServletConfig;
import org.itsnat.core.ItsNatServletContext;
import org.itsnat.core.http.ItsNatHttpServlet;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
public class ItsNatBeansRegistryUtil
{
public final static String itsNatHttpServletBean = "itsNatHttpServlet";
public final static String itsNatServletConfigBean = "itsNatServletConfig";
public final static String itsNatServletContextBean = "itsNatServletContext";
public static ItsNatHttpServlet getItsNatHttpServlet(ApplicationContext context) {
return context.getBean(itsNatHttpServletBean,ItsNatHttpServlet.class);
}
public static ItsNatServletConfig getItsNatServletConfig(ApplicationContext context){
return context.getBean(itsNatServletConfigBean,ItsNatServletConfig.class);
}
public static ItsNatServletContext getItsNatServletContext(ApplicationContext context){
return context.getBean(itsNatServletContextBean,ItsNatServletContext.class);
}
28
ItsNatBeansRegistryUtil
public static void registerSingletons(AbstractApplicationContext context,
ItsNatHttpServlet itsNatServlet)
{
ItsNatServletConfig itsNatServletCofig =
itsNatServlet.getItsNatServletConfig();
ItsNatServletContext itsNatServletContext =
itsNatServletCofig.getItsNatServletContext();
ConfigurableListableBeanFactory beanFact = context.getBeanFactory();
beanFact.registerSingleton(itsNatHttpServletBean,itsNatServlet);
beanFact.registerSingleton(itsNatServletConfigBean,itsNatServletCofig);
beanFact.registerSingleton(itsNatServletContextBean,itsNatServletContext);
}
}
• El resultado es el registro manual como singleton de los objetos de conf. de ItsNat
29
web.xml<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<servlet>
<servlet-name>itsnatservlet</servlet-name>
<servlet-class>itsnatspring.itsnatservlet</servlet-class>
<init-param>
<param-name>spring_config</param-name>
<param-value>itsnatex/spring.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>itsnatservlet</servlet-name>
<url-pattern>/itsnatservlet</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
</web-app> 30
spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<bean class="itsnatspring.ItsNatServletContextBean">
<property name="maxOpenDocumentsBySession" value="10" />
<property name="sessionReplicationCapable" value="false" />
<property name="sessionSerializeCompressed" value="false" />
<property name="sessionExplicitSerialize" value="false" />
</bean>
31
ItsNatServletContextBean
• Este bean singleton de utilidad nos sirve para recordar los flags definidos y al final registrarlos de forma efectiva en el ItsNatServletContext
– Como se necesita el ApplicationContextimplementamos ApplicationContextAware
– Como necesitamos actuar cuando termine la configuración del bean, implementamos InitializingBean
32
ItsNatServletContextBean
package itsnatspring;
import org.itsnat.core.ItsNatServletContext;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class ItsNatServletContextBean
implements InitializingBean,ApplicationContextAware
{
protected ApplicationContext context;
protected Integer maxOpenDocumentsBySession;
protected Boolean sessionReplicationCapable;
protected Boolean sessionSerializeCompressed;
protected Boolean sessionExplicitSerialize;
public ItsNatServletContextBean() { }
33
ItsNatServletContextBeanpublic int getMaxOpenDocumentsBySession() {
return maxOpenDocumentsBySession;
}
public void setMaxOpenDocumentsBySession(int maxOpenDocumentsBySession){
this.maxOpenDocumentsBySession = maxOpenDocumentsBySession;
}
public boolean getSessionReplicationCapable() {
return sessionReplicationCapable;
}
public void setSessionReplicationCapable(
boolean sessionReplicationCapable) {
this.sessionReplicationCapable = sessionReplicationCapable;
}
public boolean getSessionSerializeCompressed() {
return sessionSerializeCompressed;
}
public void setSessionSerializeCompressed(
boolean sessionSerializeCompressed) {
this.sessionSerializeCompressed = sessionSerializeCompressed;
}34
ItsNatServletContextBeanpublic boolean getSessionExplicitSerialize() { return sessionExplicitSerialize; }
public void setSessionExplicitSerialize(boolean sessionExplicitSerialize){
this.sessionExplicitSerialize = sessionExplicitSerialize;
}
@Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
this.context = context; }
@Override
public void afterPropertiesSet() throws Exception {
ItsNatServletContext itsNatServletContext =
ItsNatBeansRegistryUtil.getItsNatServletContext(context);
if (maxOpenDocumentsBySession != null)
itsNatServletContext.setMaxOpenDocumentsBySession(maxOpenDocumentsBySession);
if (sessionReplicationCapable != null)
itsNatServletContext.setSessionReplicationCapable(sessionReplicationCapable);
if (sessionSerializeCompressed != null)
itsNatServletContext.setSessionSerializeCompressed(sessionSerializeCompressed);
if (sessionExplicitSerialize != null)
itsNatServletContext.setSessionExplicitSerialize(sessionExplicitSerialize);
}
}
35
spring.xml (cont.)<bean id="defaultLocale" class="itsnatspring.LocaleBean" >
<property name="language" value="en" />
<property name="country" value="US" />
</bean>
<bean id="defaultDateFormat" class="itsnatspring.DateFormatBean" >
<property name="style" value="2" /> <!-- DateFormat.DEFAULT -->
<property name="locale">
<bean factory-bean="defaultLocale" factory-method="getLocale"/>
</property>
</bean>
<bean id="defaultNumberFormat" class="itsnatspring.NumberFormatBean" >
<property name="locale">
<bean factory-bean="defaultLocale" factory-method="getLocale" />
</property>
</bean>
... 36
LocaleBean• Este “factory bean” nos permite configurar un objeto y
hacerlo público a través del “factory method” getLocale()
package itsnatspring;
import java.util.Locale;
import org.springframework.beans.factory.InitializingBean;
public class LocaleBean implements InitializingBean
{
protected String language;
protected String country;
protected Locale locale;
public LocaleBean() { }
public String getCountry() { return country; }
public void setCountry(String country) { this.country = country; }
public String getLanguage() { return language; }
37
LocaleBean
public void setLanguage(String language) { this.language = language; }
public Locale getLocale() { return locale; }
@Override
public void afterPropertiesSet() throws Exception
{
Locale[] availablelocales = Locale.getAvailableLocales();
for(Locale locale : availablelocales)
if (locale.getLanguage().equals(language) &&
locale.getCountry().equals(country))
{
this.locale = locale;
return;
}
this.locale = new Locale(language,country);
}
}
38
• Desde ahora sólo mostraremos las clases de utilidad más interesantes
• A partir del XML puede intuirse la funcionalidad de las demás
– Obteniéndose los singleton de configuración de ItsNat a través del ApplicationContext
– El cual es obtenido implementando ApplicationContextAware
39
spring.xml (cont.)
<bean class="itsnatspring.ItsNatServletConfigBean">
<property name="debugMode" value="true" />
<property name="clientErrorMode" value="4" />
<!– ClientErrorMode.SHOW_SERVER_AND_CLIENT_ERRORS -->
<property name="defaultEncoding" value="UTF-8" />
<property name="onLoadCacheStaticNodes">
<value>
text/html=true
text/xml=false
</value>
</property>
<property name="defaultDateFormat">
<bean factory-bean="defaultDateFormat" factory-method="getDateFormat"/>
</property>
<property name="defaultNumberFormat">
<bean factory-bean="defaultNumberFormat" factory-method="getNumberFormat"/>
</property>
</bean>
...40
spring.xml (cont.)
<bean id="coreExamplePath" class="itsnatspring.WebPathBean">
<property name="relativePath" value="/WEB-INF/pages/manual/core_example.xhtml"/>
</bean>
<bean id="coreExampleDoc" class="itsnatex.CoreExampleDocument" scope="prototype" >
<!-- Globals Here -->
</bean>
<bean id="coreExampleDocTemplate" class="itsnatspring.ItsNatDocumentTemplateBean">
<property name="name" value="manual.core.example" />
<property name="mime" value="text/html" />
<property name="source">
<bean factory-bean="coreExamplePath" factory-method="getAbsolutePath"/>
</property>
<property name="itsNatServletRequestListener" >
<bean class="itsnatspring.ItsNatServletRequestListenerBean" >
<property name="documentBeanName" value="coreExampleDoc" />
</bean>
</property>
</bean>
...
41
ItsNatServletRequestListenerBean
• Este bean es MUY interesante pues actúa como “ItsNat document loader listener” genérico
• Nos obligará a que la clase procesadora del documento implemente una sencilla interfaz especial llamada: ItsNatDocumentInitialize
package itsnatspring;
import org.itsnat.core.ItsNatServletRequest;
import org.itsnat.core.ItsNatServletResponse;
public interface ItsNatDocumentInitialize
{
public void load(ItsNatServletRequest request,
ItsNatServletResponse response);
}
42
ItsNatServletRequestListenerBeanpackage itsnatspring;
import org.itsnat.core.ItsNatServletRequest;
import org.itsnat.core.ItsNatServletResponse;
import org.itsnat.core.event.ItsNatServletRequestListener;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.support.AbstractApplicationContext;
public class ItsNatServletRequestListenerBean implements
ItsNatServletRequestListener,ApplicationContextAware,InitializingBean
{
protected AbstractApplicationContext context;
protected String documentBeanName;
public ItsNatServletRequestListenerBean() { }43
ItsNatServletRequestListenerBean
public void processRequest(ItsNatServletRequest request,
ItsNatServletResponse response) {
ItsNatDocumentInitialize docWrapper =
context.getBean(documentBeanName,ItsNatDocumentInitialize.class);
docWrapper.load(request, response);
}
public String getDocumentBeanName() { return documentBeanName; }
public void setDocumentBeanName(String documentBeanName) {
this.documentBeanName = documentBeanName;
}
44
ItsNatServletRequestListenerBean@Override
public void setApplicationContext(ApplicationContext context)
throws BeansException {
this.context = (AbstractApplicationContext)context;
}
@Override
public void afterPropertiesSet() throws Exception {
// Checking correctly defined:
if (documentBeanName == null)
throw new RuntimeException("docBeanName property is mandatory");
if (!context.getBeanFactory().isPrototype(documentBeanName))
throw new RuntimeException("Bean " + documentBeanName +
" must be \"prototype\" scoped");
}
}
45
ItsNatDocumentTemplateBean• Finalmente este bean registrará en el template el “ItsNat
document loader listener” configurado
package itsnatspring;
import org.itsnat.core.event.ItsNatServletRequestListener;
import org.itsnat.core.http.ItsNatHttpServlet;
import org.itsnat.core.tmpl.ItsNatDocumentTemplate;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class ItsNatDocumentTemplateBean
implements InitializingBean,ApplicationContextAware {
protected ApplicationContext context;
protected String name;
protected String mime;
protected Object source;
protected ItsNatServletRequestListener itsNatServletRequestListener;
46
ItsNatDocumentTemplateBean
public ItsNatServletRequestListener getItsNatServletRequestListener(){
return itsNatServletRequestListener;
}
public void setItsNatServletRequestListener(
ItsNatServletRequestListener itsNatServletRequestListener) {
this.itsNatServletRequestListener = itsNatServletRequestListener;
}
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getMime() { return mime; }
public void setMime(String mime) { this.mime = mime; }
public Object getSource() { return source; }
public void setSource(Object source) { this.source = source; }
@Override
public void setApplicationContext(ApplicationContext context)
throws BeansException {
this.context = context;
}
47
ItsNatDocumentTemplateBean
@Override
public void afterPropertiesSet() throws Exception
{
// name, mime and source are mandatory
ItsNatHttpServlet itsNatHttpServlet =
ItsNatBeansRegistryUtil.getItsNatHttpServlet(context);
ItsNatDocumentTemplate docTemplate =
itsNatHttpServlet.registerItsNatDocumentTemplate(name,mime,source);
if (itsNatServletRequestListener != null)
docTemplate.addItsNatServletRequestListener(
itsNatServletRequestListener);
// More config here...
}
}
48
spring.xml (cont.)<bean id="coreXMLDocExamplePath" class="itsnatspring.WebPathBean">
<property name="relativePath" value="/WEB-INF/pages/manual/xml_example.xml" />
</bean>
<bean id="coreXMLExampleDoc" class="itsnatex.CoreXMLExampleDocument“
scope="prototype">
<!-- Globals Here -->
</bean>
<bean id="coreXMLExampleDocTemplate" class="itsnatspring.ItsNatDocumentTemplateBean">
<property name="name" value="manual.core.xmlExample" />
<property name="mime" value="text/xml" />
<property name="source">
<bean factory-bean="coreXMLDocExamplePath"
factory-method="getAbsolutePath"/>
</property>
<property name="itsNatServletRequestListener" >
<bean class="itsnatspring.ItsNatServletRequestListenerBean" >
<property name="documentBeanName" value="coreXMLExampleDoc" />
</bean>
</property>
</bean> ...
49
spring.xml (cont.)
<bean id="coreXMLFragExamplePath" class="itsnatspring.WebPathBean">
<property name="relativePath"
value="/WEB-INF/pages/manual/xml_fragment_example.xml" />
</bean>
<bean id="coreXMLExampleFragTemplate"
class="itsnatspring.ItsNatDocFragmentTemplateBean">
<property name="name" value="manual.core.xmlFragExample" />
<property name="mime" value="text/xml" />
<property name="source">
<bean factory-bean="coreXMLFragExamplePath"
factory-method="getAbsolutePath"/>
</property>
</bean>
</beans>
50
ItsNatDocFragmentTemplateBean• Con ella registramos un template fragment...
public class ItsNatDocFragmentTemplateBean
implements InitializingBean,ApplicationContextAware
{
protected ApplicationContext context;
protected String name;
protected String mime;
protected Object source;
...
@Override
public void afterPropertiesSet() throws Exception {
// name, mime and source are mandatory
ItsNatHttpServlet itsNatHttpServlet =
ItsNatBeansRegistryUtil.getItsNatHttpServlet(context);
ItsNatDocFragmentTemplate fragTemplate;
fragTemplate = itsNatHttpServlet.registerItsNatDocFragmentTemplate(
name,mime,source);
// More config here...
}
} 51
CONCLUSIÓN¿Puedes integrar Spring para configurar “cualquier” API?
52
YES, YOU CAN!
53
¿PREGUNTAS?
54