El objetivo de este post es crear un proyecto sencillo utilizando los framerworks Java: Sencha GXT, Spring e Hibernate de manera intregrada usando el modelo MVC de la misma forma en que lo hicimos en el blog http://vaadinspringhibernate.blogspot.com/
El código del proyecto lo pueden encontrar en github construido con maven
En este caso también asumimos que ustedes conocen el framework Spring, Hibernate y GWT, además de que Sencha es un framework tipo RIA que esta basado en GWT.
La configuración inicial es similar a la de este post salvo que como esta vez estamos trabajando con maven el archivo pom.xml es como sigue:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ejemplo.sencha</groupId>
<artifactId>com.ejemplo.sencha</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>gxt-basic-public-3x</name>
<description>GXT maven setup</description>
<properties>
<!-- GXT -->
<gxt.version>3.1.1</gxt.version>
<!-- GWT -->
<gwt.version>2.6.1</gwt.version>
<gwt.style>OBF</gwt.style>
<spring.version>3.2.13.RELEASE</spring.version><!-- 3.0.5.RELEASE -->
<version.hibernate>3.5.6-Final</version.hibernate><!--3.5.3-Final-->
<version.slf4j>1.5.8</version.slf4j>
<version.log4j>1.2.14</version.log4j>
<!-- tell the compiler we can use 1.6 -->
<maven.compiler.source>1.6</maven.compiler.source>
<maven.compiler.target>1.6</maven.compiler.target>
<!-- Maven -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<webappDirectory>${project.build.directory}/${project.build.finalName}</webappDirectory>
</properties>
<build>
<outputDirectory>${webappDirectory}/WEB-INF/classes</outputDirectory>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<!-- Skips the GWTTestCases during Junit Testing -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12</version>
<configuration>
<includes>
<include>**/*Test.java</include>
</includes>
<excludes>
<exclude>**/*GwtTest.java</exclude>
</excludes>
</configuration>
</plugin>
<!-- GWT -->
<!-- 'mvn gwt:run' - runs development mode -->
<!-- 'mvn gwt:debug' - runs debug mode -->
<!-- 'mvn gwt:compile' - compiles gwt -->
<!-- 'mvn gwt:test' or 'mvn integration-test' - runs the gwt tests (*GwtTest.java), (run a suite its faster) -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>gwt-maven-plugin</artifactId>
<version>${gwt.version}</version>
<configuration>
<strict>true</strict>
<testTimeOut>180</testTimeOut>
<includes>**/*GwtTestSuite.java</includes>
<excludes>**/*GwtTest.java</excludes>
<mode>htmlunit</mode>
<extraJvmArgs>-Xss1024K -Xmx1024M -XX:MaxPermSize=256M</extraJvmArgs>
<logLevel>INFO</logLevel>
<style>${gwt.style}</style>
<copyWebapp>true</copyWebapp>
<hostedWebapp>${webappDirectory}</hostedWebapp>
<port>8889</port>
<bindAddress>0.0.0.0</bindAddress>
<runTarget>Project.html</runTarget>
<module>com.ejemplo.sencha.Project</module>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Copy static web files before executing gwt:run -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>exploded</goal>
</goals>
</execution>
</executions>
<configuration>
<webappDirectory>${webappDirectory}</webappDirectory>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!-- GXT -->
<!-- http://docs.sencha.com/gxt/3.1/getting_started/maven/Maven.html -->
<dependency>
<groupId>com.sencha.gxt</groupId>
<artifactId>gxt</artifactId>
<version>${gxt.version}</version>
</dependency>
<dependency>
<groupId>com.sencha.gxt</groupId>
<artifactId>gxt-chart</artifactId>
<version>${gxt.version}</version>
</dependency>
<!-- GXT 3.1.0+ - Neptune Theme -->
<dependency>
<groupId>com.sencha.gxt</groupId>
<artifactId>gxt-theme-neptune</artifactId>
<version>${gxt.version}</version>
</dependency>
<!-- GWT -->
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-servlet</artifactId>
<version>${gwt.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-user</artifactId>
<version>${gwt.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-codeserver</artifactId>
<version>${gwt.version}</version>
<scope>provided</scope>
</dependency>
<!-- Testing -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- Spring -->
<!--dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>${spring.version}</version>
</dependency-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.8</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>commons-digester</groupId>
<artifactId>commons-digester</artifactId>
<version>1.7</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!-- Hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${version.hibernate}</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>${version.hibernate}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.0.2.GA</version>
</dependency>
<!-- Driver MYSQL -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.16</version>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>2.0.0</version>
<scope>test</scope>
</dependency>
<!-- Driver PostgreSQL -->
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.1-901.jdbc4</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<artifactId>commons-collections</artifactId>
<groupId>commons-collections</groupId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.4.GA</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${version.slf4j}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${version.slf4j}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${version.log4j}</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>javax.persistence</artifactId>
<version>2.0.3</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa.modelgen.processor</artifactId>
<version>2.2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>jsr250-api</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.8.1</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.0.0.GA</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.0.0.GA</version>
<classifier>sources</classifier>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>The Buzz Media Maven Repository</id>
<url>http://maven.thebuzzmedia.com</url>
</repository>
<repository>
<id>EclipseLink</id>
<url>http://download.eclipse.org/rt/eclipselink/maven.repo</url>
</repository>
</repositories>
</project>
Y para trabajar los RPC de GWT ya no vamos a usar el típico Servlet sino que mapearemos esto con Spring, para lo cual creamos la siguiente clase:
package com.ejemplo.sencha.server.comm;
import java.util.Enumeration;
import java.util.Properties;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;
/**
* Spring Controller implementation that mimics standard
* ServletWrappingController behaviour (see its documentation), but with the
* important difference that it doesn't instantiate the Servlet instance
* directly but delegate for this the BeanContext, so that we can also use IoC.*
*/
public class ServletWrappingController extends AbstractController
implements BeanNameAware, InitializingBean, DisposableBean {
private Class servletClass;
private String servletName;
private Properties initParameters = new Properties();
private String beanName;
private Servlet servletInstance;
public void setServletClass(Class servletClass) {
System.out.print("setServletClass : " + servletClass);
this.servletClass = servletClass;
}
public void setServletName(String servletName) {
System.out.print("setServletName : " + servletName);
this.servletName = servletName;
}
public void setInitParameters(Properties initParameters) {
System.out.print("setInitParameters : " + initParameters);
this.initParameters = initParameters;
}
public void setBeanName(String name) {
System.out.print("setBeanName : " + name);
this.beanName = name;
}
public void setServletInstance(Servlet servletInstance) {
System.out.print("setServletInstance : " + servletInstance);
this.servletInstance = servletInstance;
}
public void afterPropertiesSet() throws Exception {
System.out.print("afterPropertiesSet");
if (this.servletInstance == null) {
throw new IllegalArgumentException("servletInstance is required");
}
if (!Servlet.class.isAssignableFrom(servletInstance.getClass())) {
throw new IllegalArgumentException("servletInstance [" + this.servletClass.getName()
+ "] needs to implement interface [javax.servlet.Servlet]");
}
if (this.servletName == null) {
this.servletName = this.beanName;
}
this.servletInstance.init(new DelegatingServletConfig());
}
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
throws Exception {
System.out.print("handleRequestInternal");
this.servletInstance.service(request, response);
return null;
}
public void destroy() {
System.out.print("destroy");
this.servletInstance.destroy();
}
private class DelegatingServletConfig implements ServletConfig {
public String getServletName() {
return servletName;
}
public ServletContext getServletContext() {
return getWebApplicationContext().getServletContext();
}
public String getInitParameter(String paramName) {
return initParameters.getProperty(paramName);
}
public Enumeration getInitParameterNames() {
return initParameters.keys();
}
}
}
Adicional a lo anterior crearemos un dispatcher con spring el cual ya debe estar definido en el web.xml y el contenido del archivo springrpc-servlet.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"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<context:annotation-config />
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="urlMap">
<map>
<entry key = "GWTService">
<ref bean="ServiceControllerGWTService" />
</entry>
</map>
</property>
</bean>
<bean id="ServiceControllerGWTService" class="com.ejemplo.sencha.server.comm.ServletWrappingController">
<property name="servletName" value="GWTService"/>
<property name="servletInstance">
<ref bean="GWTService"/>
</property>
</bean>
<bean id="GWTService" class="com.ejemplo.sencha.server.GWTServiceImpl"> </bean>
</beans>
Aparte de lo anterior las clases que se usan en el RPC siguen teniendo la misma estructura y ya no hace falta la notación @RemoteServiceRelativePathComo se mencionó antes este post esta basado en el blog acerca de vaadin por lo que el modelo de datos es el mismo y los servicios spring también.
Como ya deben saber a la hora de ejecutar proyectos en GWT existe la opcion dev-mode y hosted-mode el cual explican más claramente acá. Para correr en dev-mode este proyecto en netbeans teniendo en cuenta que esta construido con maven, se hace click derecho sobre el proyecto y se escoge la opción GWT dev mode como primera instancia y luego en la consola nos sale algo como "Listening for transport dt_socket at address: 8000", luego de esto vamos al menú "Debug" y ejecutamos la opción "Attach debuger", lo que nos mostrará una ventana como la que sigue:
https://github.com/juliandresog/SenchaGXTEjemplo.git
Visita también
https://joarchitectus.wordpress.com
https://joarchitectus.wordpress.com/2018/03/23/sencha-extjs-ajax-request-rest-json/
No hay comentarios:
Publicar un comentario