Canigó - FAQ Canigó 2.3.x
FAQ CANIGÓ 2.3.xPreguntes ComunsErrors en Arrencar l'AplicacióError creating bean with name 'sessionFactory'...Problema Si apareix un missatge com el mostrat a continuació: Solució En general, aquest problema és degut a que no s'ha definit correctament el datasource al Servidor. Cada servidor té la seva forma particular de definir el datasource. En el cas de fer ús de Tomcat, podem incorporar al fitxer 'server.xml' el següent codi: Dins el tag 'Context' de l'aplicació afegir un 'Resource' per definir la connexió a la font de dades. Exemple: <Context docBase="D:\Users\xescuder\Projectes\canigo-samples-jPetstore\.deployables\canigo-samples-jPetstore" path="/canigo-samples-jPetstore" reloadable="true"> <Resource name="canigoDS" auth="Container" type="javax.sql.DataSource"/> <ResourceParams name="canigoDS"> En Eclipse podem accedir a aquest fitxer des de la carpeta 'Servers>Nom Servidor'. Bean context must contain at least one bean of type net.sf.acegisecurity.util.FilterChainProxyProblema javax.servlet.ServletException: Bean context must contain at least one bean of type net.sf.acegisecurity.util.FilterChainProxy Si fas F5 canviarà el missatge a: java.lang.NullPointerException Solució Aquest missatge apareix perquè s'ha definit el filtre del Servei de Seguretat de la classe 'net.sf.acegisecurity.util.FilterToBeanProxy'. <filter> En cas de que no es vulgui activar la seguretat comentar aquest filtre i el seu filter-mapping associat. Si es vol activar la seguretat realment ens hem d'assegurar que:
El Servei de Seguretat defineix alguns beans de configuració dins el jar desplegat. Ara bé, per tal que aquests siguin carregats hem de definir la seva importació en els nostres fitxers de configuració: <import resource="classpath:/spring/acegi-beans.xml" /> Apareix el missatge 'Usuari o password incorrecte' però crec que està tot correctament configuratProblema El presentat en el títol. Solució Aquest problema es pot donar si no s'han incorporat els fitxers de càrrega de hibernate necessaris pel Servei de Seguretat. Seguir els següents pasos:
<beans>
sessionFactory.configLocation=hibernate/config/hibernate.cfg.xml
<mapping resource="hibernate/mappings/UserLogin.hbm.xml" /> Aquestes referències són necessàries pel Servei de Seguretat. Els fitxers es troben dins el jar de 'canigo-services-security'. Apareix el missatge 'ClassCastException... TilesRequestProcesso.initDefinitionsMapping'Problema
Solució Cal definir el plugin de Tiles i la ruta a la definició de les pantalles:
Problemes en EclipseObrir un fitxer tarda moltíssim i es queda el sistema com aturatAquest comportament és degut a la configuració del proxy que valida els fitxers. Accedir a l'opció 'Window>Preferences' i seleccionar el node 'Internet>Proxy Settings'. Si per accedir a la Web es fa ús d'un Proxy configurarem els seus valors, en cas contrari desmarcar 'Enable proxy': + On trobo les traces del Servidor Tomcat?Podem accedir a les traces d'arranc de Tomcat per veure si hi ha algun problema a la carpeta '\.metadata\.plugins\org.eclipse.wst.server.core' del workspace utilitzat. Dins aquesta carpeta escollir el subdirectori 'tmpX' corresponent al servidor i accedir al directori 'logs'. He fet canvis a un fitxer però sembla que no es reflecteixen en l'execucióEl directori '.deployables' és el directori que utilitza Tomcat en els desplegaments. Si hem fet un canvi a un fitxer dins l'estructura arrel de src, primer de tot ens assegurarem que s'ha copiat correctament al subdirectori '.deployables'. Si no s'ha copiat a '.deployables' hem d'assegurar-nos de que al fitxer .classpath (a l'arrel del projecte) tenim el següent contingut: <classpathentry output=".deployables/WEB_NAME/WEB-INF/classes" kind="src" path="src/main/java"/> On WEB_NAME correspon al subdirectori dins de deployables que correspon a l'aplicació. Unsupported major.minor version 49.0BUILD FAILED Window>Preferences. Canviar 'Java Home' per a que apunti al j2sdk1.4.2_09. Assegurar-se al node 'Java>Installed JREs' que tenim seleccionat per defecte 'JDK1.4.2'. Des del Panel de Control>Sistema assegurar-se que la variable d'entorn apunta al JSDK1.4.2
Problemes amb Maven a EclipseQuan es descarreguen les dependències de llibreries dóna ConnectionTimeOutProblema En executar algun goal per descarregar les dependències definides al fitxer 'project.xml' dóna problemes de connexió o es queda bastant temps aturat. La seva resolució normalment depén de la xarxa utilitzada però en la majoria de casos esdevé mitjançant la configuració del proxy a Internet. Solució En cas de que es faci servir proxy de connexió a Internet, podem definir que es faci ús del proxy amb els següents pasos:
Exemple : maven.proxy.host=10.49.1.1 Si una vegada aplicats els canvis apareix un missatge com el mostrat a continuació: Intentando descargar jdtcore-3.1.0.jar. Cal afegir les variables 'maven.proxy.username' i 'maven.proxy.password'. * Consultes / incidències diversesEn l'aplicació les modificacions de la BD les fem en un ordre i en canvi per la consola es veuen en ordre invers, provocant un error a la BD del tipus DataIntegrityViolationException.Problema El descrit a la pregunta Solució Aquest error es deu a l'ordre en el qual hibernate persisteix els canvis realitzats en els objectes persistents sobre la BD. Podem trobar informació sobre aquest procediment al següent link:
http://www.hibernate.org/hib_docs/v3/reference/en/html_single/#objectstate-flushing Per exemple, si tenim el següent codi dintre d'un mètode d'un DAO:
provocará una excepció del tipus org.springframework.dao.DataIntegrityViolationException Això es deu a que l'ordre en el qual es persisteixen els canvis és el següent (està més detallat al link anterior):
La solució a aquest problema consisteix en forçar un flush després de fer el delete. És a dir:
Important: no cal confondre el flush amb un commit. El flush no fa commit, simplement volca els canvis sobre la BD però no els fa persistents. Per tant un rollback donaria marxa enrera als canvis. Com podem fer servir sentències SQL en lloc de HQL als llistats de l'aplicació, si per a generar els llistats fem servir el servei de llistats?Problema Volem fer servir sentències SQL per a obtenir les dades pels llistats generats via la llibreria Valuelist. Solució Sabem que el servei de llistats de canigo es fonamenta en la llibreria open source Valuelist (http://valuelist.sourceforge.net ). Els motius que podem fer-nos fer servir SQL en lloc de HQL són molt diversos:
En el cas que volguem fer servir SQL en lloc de HQL, l'únic canvi que hem de fer és a nivell de configuració, ja que la JSP no sap en cap moment de quina font provenen les dades que està renderitzant. Els canvis a fer són els següents:
Modificació del fitxer canigo_-services-web-list.xml_ La modificació a fer en aquest fitxer consisteix a definir una entrada dintre de l'apartat de config.adapters corresponent a la nostra consulta. L'única diferència important respecte a la resta d'entrades és l'adapter que es fa servir, que no correspon a l'adapter baseHibernateAdapter típic de les consultes HQL __sinó a un nou adapter. Aquí podem veure un exemple:
Com podem veure, definim un adaptador de tipus DefaultWrapperAdapter, al qual li hem d'indicar quin dataSource farà servir per a obtenir les conexions a la BD, li configurem els paràmetres típics de tot llistat: nombre d'elements per pàgina, columna d'ordenació per defecte, ..., li indiquem la consulta SQL i per últim, li indiquem quina classe ha de fer servir per a fer el mapeig del resultset a objectes Java. En aquest cas li hem indicat una referència a un bean de nom accountWrapper, la definició del qual és la següent (la podem ficar dintre del mateix fitxer de configuració):
Respecte a la referència al dataSource, en el fitxer canigo_-services-persistence.xml_ podem tenir definit el següent bean (mateix funcionament que un look up mitjançant un ServiceLocator):
Definició de la classe wrapper Hem de definir un mecanisme que ens permeti llegir les dades del resultset I encapsular-les en un objecte Java per tal de que siguin afegides al llistat del value list. A continuació podem veure la implementació de AccountWrapper: en aquest cas el que fem és traspassar les dades del resultset a un objecte Account (el mateix pojo que tenim definit al petStore). Podem optar per aixecar completament el pojo o només informar aquelles columnes a les quals es fa referència al llistat. En aquest exemple s'ha optat per la segona alternativa, però és recomanable optar per la primera ja que futures modificacions sobre la presentació del llistat (per exemple afegir més informació) no implicarien modificar el wrapper.
Fixem-nos que el nostre wrapper ha d'implementar la interficie net.mlw.vlh.adapter.util.ObjectWrapper. Com ja s'ha comentat, el mètode getWrappedRecord ha de retornar l'objecte java que serà afegit al llistat del value list. Aquest mètode rep com a paràmetre el registre del Resultset a llegir, per tant no hem de fer cap iteració sobre aquest. Per últim, el fet de fer servir la posició de la columna en lloc del nom de la columna és merament anecdotic. Es pot fer servir qualsevold e les dos alternatives. Podem trobar més informació a la següent adreça: Com puc implementar la cerca aproximada mijançant LIKE a les consultes associades als llistats? Com puc fer cerques case insensitive?Problema Volem implementar a les nostres consultes dels llistats la funcionalitat de cerca LIKE i case insensitive de SQL. Solució A continuació podem veure un exemple en el qual es fa la cerca aproximada respecte a l'atribut firstname del pojo account. En aquest exemple també podem veure un exemple de cerca aproximada i sense considerar majuscules i minúscules sobre l'atribut lastname.
Com podem canviar els controls de navegació en els llistats per tal de que en lloc d'imatges siguin botons?Problema El descrit a la pregunta. Solució La configuració d'aquestes imatges la trobem definida als fitxers de recursos de l'aplicació (generalment els tindrem dintre del directori resources/i18n). En aquests fitxers tenim definides les següents entrades:
Aquestes definicions són les que fa servir el value list per a generar tota la part de paginació (dintre del fitxer valuelist.tld, si cerquem l'entrada showSumary podem trobar quina és l'estructura del codi de la paginació). Per tant, si volem modificar les imatges que fem servir per a navegar pel llistat només haurem de modificar les definicions anteriors. I si en lloc d'imatges volem fer servir botons el que s'ha de fer és canviar el codi HTML associat al fitxer de recurs per a cada entrada (en lloc del tag img fer servir el tag input, per exemple). Per exemple, si definim el següent codi al fitxer de recursos:
Obtenim Es recomana mirar-se el fitxer valuelist.tld per a veure més propietats de la generació de llistats mitjançant value list. Com puc mostrar més de un llistat en una pàgina fent servir el servei de llistats?Problema El descrit a la pregunta Solució Anem a mostrar un exemple en el qual es mostren per pantalla dos llistats: un de comptes i un altre de categories. Per a cadascun dels llistats limitarem la seva secció mitjançant el tag i per a distingir cadascun d'aquests haurem de definir un identificador per a cadascun d'ells: Aquest identificador es fa servir per a identificar a quin llistat pertany els camps de paginació o ordenació. La clau del procés està en fer servir el tag <vlh:retrieve name="id_de_consulta"> que ens permet associar a cadascun dels llistats una consulta definida en el fitxer de configuració. El següent codi JSP (només ens mostra la part realment important):
ens genera la següent sortida per pantalla: Per a aquest exemple s'ha fet servir butons per a la paginació en lloc d'imatges (tal i com s'ha explicat en una pregunta anterior). Important Aquest mecanisme de generació de llistats té el handicap de que no fa servir els paràmetres que estiguin a la sessió, i per tant no té 'memòria' de l'estat anterior. Com puc generar un llistat amb el servei de llistats on la consulta HQL estigui formada per una JOIN i per pantalla es mostri informació de tots els objectes que conformen la JOIN?Problema El descrit a la pregunta. Solució Anem a veure un exemple de consulta HQL amb una JOIN, i com indicar a la JSP la informació que volem mostrar. Per a fer servir aquesta funcionalitat el primer que cal fer és actualitzar-se les llibreries del framework canigo_-services-core_ i canigo_-services-web_ a la versió 1.0.1-SNAPSHOT. Per a veure l'exemple, agafem la següent consulta HQL (la qual tenim definida dintre del fitxer canigo_-services-web-list.xml_):
Podem veure que tenim definida una JOIN entre Account i Product. En la pàgina JSP l'únic que hem de fer per a recuperar informació d'un objecte o de l'altre és fer servir la següent sintaxis: nom_del_bean.array[posicio].propietat on Per exemple, en aquest cas tindriem:
que ens genera el següent llistat: L'exportació dels llistats a PDF i Excel només m'exporta la primera pàgina.Problema El descrit a la pregunta Solució Aquest problema ha estat solucionat a partir de la versió 1.0.1-SNAPSHOT de la llibreria canigo_-services-web.jar_ El comportament que es segueix ara és el següent:
Com podem modificar els paràmetres de cerca que rep el servei de llistats de la Request?Problema L'objectiu és o bé afegir més paràmetres de filtre a la cerca dels llistats o bé modificar els paràmetres que venen a la request. Solució A partir de la versió 1.0.1-SNAPSHOT de la llibreria canigo_-services-web.jar_ està disponible una nova funcionalitat que permet modificar els paràmetres de cerca que rep el servei de generació de llistats, o be afegir més paràmetres de cerca. L'únic que cal fer és informar una Map amb els paràmetres que volem fer servir a la cerca, abans de fer la crida al mètode search del valueListActionHelper del nostre client. Per exemple, supossem que volem que a totes les cerques que es facin es tingui en compte un paràmetre de nom idioma el qual no serà informat per pantalla sinó que serà informat segons certa casuistica de negoci. Aleshores, el que farem serà el següent:
Fixem-nos que el hem de fer es ficar un attribute a la request de nom Si en aquesta Map existeix un paràmetre amb el mateix nom que un dels paràmetres de cerca de la request, aleshores en el moment de fer la cerca el valor que s'agafarà és el de la Map. És a dir, els valors de la Map tenen preferència respecte als de la Request. Això ens permet modificar els valors informats per l'usuari al filtre de cerca. Com podem afegir nous parametres de cerca per a les consultes que retornen les dades de les combos?Problema Idem a l'anterior. Solució L'objectiu d'aquest punt és com podem informar nous paràmetres de cerca de les consultes associades a les combos (o Selects), els quals no venen informats des de el formulari. És a dir, són paràmetres de cerca que no venen informats a la request. La idea és fer servir el mateix mecanisme descrit a la faq anterior, però en aquets cas el nomd e la Map és diferent. En lloc de ser ValueListActionHelper.VALUE_LIST_FILTERS_ATTRIBUTE_NAME hem de fer servir VlhOptionListSourceImpl.VALUE_OPTION_LIST_FILTERS_ATTRIBUTE_NAME Per exemple, imaginem que tenim una combo en les quals les dades han de sortir filtrades per un paràmetre idioma que ha de ser informat des de l'aplicació i no per l'usuari. La consulta que tenim associada a aquesta select és la següent:
En aquest cas, el paràmetre category serà informat des de el formulari de dades i el paràmetre idiomaAp haurà de ser informat des de l'aplicació. Per tal d'informar aquest paràmetre, des del mètode corresponent de l'action que s'encarregui de gestionar la petició, tindrem el següent codi:
Amb això el que estem fent és indicar que la llista de paràmetres de cerca de aplicar a la consulta ve donada per: Els paràmetres de la Map informada a l'Action. És important tenir en compte el següent: si a la Map i a la request tenim dos paràmetres amb el mateix nom, alhora de generar la llista de paràmetres de cerca que s'aplicarà a la consulta, el valor del paràmetre a la request és el que s'aplicarà al final. És a dir, els valors dels paràmetres a la request predominen respecte als valors de la Map en cas de coincidència en els noms. Com puc implementar el meu propi custom editor?Problema El descrit a la pregunta Solució Anem a explicar amb un exemple com podem implementar un custom editor per a un tipus especific de dades. En el nostre cas la dada que volem formatejar és un número de compte bancari, el qual per pantalla és informat per l'usuari en un camp de text i en canvi al nostre objecte de negoci la dada queda representada per un objecte de tipus CompteBancari, el qual té com a atributs: entitat bancaria, oficina, dígits de control i número de compte. L'entitat CompteBancari ve representat per la següent pojo:
I al nostre objecte de negoci tindrem un atribut de tipus CompteBancari:
El primer pas a fer es generar la classe custom editor. Aquesta classe ha d'extendre de java.beans.PropertyEditorSupport. I l'altra condició que ha de complir és redefinir el comportament del mètode setAsText. En el nostre cas, tindrem la següent classe:
Fixem-nos que el que fem és formatejar la dada que ens ve com a paràmetre a un objecte de tipus CompteBancari. Al final fem la crida a setValue(***) que modifica el valor del paràmetre que estem editant (compteBancari en aquest cas). Altra mètode interessant d'implementar és el getAsText, el qual ens permetrà indicar de quina manera s'ha de formatejar l'objecte quan sigui mostrat per pantalla. Per exemple. Un cop tenim el custom editor definit, l'únic que cal fer és registrar-lo dintre de la llista de custom editors de l'aplicació. En el cas del framework, aquesta tasca es fa al fitxer spring/property-editors.xml. Haurem d'afegir:
on la key de la entry correspon al tipus d'objecte al qual volem associar un custom editor, i el valor de l'entrada correspon al custom editor a associar. Com puc generar un desplegable amb les dades d'una taula mestre?Problema Volem generar un desplegable amb el framework i no sabem com fer-ho. Les dades a mostrar provenen d'una taula mestre. Solució Els passos a seguir per a generar un desplegable a partir de les dades d'una taula mestre són els següents:
Per a descriure cada pas anem a definir un desplegable amb les dades de Categories. Definir la consulta HQL i configurar el bean del desplegable La definició d'aquesta consulta HQL l'hem de fer al fitxer La modificació que hem d'afegir al fitxer és la següent:
Podem veure que hi ha definits 3 beans: P En aquest pas, dintre de la propietat config.adapters del bean hem d'afegir l'entrada corresponent a la sentència HQL que correspon a com recuperar les dades del nostre desplegable. e En aquest pas definim un bean que representa al nostre desplegable: indiquem quina consulta es farà servir (optionListName), quin serà l'identificador de cada element del desplegable (optionLabelProperty) i quina serà l'etiqueta que es mostrarà per a cada element (optionLabelName). ) Per últim, afegim el bean definit en el pas anterior a la llista de beans disponibles per a generar un desplegable. El nom amb el qual el registrem dintre d'aquest llistat es com l'haurem de referenciar després. Definir els atributs de visualització del desplegable Aquest pas implica modificar el fitxer spring/action-servlet-xxx.xml associat al formulari on volem afegir el desplegable. Dintre de la propietat tags.configuration del bean corresponent a la nostra acció, afegirem (a la entrada on ens interessi):
Fixem-nos que el nom indicat a e coincideix amb el definit en el pas anterior. Afegir el tag a la JSP Aquest darrer pas simplement significa afegir el següent codi:
Error amb les connexions amb Tomcat: Socket closedProblema L'aplicació ens retorna el següent error: java.sql.SQLException: Excepción de E/S: Socket closed Solució Depenent de la configuració que tinguem al nostre Datasource, pot ser que al demanar una connexió a aquest i executar qualsevol consulta ens retorni un missatge d'error on podem trobar la següent causa: java.sql.SQLException: Excepción de E/S: Socket closed Aquest error es produeix quan el datasource està retornant a l'aplicació una connexió que ja no és valida. Per tal d'evitar aquest comportament del Datasource, els servidors d'aplicacions implementen un mecanisme alhora de definir un datasource que permet validar l'estat de la connexió abans de ser assignada a un client. En particular el que es fa és que abans de lliurar la connexió a un client, s'executa una consulta fent servir la connexió: si la consulta retorna resultats, aleshores la connexió és valida, i sinó retorna resultats o dóna errors, la connexió és rebutja i s'agafa una altra per a lliurar-la al client. En el cas particular del AS Tomcat, aquesta validació s'ha d'afegir a la configuració del DS que fem al fitxer server.xml (sempre hi quan tinguem la configuració del DS via el servidor). El codi a afegir és el següent:
> Aquest paràmetre correspon a la consulta que volem que s'executi per a validar la connexió. Es recomana fer servir aquesta o SELECT 1 FROM DUAL. Exemple d'invocació client-servidor mitjançant AJAXProblema El descrit a la pregunta. Solució L'objectiu d'aquest document és donar un exemple d'ús d'AJAX. En particular, anem a veure com implementar un filtre per a les combos (o selects), de tal manera que l'usuari pugui filtrar el contingut d'aquestes simplement introdunt paraules de filtrat. Els passos a seguir són els següents:
Modificar consulta HQL La consulta HQL de la nostra combo serà la següent (li hem afegit el criteri de cerca nom)
Definir classe Java La única condició que ha de seguir aquesta classe és que implementi la interface java.io.Serializable. En el nostre cas, volem que implementi un mètode que rebi el nom del llistat associat a la select i el paràmetre de cerca, i retorni un llistat amb els elements de la combo que verifiquin la condició de filtre. Com la gestió de les combos al framework es delega al servei de llistats, aquesta classe té definit un atribut de tipus OptionsListService, que es correspondrà al bean que hi ha definit al fitxer de configuració canigo_-services-web-list-options.xml_. A continuació es mostra el codi de la classe:
Un cop hem definit la classe, hem de registrar un bean dintre d'Spring que ens permeti injectar el valor de l'atribut. Per fer això, definim el següent bean (una recomanació d'on registrar aquest bean pot ser al fitxer account-servlet-xxx.xml associat a l'acció):
Definir la classe dintre del fitxer de configuració de DWR En aquest pas el que hem de fer és afegir dintre del fitxer de configuració de DWR la referència a la nostra classe (aquest fitxer indica quines classes pot crear i invocar DWR de manera remota des de javascript). El codi a afegir-hi al fitxer /resources/dwr/dwr.xml és:
El paràmetre javascript correspon al nom mitjançant el qual farem referència al bean des de el nostre codi javascript. Provar la implementació Per a provar que tots els passos anteriors els hem fet bé, simplement hem d'iniciar el servidor i anar al següent enllaç (al fitxer web.xml és on tenim definida que totes les peticions del tipus /AppJava/dwr/* siguin gestionades pel servlet de DWR):
host:port/YOUR\-WEBAPP/AppJava/dwr/" title="Visit page outside Confluence" rel="nofollow"linktype="raw" linktext="http://host:port/YOUR\-WEBAPP/AppJava/dwr/">host:port/YOUR\-WEBAPP/AppJava/dwr/" title="Visit page outside Confluence" rel="nofollow"linktype="raw" linktext="http://host:port/YOUR\-WEBAPP/AppJava/dwr/">host:port/YOUR\-WEBAPP/AppJava/dwr/" title="Visit page outside Confluence" rel="nofollow"linktype="raw" linktext="http://host:port/YOUR\-WEBAPP/AppJava/dwr/">host:port/YOUR\-WEBAPP/AppJava/dwr/" title="Visit page outside Confluence" rel="nofollow"linktype="raw" linktext="http://host:port/YOUR\-WEBAPP/AppJava/dwr/">host:port/YOUR\-WEBAPP/AppJava/dwr/" title="Visit page outside Confluence" rel="nofollow"linktype="raw" linktext="http://host:port/YOUR\-WEBAPP/AppJava/dwr/">host:port/YOUR\-WEBAPP/AppJava/dwr/" title="Visit page outside Confluence" rel="nofollow"linktype="raw" linktext="http://host:port/YOUR\-WEBAPP/AppJava/dwr/">host:port/YOUR\-WEBAPP/AppJava/dwr/" title="Visit page outside Confluence" rel="nofollow"linktype="raw" linktext="http://host:port/YOUR\-WEBAPP/AppJava/dwr/">host:port/YOUR\-WEBAPP/AppJava/dwr/" title="Visit page outside Confluence" rel="nofollow"linktype="raw" linktext="http://host:port/YOUR\-WEBAPP/AppJava/dwr/">host:port/YOUR\-WEBAPP/AppJava/dwr/" title="Visit page outside Confluence" rel="nofollow"linktype="raw" linktext="http://host:port/YOUR\-WEBAPP/AppJava/dwr/">http://host:port/YOUR\-WEBAPP/AppJava/dwr/ Haurem de veure una pantalla semblant a la següent: Si tot a anat bé, a la llista de classes conegudes per DWR ha de sortir la que hem definit prèviament. Si ara clickem sobre l'enllaç de la nostra classe, veurem la següent pantalla: En aquesta pantalla podem veure tots els mètodes de la classe que podem invocar des de javascript. I a més, podem provar la seva invocació des d'aquí. Per exemple, anem a provar si la implementació que hem fet del mètode getOptionList és correcta. Per a això, informem els dos paràmetres d'entrada amb els valors "categoriesList" i "ca", i polsem el botó execute (ens ha de retornar tota la llista de categories que comencen per ca, aplicant ignoreCase). Obtenim: tal i com esperavem. Un cop hem validat el funcionament, el que hem de fer és seguir les indicacions que ens dóna DWR al començament de la pantalla: hem d'afegir 3 fitxers js a la nostra aplicació. Dos d'ells ja els tenim: engine.js i util.js (s'afegeixen amb el tag del framework fwk:configuration). I respecte al tercer fitxer, simplement hem de copiar la línia que aparaeix per pantalla <script type='text/javascript' src='/canigo-formacio/AppJava/dwr/interface/optionsUtil.js'></script> i afegir-la a la nostra JSP (aquest js el genera DWR de manera dinàmica a l'iniciar el servidor). _ L'únic que queda ja per fer és implementar el codi javascript a la nostra JSP. En aquest cas el que volem es que quan es produeixi l'event onKeyPress sobre la nostra select, aquesta es recarregui mostrant només els elements que comencen per la cadena de caràcters introduïda per l'usuari. Per tant, les modificacions a la JSP són 3: Afegir la llibreria JS
Afegir els events que volem controlar a la definició de la select
En aquest cas, capturem els events onKeyPress més els events onblur i onclick, els quals fan una crida a una funció js que inicialitza les variables js que controlen el procés. Afegir codi javascript El codi a afegir-hi és:
La part important d'aquest codi són les funcions recarrega i ompleLlista. La primera és la que s'encarrega de fer la petició al servidor. Fixem-nos que fa una petició a un mètode que té 3 paràmetres: els dos primers corresponen als paràmetres que nosaltres hem definit a la nostra classe Java. I el tercer? El tercer correspon a la funció js a la qual ha de cridar quan rebi la resposta del servidor. Això es deu al fet a que la comunicació amb el servidor és asincrona i per tant li hem d'indicar per on ha de continuar.... La segona funció és la que rep l'array de dades retornada pel servidor i s'encarrega d'omplir la select amb les noves dades. En aquest cas fa ús de crides a funcions js que ja venen implementades dintre de DWR (llibreria util.js). Amb tot això ja podem provar l'exemple: simplement ens hem de posicionar a la select i teclejar la paraula per la qual volem que filtri (les tecles polsades no es veuen per pantalla...). A continuació podem veure el resultat d'executar l'exemple anterior. Inicialment tenim la següent select: Si ara ens situem sobre la select i polsem 'ca' el resultat és: Com modificar el comportament de la gestió d'errors que té DWR?Problema Solució Això es deu a que per defecte DWR té definida la següent instrucció al fitxer engine.js
És a dir, està indicant que qualsevol error ha de ser gestionat per la funció js defaultMessageHandler, el codi de la qual és:
Si a la nostra aplicació volem definir un gestor diferent pels errors, l´'unic que hem de fer és indicar quina funció ha de ser el nou gestor. I això ho farem amb la següent crida al nostre codi:
On nom_de_la_funcio és una funció javascript que tindrem definida, per exemple:
_ Com puc afegir un CustomEditor per les dades de tipus Number?Problema Solució En concret, hem d'afegir el següent codi:
On Correspon al tipus de dades que volem tractar. Ha de ser una classe de tipus Number. _ Problemes amb els elements enllaçats o depenentsProblema L'enllaçament d'elements no funciona. Solució A la nostra plana tenim elements enllaçats de tal manera que quan es modifica el valor d'un és recarrega el valor de l'altre. Per exemple, tenim dos selects selectA i selectB, i quan modifiquem el valor de la selectA es recarrega el valor de la selectB, és a dir el valor seleccionat a la selectA ens permet filtrar els elements de la selectB. Si hem implementat aquesta funcionalitat i veiem que no ens funciona, podem validar els seguents aspectes de la implementació. Definició de la dependència correcta Al fitxer action-servlet-xxx.xml , on tinguem definida la dependència, hem de tenir definida la relació de la següent manera:
> Aquesta propietat ens diu que aquesta select té una dependència d'un altre element, Definició de la consulta que ens retorna els valors de la selectB En aquest cas haurem de validar que la consulta que ens retorna els valors de la selectB està ben definida i té com paràmetre de filtre l'element que ens ve de la selectA. Per exemple, en el nostre exemple aquesta consulta correspon a:
Podem observar que aquesta consulta té un paràmetre de filtre de nom category, el qual ha de Implementació correcta a la JSP L'ordre en el qual han d'apareixer els elements a la nostra plana JSP ha de ser el mateix ordre jeràrquic de la dependència, sinó la dependència no funcionarà. És a dir, al nostre exemple, a la JSP els elements han d'estar implementats en el següent ordre:
La raó per la qual deixa de funcionar la podem resumir en el següent: en el moment en el qual es renderitza el component JSP depenent, es valida que existeixi l'element html del qual depèn, i sinó existeix no es modifica el comportament de l'event onchange, i per tant els valors de la selectB no es recarreguen al modificar la selectA. Podem mirar el codi següent al js canigo_-ajaxtags-select.js_
_ Més d'un formulari en una mateixa JSP.Problema Definir més d'un formulari dins d'una mateixa JSP. Solució Haurem de seguir els següents passos: 1-Primerament haurem d'actualitzar dos fitxers a la release 1.0.8 o superior: - canigo_-services-web-1.0.8.jar_ 2-Definirem les validacions dels formularis en el fitxer validation.xml per separat. En l'exemple que detallem definim 2 formularis: <form-validation> <formset> <form name="accounts1"> <field property="preferredCategory.id" depends="required"> </form> <form name="accounts2"> </formset> 3-Dins del fitxer action-servlet-xxx.xml definirem un formTag per cada formulari: ... <bean parent="formTag"> </bean> Dins de validationProperties definirem les següents propietats: - validationType: tipus de validació .Els possibles valors són CLIENT/SERVER. 4- En la JSP definirem els formularis amb el seu corresponent styleId (corresponent al definit dins del seu formTag de action-servlet-xxx.xml): <fwk:form action="editAccount.do" styleId="actionForm" reqCode="edit" width="500" method="post" styleClass="edit"> ... <tr> </fwk:form> <fwk:form action="editAccount.do" styleId="actionForm2" reqCode="edit" width="500" method="post" styleClass="edit"> ... _ Eliminar col.lumnes d'un llistat a l'exportar a excel o pdf.Problema Eliminar columnes d'un llistat a l'exportar a excel o pdf. Poder eliminar columnes per títol de la columna o per index de la columna. Solució Eliminar columnes per títol de columna: Dins del fitxer canigo-services-web-lists.xml hi trobem el bean de configuració del valuelist (ValueListConfigBean). Aquest bean conté els displayProviders ExportPdf i ExportExcel. Aquests beans tenen una propietat que es diu skipColumns. Aquí haurem d'introduïr el titleKey de la columna que volem ignorar a l'exportar (tant a pdf com a excel): <entry key="ExportPDF"> Eliminar columnes per index de columna: Per eliminar columnes pel seu index, haurem de configurar-ho en la Action que fa l'export: public ActionForward searchExportPDF(ActionMapping mapping, ActionForm form, List skipColumnNumbers = new ArrayList(); request.setAttribute(PdfDisplayProvider.SKIP_COLUMN_NUMBERS,skipColumnNumbers); request.setAttribute("displayProvider","ExportPDF"); return this.search(mapping,form,request,response); public ActionForward searchExportExcel(ActionMapping mapping, ActionForm form, List skipColumnNumbers = new ArrayList(); request.setAttribute("displayProvider","ExportExcel"); return this.search(mapping,form,request,response); En l'exemple anterior, a l'exportar tant a pdf com a excel, estariem ignorant les columnes primera i tercera. _ Més d'una ValueList en una mateixa JSP.Problema Configurar una aplicació per poder mostrar més d'una ValueList en una mateixa JSP. Solució Els passos a seguir són els següents: - Dins del fitxer action-servlet-xxx.xml, definir un Map d'objectes ValueListActionHelper, amb una clau que servirà per identificar cada ValueListActionHelper: <bean name="/accounts" parent="accountBaseDefinition"> Per a cada ValueListActionHelper haurem de definir, a part de les que ja informavem (listName i tableId), les propietats )listAttributName (nom de la valuelist) i id (id de la valuelist). - Dins l'Action definirem el Map d'objectes ValueListActionHelper i recuperarem els que necessitem per fer les búsquedes: private Map valueListActionHelperMap; ... public ActionForward search(ActionMapping mapping, ActionForm form, ValueListActionHelper valueListActionHelperAccounts = (ValueListActionHelper)valueListActionHelperMap.get("accounts"); ValueListActionHelper valueListActionHelperCategories = (ValueListActionHelper)valueListActionHelperMap.get("categories"); FormUtils.setFormDisplayMode(request, form, FormUtils.EDIT_MODE); return mapping.findForward("success"); - En la JSP definirem les diferents valuelists posant com a name el nom que haguem definit en la propietat listAttributeName i id que també haguem definit en la propietat id dins l'action-servlet-xxx.xml: <fwk:vlhroot fvalue="list" "id="valuelist1" url="accounts.do?" includeParameters="reqCode" configName="vlConfig"> <vlh:root value="list2" id="valuelist2" url="categories.do?" includeParameters="reqCode" configName="vlConfig"> - Exemple de JSP complet: <%@ include file="/WEB-INF/jsp/includes/fwkTagLibs.jsp" %> <fwk:vlhroot value="list" id="valuelist1" url="accounts.do?" includeParameters="reqCode" configName="vlConfig"> <table width="450" align="center" border="0"> <vlh:attribute name="onmouseover">this.className='selected';</vlh:attribute> </fwk:vlhrow> </fwk:form> </fwk:vlhroot> Posicionament botó de calendari.Problema El botó del calendari no apareix en la posició desitjada. Solució Per modificar qualsevol propietat del botó del calendari, podem fer-ho directament amb estils (css), tenint en compte que el botó es crea automàticament sota la classe 'calendarImageClass'. Així, per modificar, per exemple, la posició del botó, podem for-ho de la següent manera: .calendarImageClass{ Posicionament botó de select paginat (pagedSelect).Problema El botó del select paginat no apareix en la posició desitjada. Solució Per modificar qualsevol propietat del botó del calendari, podem fer-ho directament amb estils (css), tenint en compte que el botó es crea automàticament sota la classe 'calendarImageClass'. Així, per modificar, per exemple, la posició del botó, podem for-ho de la següent manera: .pagedSelectImageClass{ org.hibernate.exception.SQLGrammarException: could not execute queryProblema Al desplegar una aplicació en un servidor d'aplicacions WebLogic es produeix la següent excepció: org.hibernate.exception.SQLGrammarException: could not execute query Solució Això és degut a la incompatibilitat de la llibreria d'antlr que utilitza WebLogic i la que utilitza Hibernate. Es pot solucionar de dues maneres: - Configurar l'aplicació perque doni preferencia als seus jars davant els de WebLogic. Això és configura en el fitxer weblogic.xml: <prefer-web-inf-classes>true</prefer-web-inf-classes> - Configurant Hibernate per a que utilitzi la interpretació clàssica de queries: <property name="hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory</property> _ Com puc afegir un CustomEditor per les propietats d'un pojo?Problema *Solució* <bean name="/detailsusers" El map customMappingEditors contindrà les propietats del pojo com a clau i la classe que implementi el customEditor de la propietat com a valor. Generalitat de Catalunya |