SlideShare uma empresa Scribd logo
1 de 54
Baixar para ler offline
HOW TO CONFIGURE WITH SPRING AN
    API NOT BASED ON SPRING
    Jose María Arranz Santamaría



                   Madrid (Spain) February 17-18, 2011
                                                         1
THE PROBLEM




              2
THE PROBLEM
• Spring was born as a tool to configure and
  integrate disparate technologies
• We can not always expect such disparate
  technologies be ready to be configured “out of
  the box” with Spring
     This is the thing Spring was invented for!



                                               3
THE PROBLEM
• ItsNat is a Java web framework
  with a custom non-Spring configuration system
• ItsNat configuration is the most powerful and
  flexible approach ever invented: Calling methods!
• As of day 0 ItsNat configuration was conceived to
  be “overloaded” with higher level configuration
  techniques and APIs, for instance… Spring!



                                                  4
5
DO NOT WORRY THIS IS NOT GOING
    TO BE AN ItsNat COURSE!
               



                                 6
WE ARE GOING TO LEARN SOME
        Spring TRICKS




                             7
BUT WE MUST KNOW HOW TO
 CONFIGURE A WEB PROJECT BASED
 ON ItsNat TO CONFIGURE IT LATER
           WITH Spring

We will pick the “core” example in the
      ItsNat Reference Manual

                                         8
“PURE” ItsNat EXAMPLE: the servlet
• ItsNat does not define a concrete servlet,
  developer must create one (or more)
   – Configuration is done in method init
       • In this example most of configuration is optional, just
         used to show ItsNat configuration options
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
“PURE” ItsNat EXAMPLE: the servlet
• ItsNatHttpServlet, ItsNatServletConfig
  y ItsNatServletContext are the roots (and
  singletons) of ItsNat configuration
  itsNatCtx.setMaxOpenDocumentsBySession(6);

  String serverInfo = getServletContext().getServerInfo();
  boolean gaeEnabled = serverInfo.startsWith(
     "Google App Engine");

  itsNatCtx.setSessionReplicationCapable(gaeEnabled);
  itsNatCtx.setSessionSerializeCompressed(false);
  itsNatCtx.setSessionExplicitSerialize(false);




                                                        10
“PURE” ItsNat EXAMPLE: the 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
“PURE” ItsNat EXAMPLE: the 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
“PURE” ItsNat EXAMPLE: the servlet
• Now we register in the servlet an ItsNat template
  core_example.xhtml and associated document loader
  CoreExampleLoadListener
   – Just a simple example of HTML page with 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
“PURE” ItsNat EXAMPLE: the servlet
• Another example, in this case a page with XML
   docTemplate = itsNatServlet.registerItsNatDocumentTemplate(
       "manual.core.xmlExample","text/xml",
       pathPrefix + "xml_example.xml");
  docTemplate.addItsNatServletRequestListener(
       new CoreXMLExampleLoadListener());

• This XML example inserts an ItsNat “template
  fragment”
  – Template fragments have not “loaders/processors”
 ItsNatDocFragmentTemplate docFragTemplate;
 docFragTemplate = itsNatServlet.registerItsNatDocFragmentTemplate(
      "manual.core.xmlFragExample","text/xml",
      pathPrefix + "xml_fragment_example.xml");



                                                                 14
“PURE” ItsNat EXAMPLE
• <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
“PURE” ItsNat EXAMPLE
• CoreExampleLoadListener is just a simple
  launcher of document processors, called per page
  loaded
public class CoreExampleLoadListener
       implements ItsNatServletRequestListener
{
  public CoreExampleLoadListener() {}

    public void processRequest(ItsNatServletRequest request,
           ItsNatServletResponse response)
    {
      ItsNatHTMLDocument itsNatDoc =
             (ItsNatHTMLDocument)request.getItsNatDocument();
      new CoreExampleDocument(itsNatDoc);
    }
}

                                                                16
“PURE” ItsNat EXAMPLE
• CoreExampleDocument manages the page
  (document) state receiving AJAX events
public class CoreExampleDocument implements EventListener
{
    protected ItsNatHTMLDocument itsNatDoc;
    protected Element clickElem1;
    protected Element clickElem2;

    public CoreExampleDocument(ItsNatHTMLDocument itsNatDoc)
    {
        this.itsNatDoc = itsNatDoc;
        load();
    }
    ...


                                                            17
“PURE” ItsNat EXAMPLE




                        18
“PURE” ItsNat EXAMPLE
• <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
“PURE” ItsNat EXAMPLE
• <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
“PURE” ItsNat EXAMPLE
• CoreXMLExampleLoadListener : in this case
  (XML page) there is no AJAX events, we do not need a
  class wrapping the document. This example includes the
  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
“PURE” ItsNat EXAMPLE




                        22
ItsNat Springization




                       23
OBJETIVES
1. Build a single reused generic servlet :
     itsnatspring.itsnatservlet
2. Configuration is fully done in a XML
   configuration file of Spring in classpath:
     itsnatex/spring.xml
3. The only user defined Java classes will be the
   document wrappers/containers:
     itsnatex.CoreExampleDocument
     itsnatex.CoreXMLExampleDocument

                                                24
CONSEQUENCES
• Besides the generic servlet we will need some
  utility classes also generic and reusable for
  other ItsNat+Spring projects
• These classes are not completed, just to cover
  the needs of this example
  – ItsNat has more configuration options




                                               25
THE 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
THE 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);
    }
}

• ItsNat configuration objects are registered into a
  generic ApplicationContext (the root), our
  XML with Spring configuration is loaded by
  another (child) Spring context

                                                                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);
    }
}

• ItsNat configuration objects are manually
  registered as singletons in Spring context

                                                                             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
• This utility class is used as a singleton to save the
  specified flags and in the end of bean configuration
  they are registered calling methods of
  ItsNatServletContext
   – Because we need the ApplicationContext
     we will implement
     ApplicationContextAware
   – Because we must to save in ItsNat context our
     configuration data in the end of bean
     configuration we need to implement
     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
• This “factory bean” allows configuring a Locale and
  made public calling the “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
• Some other utility classes are very similar to the
  previous shown, from now we are just to show
  only the most interesting
• From Spring XML you can figure out how they
  work under the hood
   – ItsNat singletons are got through
     ItsNatBeansRegistryUtil and the Spring
     ApplicationContext
   – This context is got implementing
     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"> <!– backed by a Properties attr -->
        <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
• This “local singleton bean” is very interesting becase it works
  like a generic “ItsNat document loader listener”
  implementing ItsNatServletRequestListener
• To be generic we must invent a simple interface
  ItsNatDocumentInitialize for the document
  processors/wrappers:
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
• Finally this bean registers the template and the
  associated “ItsNat document loader listener” configured
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
• With this class the template fragment is registered
...
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
CONCLUSION
Can you use Spring to configure “any”
                API?



                                    52
YES, YOU CAN!




                53
QUESTIONS?




             54

Mais conteúdo relacionado

Mais procurados

Defcon 20-zulla-improving-web-vulnerability-scanning
Defcon 20-zulla-improving-web-vulnerability-scanningDefcon 20-zulla-improving-web-vulnerability-scanning
Defcon 20-zulla-improving-web-vulnerability-scanning
zulla
 
HTML5 Dev Conf - Sass, Compass & the new Webdev tools
HTML5 Dev Conf - Sass, Compass &  the new Webdev toolsHTML5 Dev Conf - Sass, Compass &  the new Webdev tools
HTML5 Dev Conf - Sass, Compass & the new Webdev tools
Dirk Ginader
 
Web前端性能分析工具导引
Web前端性能分析工具导引Web前端性能分析工具导引
Web前端性能分析工具导引
冰 郭
 
Even faster web sites presentation 3
Even faster web sites presentation 3Even faster web sites presentation 3
Even faster web sites presentation 3
Felipe Lavín
 
Pane web & salame 3 - Un bel tagliere di storie dal web
Pane web & salame 3 - Un bel tagliere di storie dal webPane web & salame 3 - Un bel tagliere di storie dal web
Pane web & salame 3 - Un bel tagliere di storie dal web
Gummy Industries
 
Even faster web sites
Even faster web sitesEven faster web sites
Even faster web sites
Felipe Lavín
 

Mais procurados (20)

Frfrfrf
FrfrfrfFrfrfrf
Frfrfrf
 
Polyglot payloads in practice by avlidienbrunn at HackPra
Polyglot payloads in practice by avlidienbrunn at HackPraPolyglot payloads in practice by avlidienbrunn at HackPra
Polyglot payloads in practice by avlidienbrunn at HackPra
 
Defcon 20-zulla-improving-web-vulnerability-scanning
Defcon 20-zulla-improving-web-vulnerability-scanningDefcon 20-zulla-improving-web-vulnerability-scanning
Defcon 20-zulla-improving-web-vulnerability-scanning
 
Use Web Skills To Build Mobile Apps
Use Web Skills To Build Mobile AppsUse Web Skills To Build Mobile Apps
Use Web Skills To Build Mobile Apps
 
XSS Attacks Exploiting XSS Filter by Masato Kinugawa - CODE BLUE 2015
XSS Attacks Exploiting XSS Filter by Masato Kinugawa - CODE BLUE 2015XSS Attacks Exploiting XSS Filter by Masato Kinugawa - CODE BLUE 2015
XSS Attacks Exploiting XSS Filter by Masato Kinugawa - CODE BLUE 2015
 
Case Study of Django: Web Frameworks that are Secure by Default
Case Study of Django: Web Frameworks that are Secure by DefaultCase Study of Django: Web Frameworks that are Secure by Default
Case Study of Django: Web Frameworks that are Secure by Default
 
Progressive Downloads and Rendering - take #2
Progressive Downloads and Rendering - take #2Progressive Downloads and Rendering - take #2
Progressive Downloads and Rendering - take #2
 
User Credential handling in Web Applications done right
User Credential handling in Web Applications done rightUser Credential handling in Web Applications done right
User Credential handling in Web Applications done right
 
#NoXML: Eliminating XML in Spring Projects - SpringOne 2GX 2015
#NoXML: Eliminating XML in Spring Projects - SpringOne 2GX 2015#NoXML: Eliminating XML in Spring Projects - SpringOne 2GX 2015
#NoXML: Eliminating XML in Spring Projects - SpringOne 2GX 2015
 
HTML5 Dev Conf - Sass, Compass & the new Webdev tools
HTML5 Dev Conf - Sass, Compass &  the new Webdev toolsHTML5 Dev Conf - Sass, Compass &  the new Webdev tools
HTML5 Dev Conf - Sass, Compass & the new Webdev tools
 
Walk on the Client Side - Chris Mountford
Walk on the Client Side - Chris MountfordWalk on the Client Side - Chris Mountford
Walk on the Client Side - Chris Mountford
 
XXE Exposed: SQLi, XSS, XXE and XEE against Web Services
XXE Exposed: SQLi, XSS, XXE and XEE against Web ServicesXXE Exposed: SQLi, XSS, XXE and XEE against Web Services
XXE Exposed: SQLi, XSS, XXE and XEE against Web Services
 
jAPS 2 0 - Presentation Layer Comparison
jAPS 2 0 - Presentation Layer ComparisonjAPS 2 0 - Presentation Layer Comparison
jAPS 2 0 - Presentation Layer Comparison
 
Web前端性能分析工具导引
Web前端性能分析工具导引Web前端性能分析工具导引
Web前端性能分析工具导引
 
WordPress-Templates mit Twig erstellen - PHPUGFFM
WordPress-Templates mit Twig erstellen - PHPUGFFMWordPress-Templates mit Twig erstellen - PHPUGFFM
WordPress-Templates mit Twig erstellen - PHPUGFFM
 
Even faster web sites presentation 3
Even faster web sites presentation 3Even faster web sites presentation 3
Even faster web sites presentation 3
 
Examining And Bypassing The IE8 XSS Filter
Examining And Bypassing The IE8 XSS FilterExamining And Bypassing The IE8 XSS Filter
Examining And Bypassing The IE8 XSS Filter
 
Pane web & salame 3 - Un bel tagliere di storie dal web
Pane web & salame 3 - Un bel tagliere di storie dal webPane web & salame 3 - Un bel tagliere di storie dal web
Pane web & salame 3 - Un bel tagliere di storie dal web
 
Even faster web sites
Even faster web sitesEven faster web sites
Even faster web sites
 
Web技術勉強会 第19回
Web技術勉強会 第19回Web技術勉強会 第19回
Web技術勉強会 第19回
 

Semelhante a How to configure with Spring an api not based on Spring

Semelhante a How to configure with Spring an api not based on Spring (20)

Having Fun with Play
Having Fun with PlayHaving Fun with Play
Having Fun with Play
 
Os Haase
Os HaaseOs Haase
Os Haase
 
Tomcat + other things
Tomcat + other thingsTomcat + other things
Tomcat + other things
 
Building AOL's High Performance, Enterprise Wide Mail Application With Silver...
Building AOL's High Performance, Enterprise Wide Mail Application With Silver...Building AOL's High Performance, Enterprise Wide Mail Application With Silver...
Building AOL's High Performance, Enterprise Wide Mail Application With Silver...
 
Practical catalyst
Practical catalystPractical catalyst
Practical catalyst
 
Struts Portlet
Struts PortletStruts Portlet
Struts Portlet
 
I Feel Pretty
I Feel PrettyI Feel Pretty
I Feel Pretty
 
Boston Computing Review - Java Server Pages
Boston Computing Review - Java Server PagesBoston Computing Review - Java Server Pages
Boston Computing Review - Java Server Pages
 
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
 
Struts2 - 101
Struts2 - 101Struts2 - 101
Struts2 - 101
 
Configuring jpa in a Spring application
Configuring jpa in a  Spring applicationConfiguring jpa in a  Spring application
Configuring jpa in a Spring application
 
Core Data with Swift 3.0
Core Data with Swift 3.0Core Data with Swift 3.0
Core Data with Swift 3.0
 
JavaScripts & jQuery
JavaScripts & jQueryJavaScripts & jQuery
JavaScripts & jQuery
 
Hackingtomcat
HackingtomcatHackingtomcat
Hackingtomcat
 
Hacking Tomcat
Hacking TomcatHacking Tomcat
Hacking Tomcat
 
Das kannste schon so machen
Das kannste schon so machenDas kannste schon so machen
Das kannste schon so machen
 
Introducing Struts 2
Introducing Struts 2Introducing Struts 2
Introducing Struts 2
 
What's Coming in Spring 3.0
What's Coming in Spring 3.0What's Coming in Spring 3.0
What's Coming in Spring 3.0
 
Servlets 3.0 - Asynchronous, Extensibility, Ease-of-use @ JavaOne Brazil 2010
Servlets 3.0 - Asynchronous, Extensibility, Ease-of-use @ JavaOne Brazil 2010Servlets 3.0 - Asynchronous, Extensibility, Ease-of-use @ JavaOne Brazil 2010
Servlets 3.0 - Asynchronous, Extensibility, Ease-of-use @ JavaOne Brazil 2010
 
Jsp and jstl
Jsp and jstlJsp and jstl
Jsp and jstl
 

Último

+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 

Último (20)

TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 

How to configure with Spring an api not based on Spring

  • 1. HOW TO CONFIGURE WITH SPRING AN API NOT BASED ON SPRING Jose María Arranz Santamaría Madrid (Spain) February 17-18, 2011 1
  • 3. THE PROBLEM • Spring was born as a tool to configure and integrate disparate technologies • We can not always expect such disparate technologies be ready to be configured “out of the box” with Spring This is the thing Spring was invented for! 3
  • 4. THE PROBLEM • ItsNat is a Java web framework with a custom non-Spring configuration system • ItsNat configuration is the most powerful and flexible approach ever invented: Calling methods! • As of day 0 ItsNat configuration was conceived to be “overloaded” with higher level configuration techniques and APIs, for instance… Spring! 4
  • 5. 5
  • 6. DO NOT WORRY THIS IS NOT GOING TO BE AN ItsNat COURSE!  6
  • 7. WE ARE GOING TO LEARN SOME Spring TRICKS 7
  • 8. BUT WE MUST KNOW HOW TO CONFIGURE A WEB PROJECT BASED ON ItsNat TO CONFIGURE IT LATER WITH Spring We will pick the “core” example in the ItsNat Reference Manual 8
  • 9. “PURE” ItsNat EXAMPLE: the servlet • ItsNat does not define a concrete servlet, developer must create one (or more) – Configuration is done in method init • In this example most of configuration is optional, just used to show ItsNat configuration options 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. “PURE” ItsNat EXAMPLE: the servlet • ItsNatHttpServlet, ItsNatServletConfig y ItsNatServletContext are the roots (and singletons) of ItsNat configuration 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. “PURE” ItsNat EXAMPLE: the 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. “PURE” ItsNat EXAMPLE: the 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. “PURE” ItsNat EXAMPLE: the servlet • Now we register in the servlet an ItsNat template core_example.xhtml and associated document loader CoreExampleLoadListener – Just a simple example of HTML page with 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. “PURE” ItsNat EXAMPLE: the servlet • Another example, in this case a page with XML docTemplate = itsNatServlet.registerItsNatDocumentTemplate( "manual.core.xmlExample","text/xml", pathPrefix + "xml_example.xml"); docTemplate.addItsNatServletRequestListener( new CoreXMLExampleLoadListener()); • This XML example inserts an ItsNat “template fragment” – Template fragments have not “loaders/processors” ItsNatDocFragmentTemplate docFragTemplate; docFragTemplate = itsNatServlet.registerItsNatDocFragmentTemplate( "manual.core.xmlFragExample","text/xml", pathPrefix + "xml_fragment_example.xml"); 14
  • 15. “PURE” ItsNat EXAMPLE • <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. “PURE” ItsNat EXAMPLE • CoreExampleLoadListener is just a simple launcher of document processors, called per page loaded public class CoreExampleLoadListener implements ItsNatServletRequestListener { public CoreExampleLoadListener() {} public void processRequest(ItsNatServletRequest request, ItsNatServletResponse response) { ItsNatHTMLDocument itsNatDoc = (ItsNatHTMLDocument)request.getItsNatDocument(); new CoreExampleDocument(itsNatDoc); } } 16
  • 17. “PURE” ItsNat EXAMPLE • CoreExampleDocument manages the page (document) state receiving AJAX events public class CoreExampleDocument implements EventListener { protected ItsNatHTMLDocument itsNatDoc; protected Element clickElem1; protected Element clickElem2; public CoreExampleDocument(ItsNatHTMLDocument itsNatDoc) { this.itsNatDoc = itsNatDoc; load(); } ... 17
  • 19. “PURE” ItsNat EXAMPLE • <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. “PURE” ItsNat EXAMPLE • <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. “PURE” ItsNat EXAMPLE • CoreXMLExampleLoadListener : in this case (XML page) there is no AJAX events, we do not need a class wrapping the document. This example includes the 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. OBJETIVES 1. Build a single reused generic servlet : itsnatspring.itsnatservlet 2. Configuration is fully done in a XML configuration file of Spring in classpath: itsnatex/spring.xml 3. The only user defined Java classes will be the document wrappers/containers: itsnatex.CoreExampleDocument itsnatex.CoreXMLExampleDocument 24
  • 25. CONSEQUENCES • Besides the generic servlet we will need some utility classes also generic and reusable for other ItsNat+Spring projects • These classes are not completed, just to cover the needs of this example – ItsNat has more configuration options 25
  • 26. THE 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. THE 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); } } • ItsNat configuration objects are registered into a generic ApplicationContext (the root), our XML with Spring configuration is loaded by another (child) Spring context 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); } } • ItsNat configuration objects are manually registered as singletons in Spring context 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 • This utility class is used as a singleton to save the specified flags and in the end of bean configuration they are registered calling methods of ItsNatServletContext – Because we need the ApplicationContext we will implement ApplicationContextAware – Because we must to save in ItsNat context our configuration data in the end of bean configuration we need to implement 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 • This “factory bean” allows configuring a Locale and made public calling the “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. • Some other utility classes are very similar to the previous shown, from now we are just to show only the most interesting • From Spring XML you can figure out how they work under the hood – ItsNat singletons are got through ItsNatBeansRegistryUtil and the Spring ApplicationContext – This context is got implementing 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"> <!– backed by a Properties attr --> <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 • This “local singleton bean” is very interesting becase it works like a generic “ItsNat document loader listener” implementing ItsNatServletRequestListener • To be generic we must invent a simple interface ItsNatDocumentInitialize for the document processors/wrappers: 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 • Finally this bean registers the template and the associated “ItsNat document loader listener” configured 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 • With this class the template fragment is registered ... 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. CONCLUSION Can you use Spring to configure “any” API? 52