ºÝºÝߣ

ºÝºÝߣShare a Scribd company logo
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)
   ¨C 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
   ¨C 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
  ¨C 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
  ¨C 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
   ¨C Como se necesita el ApplicationContext
     implementamos
     ApplicationContextAware
   ¨C 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
  ¨C Obteni¨¦ndose los singleton de configuraci¨®n de
    ItsNat a trav¨¦s del ApplicationContext
  ¨C El cual es obtenido implementando
    ApplicationContextAware


                                                     39
spring.xml (cont.)
<bean class="itsnatspring.ItsNatServletConfigBean">
    <property name="debugMode" value="true" />
    <property name="clientErrorMode" value="4" />
         <!¨C 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

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) ¨C 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 ¨C 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 ¨C 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 ¨C 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 ¨C Como se necesita el ApplicationContext implementamos ApplicationContextAware ¨C 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 ¨C Obteni¨¦ndose los singleton de configuraci¨®n de ItsNat a trav¨¦s del ApplicationContext ¨C 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" /> <!¨C 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