Il Blog degli smanetta!!!

Ottobre 31, 2008

Struts2 – Tips and Trick (per la migrazione da Struts1)

Archiviato in: Java, Programmazione, struts2, web application — resmanetta @ 3:37 pm
Tags:

Con questo post inizio una serie di articoli contenenti suggerimenti e soluzioni per la migrazione da struts1 a struts2. Sull’argomento si trovano numerosi documenti in rete ai quali non mi posso e non mi voglio sostituire. Parlerò soltanto di questioni pratiche in cui mi sono imbattuto e delle soluzioni intraprese per superarli. In alcuni casi quindi darò per scontato terminologie e sintassi che si possono trovare nella documentazione del framework: http://struts.apache.org/2.x/docs/home.html

Internazionalizzazione delle pagine

Iniziamo dalla configurazione. In struts1 si indica il nome del file generico language.properties di risorsa(indicando anche il package che lo contiente) con il tag :

<message-resources null=”false” parameter=”it.example.struts.language” />

Per ogni lingua (oltre a quella di default utilizzata dal file generico) che si vuole supportare sarà necessario aggiungere nel package, ad esempio per la lingua inglese, un file con nome language_en.properties.

In struts2, posso stabilire il nome del mio file di risorsa lingua, utilizzando la configurazione :

<constant name=”struts.custom.i18n.resources” value=”language”/>  nel file struts.xml  o
struts.custom.i18n.resources=ssolanguage nel file struts.properties

In entrambi i casi , il file di lingua è a tutti gli effetti un file di properties standard di coppie key/value. Ad esempio:

commons.user.firstName=Nome
commons.user.lastName=Cognome

Per visualizzare una pagina che risponda ad esempio alla lingua impostata dal browser del client, devo utilizzare all’interno delle jsp un tag specifico che data la key, vada a recuperare dal file di lingua il value che voglio visualizzare  (non è obbligatorio l’uso del tag, ma rende più semplice la lettura della jsp ai designer che dovranno abbellirla!)

<bean:message key=”commons.user.firstName”/>   per struts1
<s:text name=”commons.user.firstName” />    per struts2

Tutto questo nei casi più semplici. Supponiamo ora di avere una lista di profili di accesso al nostro sito che ho inserito in una variabile statica all’interno della classe User:

public class User {
public static final String[] PROFILES = {“USER”,”ADMIN”,”OTHER”};
….
}

Nel file di lingua metterò queste chiavi:

user.profile.USER=Utente standard
user.profile.ADMIN=Amministratore
user.profile.OTHER=Altro utente

In struts1, ad esempio in una select del profilo, potevo cavarmela in questo modo:

<select name=”profile”>
<% for(int cont=0; cont < User.PROFILES.length; cont++) {%>
<option value=”<%=User.PROFILES[cont] %>”>
<bean:message key=”<%=”user.profile.”+User.PROFILES[cont]%>”/>
<% } %>
</select>

In struts2 non ho la possibilità di usare scriptlet negli attributi dei tag. Decisione se volete discutibile (ma la condivido) , ma che va sempre nella direzione di rendere facilmente leggibile la jsp ad un designer. Posso comunque utilizzare espressioni adattandomi alla nuova sintassi di struts2 (http://struts.apache.org/2.x/docs/tag-syntax.html) ,sfruttando il meccanismo del Value Stack al quale posso accedere via OGNL.

<select name=”profile”>
<% for(int cont=0; cont < User.PROFILES.length; cont++) { pageContext.setAttribute(“type”,”user.profile.”+User.PROFILES[cont]);%>

<option value=”<%=User.PROFILES[cont] %>”>
<s:text name=”%{#attr.type}”/>
<% } %>
</select>

Usando l’operatore %{} sto chiedendo al tag di valutare un’espressione (già..proprio come facevo in struts1) e con # sto chiedendo di recuperare un oggetto dal Value Stack. In particolare voglio recuperare l’attributo di nome type (che in effetti ho messo nel PageContext con un setAttribute)

Aprile 1, 2008

Problemi di carattere?

Archiviato in: Filter, Java, Tomcat, web application — resmanetta @ 9:50 am
Tags: , , ,

L’utente compila una form della vostra applicazione e i dati acquisiti non vengono visualizzati correttamente?

Il problema del titolo non è ovviamente un problema di carattere del nostro utente ma un problema di trasporto, salvataggio e visualizzazione dei caratteri inseriti! Ho usato volontariamente tre termini per descrivere il problema perchè sono tre le fasi in cui è importante gestire correttamente l’informazione.

  1. Visualizzazione
    Un browser moderno è in grado di visualizzare correttamente il testo se la pagina HTML gli fornisce i sufficienti suggerimenti per utilizzare appropriati caratteri e la giusta codifica. Sebbene ci siano delle impostazioni selezionabili da browser, è più logico pensare che l’utente tipico visualizzi correttamente la pagina senza dover modificare certe impostazioni.
    Una pagina HTML corretta deve contenere quindi il seguente meta tag:

    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>

    Anche se le pagine sono generate utilizzando JSP è necessario indicare l’encoding utlizzato.In questo caso è possibile farlo utlizzando lo stesso meta tag oppure usando la directive @page<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>

  2. Trasporto
    Con trasporto intendo quella fase in cui il browser invia i dati (ad esempio la submission di una form) al server. Avendo aggiunto i meta tag o la direttiva @page, ora il browser conosce qual codifica utilizzare per inviare i dati.Allo stesso modo è necessario imporre al web server che processa i dati di usare la stessa codifica. Di default,ad esempio, Tomcat usa la codifica ISO-8859-1 e quindi nel nostro caso (UTF-8) potrebbero nascere dei problemi. Come risolvere?
    In Tomcat è possibile configurare il character-encoding tra le impostazioni del connector nel file server.xml con il parametro URIEncoding=”UTF-8″ , ma questa soluzione è fortemente dipendente dal web server (cosa succede se non usate Tomcat? ) ed inoltre l’ URIEncoding viene utilizzato solo nel caso in cui il metodo sia GET a non POST
    La soluzione migliore è quella di utilizzare il metodo setCharacterEncoding dell’oggetto di classe HttpServletRequest.
    Su questa strada ci viene incontro un filtro presente all’interno del framework Spring: CharacterEncodingFilter
    facilmente configurabile all’interno del web.xml in questo modo:<filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
    <param-name>encoding</param-name>
    <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
    <param-name>forceEncoding</param-name>
    <param-value>true</param-value>
    </init-param>
    </filter>
  3. Salvataggio
    L’ultimo passo è quello di configurare il database in modo che possa salvare tutti i caratteri supportati dal browser e dal livello di business. In caso contrario, se si tenta di salvare del testo che contiene caratteri non presenti all’interno dell’insieme definito dal character encoding impostato, i dati vengono irrimediabilmente persi come mostrato in figura :

    Nel nostro caso abbiamo suggerito UTF-8 al browser e forzato UTF-8 nella gestione della request, quindi impostando ancora una volta UTF-8 nel database abbiamo la certezza che i dati non verranno persi nel tragitto browser-business-database sia in andata che al ritorno:

Alla prossima!

Marzo 3, 2008

Test test e ancora test

Archiviato in: Java, test, web application — resmanetta @ 3:46 pm

“Un software senza bachi è un software che non fa quello per cui è stato progettato”.
Aggiungerei anche che probabilmente “è un software che non fa nulla”!

Detto questo è chiaro che il compito di uno sviluppatore è quello di creare un prodotto che rispecchia la progettazione e che esegue le operazioni, limitando il più possibile il numero di bachi.
Riveste quindi una particolare importanza nel ciclo di sviluppo del software la fase di test.
In quest post non parlerò del test del codice, standalone o lato server di una applicazione web, per il quale esiste l’ottimo JUnit (se sviluppate in Java), ma parlerò di test di funzionalità di Web application che permettano di scoprire se un link non esiste più, se la risposta ad una form è diversa oggi da ieri, etc.
Quello che si fa con questa tipologia di test è simulare l’interazione tra il browser dell’utente e il server che ospita l’applicazione.

Nascono con questo scopo due software/tool open source: HttpUnit e Canoo WebTest
Utilizzando il primo è necessario scrivere del codice Java da integrare in test case JUnit ed è quindi necessario l’intervento di un programmatore.
La scrittura di test di funzionalità per Canoo WebTest si riduce alla scrittura di un file xml (formato Ant) che può essere anche automatizzata utilizzando software esterni. Esiste a questo scopo un add-ons di Firefox (WebTest Recorder Sidebar) che crea il file xml in formato Ant da utilizzare con Canoo WebTest “registrando” l’interazione dell’utente con il sito.

Riporto l’esempio dal sito del tool che testa se la homepage Canoo WebTest appare come primo risultato della ricerca su google impostando come chiave WebTest.
Il file del test è:

<project name=”demodefault=”test“>
<target name=”test“>
<webtest name=”check that WebTest is Google’s top ‘WebTest’ result“>
<invoke url=”http://www.google.com/ncrdescription=”Go to Google (in English)“/>
<verifyTitle text=”Google” />
<setInputField name=”qvalue=”WebTest” />
<clickButton label=”I’m Feeling Lucky” />
<verifyTitle text=”Canoo WebTest Homepage” />
</webtest>
</target>
</project>

Dandolo in pasto a Canoo WebTest si ottiene questo report esaustivo:
Canoo WebTest report

Alla prossima!

Blog su WordPress.com.