SlideShare a Scribd company logo
1 of 54
Download to read offline
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ías
  dispares
• No siempre podemos esperar que dichas
  tecnologías dispares se configuren
  necesariamente 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 existe
  A 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, ItsNatServletConfig
  y 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 servlet
  itsNatConfig.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 servlet
itsNatConfig.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 template
  core_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 XML
   docTemplate = 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 procesador
 ItsNatDocFragmentTemplate 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 fragment
  manual.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
ItsNatBeansRegistryUtil
package 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 ApplicationContext
     implementamos
     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
ItsNatServletContextBean
public 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
ItsNatServletContextBean
    public 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
ItsNatServletRequestListenerBean
package 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

More Related Content

What's hot

JUG.ua 20170225 - Java bytecode instrumentation
JUG.ua 20170225 - Java bytecode instrumentationJUG.ua 20170225 - Java bytecode instrumentation
JUG.ua 20170225 - Java bytecode instrumentationAnton Arhipov
 
Node.js moduly a testovanie
Node.js moduly a testovanieNode.js moduly a testovanie
Node.js moduly a testovanieharcek
 
Curso Symfony - Clase 5
Curso Symfony - Clase 5Curso Symfony - Clase 5
Curso Symfony - Clase 5Javier Eguiluz
 
NrStage 사용하기
NrStage 사용하기NrStage 사용하기
NrStage 사용하기Yongwu Choi
 
Test driven java script development
Test driven java script developmentTest driven java script development
Test driven java script developmentStefan Scheidt
 
Zend bootstrap
Zend bootstrapZend bootstrap
Zend bootstrapneuros
 
Jak zabít několik much jednou ranou přechodem na fragmenty
Jak zabít několik much jednou ranou přechodem na fragmentyJak zabít několik much jednou ranou přechodem na fragmenty
Jak zabít několik much jednou ranou přechodem na fragmentyDavid Vávra
 

What's hot (7)

JUG.ua 20170225 - Java bytecode instrumentation
JUG.ua 20170225 - Java bytecode instrumentationJUG.ua 20170225 - Java bytecode instrumentation
JUG.ua 20170225 - Java bytecode instrumentation
 
Node.js moduly a testovanie
Node.js moduly a testovanieNode.js moduly a testovanie
Node.js moduly a testovanie
 
Curso Symfony - Clase 5
Curso Symfony - Clase 5Curso Symfony - Clase 5
Curso Symfony - Clase 5
 
NrStage 사용하기
NrStage 사용하기NrStage 사용하기
NrStage 사용하기
 
Test driven java script development
Test driven java script developmentTest driven java script development
Test driven java script development
 
Zend bootstrap
Zend bootstrapZend bootstrap
Zend bootstrap
 
Jak zabít několik much jednou ranou přechodem na fragmenty
Jak zabít několik much jednou ranou přechodem na fragmentyJak zabít několik much jednou ranou přechodem na fragmenty
Jak zabít několik much jednou ranou přechodem na fragmenty
 

Configurar con spring un api no basado en spring

  • 1. CONFIGURAR CON SPRING UN API NO BASADO EN SPRING Jose María Arranz Santamaría Madrid (España) 17-18 Febrero 2011 1
  • 3. EL PROBLEMA • Spring nació como una herramienta de configuración e integración de tecnologías dispares • No siempre podemos esperar que dichas tecnologías dispares se configuren necesariamente con Spring ¡Para eso existe Spring! 3
  • 4. 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 existe A 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. 5
  • 6. TRANQUILO ¡ESTA NO SERÁ UNA CLASE DE ItsNat!  6
  • 8. PERO HAY QUE CONOCER CÓMO SE CONFIGURA ItsNat PARA APLICAR Spring 8
  • 9. 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
  • 10. EJEMPLO ItsNat “PURO” : el servlet • ItsNatHttpServlet, ItsNatServletConfig y 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
  • 11. EJEMPLO ItsNat “PURO” : el servlet itsNatConfig.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
  • 12. EJEMPLO ItsNat “PURO” : el servlet itsNatConfig.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
  • 13. EJEMPLO ItsNat “PURO” : el servlet • Ahora registramos en el servlet un template core_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
  • 14. EJEMPLO ItsNat “PURO” : el servlet • Y otro ejemplo de generación de página XML docTemplate = 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 procesador ItsNatDocFragmentTemplate docFragTemplate; docFragTemplate = itsNatServlet.registerItsNatDocFragmentTemplate( "manual.core.xmlFragExample","text/xml", pathPrefix + "xml_fragment_example.xml"); 14
  • 15. 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
  • 16. 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
  • 17. 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
  • 19. 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
  • 20. 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
  • 21. EJEMPLO ItsNat “PURO” • CoreXMLExampleLoadListener : como en XML no hay AJAX no necesitamos una clase wrapper de documento. Se incluye el template fragment manual.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
  • 24. 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
  • 25. 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
  • 26. 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
  • 27. 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
  • 28. ItsNatBeansRegistryUtil package 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
  • 29. 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
  • 30. 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
  • 31. 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
  • 32. 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 ApplicationContext implementamos ApplicationContextAware – Como necesitamos actuar cuando termine la configuración del bean, implementamos InitializingBean 32
  • 33. 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
  • 34. ItsNatServletContextBean public 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
  • 35. ItsNatServletContextBean public 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
  • 36. 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
  • 37. 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
  • 38. 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
  • 39. • 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
  • 40. 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
  • 41. 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
  • 42. 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
  • 43. ItsNatServletRequestListenerBean package 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
  • 44. 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
  • 45. 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
  • 46. 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
  • 47. 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
  • 48. 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
  • 49. 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
  • 50. 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
  • 51. 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
  • 52. CONCLUSIÓN ¿Puedes integrar Spring para configurar “cualquier” API? 52