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
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
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
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
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
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
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
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