Tomcat vs blank fields: you don’t like me

Eccomi qui….finalmente rientrato da una 2 giorni nel profondo nord per motivi di lavoro..corsi, parole e parole, nozioni, righe di codice….una bella overdose di tutte queste cose in sole 48h full immersion….dura la vita del programmatore eh !!! A questo punto non mi resta che pubblicare il mio post e quindi inaugurare devme con una piccola esperienza con cui ho avuto a che fare non molto tempo fa. L’argomento come si può facilemte intuire dal titolo riguarda tomcat un servlet container, per molti IL servlet container usato per pubblicare le applicazioni web sviluppate in Java. Nel corso del tempo passato ad usare tomcat, ho notato che le pagine jsp contenenti banalmente un form con dei campi di input, in alcuni casi non riuscivano ad inviare correttamente i valori verso java bean associati. In particolare, il caso tipo in cui si verificava il suddetto comportamente era il seguente: supponendo di avere una pagina jsp con un Java Bean associato, si faccia caso al comportamento di un utente medio che inserisce alcuni valori in una pagina web:

input

La pagina in questione mostra alcuni campi obbligatori da inserire, in particolare si noti che gli ultimi 2 campi del form sono esclusivi (o Quantità o Colli). A questo cliccando il tasto Submit della pagina (non si vede ma giuro che c’è!) si viene rediretti verso la pagina target, nel caso dell’esempio supponiamo un riepilogo dei dati inseriti. Ma che succede dietro le quinte ? Come ben saprete, viene fatto il submit della pagina verso il server (tomcat), che analizza i campi del form e usando il meccanismo dell’introspezione (introspector) attraverso la riflessione riesce a mappare i campi del form con le rispettive variabili membro del Java Bean associato alla pagina. Quindi supponendo che la pagina target visualizzi i valori delle varibili del Java Bean, quello che si ottiene è:

riepilogo

 

Supponete ora che l’utente si accorga di aver inserito il valore della Quantità piuttosto dei Colli, quindi facendo back nel browser torna di nuovo nel form di inserimento, elimina il valore della Quantità ed inserisce quello dei colli supponiamo 100. Ecco, proprio in questo caso quello che ottenevo era:

riepilogo-no

e cioè nonostante avessi eliminato dal campo Quantità il suo valore, ponendolo quindi a BLANK, dopo il submit il valore associato al campo del Bean era quello associato nell’inserimento precedente. Più precisamente, un valore BLANK per un campo di un form non sembra alterare il valore della corrispondente variabile membro del Bean. A questo punto stufo di questo strano comportamento, ho cominciato a fare debug sui sorgenti di tomcat, per cercare di capire in cosa sbagliava il caro amico. Dopo neanche molto tempo di analisi del codice, ecco cosa ho trovato in una classe interna:

 

1
2
3
4
5
6
7
8
9
10
private static void internalIntrospecthelper(Object bean, 
    String prop, String value, ServletRequest request, 
    String param, boolean ignoreMethodNF) throws JasperException { 
    ..................
    .................. 
    if (value == null || 
       (param != null && value.equals(""))) return;  
    // Riga 352 
    ................. 
    ................ }

Quell’if lì, verifica prima di usare la riflessione per associare il valore del campo del form alla corrispondente variabile membro del Bean, che lo stesso valore sia != null e uguale a "", in questo caso ritorna senza assegnare il valore. Questo spiega il mancato assegnamento in caso di campo con valore BLANK re-impostato. Effettuando così una piccola modifica

1
2
3
4
5
    ....... 
    ....... 
    if (value == null || param == null) return; 
    ....... 
    .......

e ricompilando tutto (cioè tutta distribuzione di tomcat), ho risolto il problema. Ma analizziamo meglio…il ricompilando tutto di prima, vuol dire che :

  • ho scaricato i sorgenti di tomcat
  • effettuato la modifica al file sorgente che è org.apache.jasper.runtime.JspRuntimeLibrary nel metodo di sopra
  • ricompilato tutto eseguendo con ant il build.xml che si trova nella root del progetto.

Al termine della compilazione come risultato ovviamente avevo i binari dell’installazione di tomcat e copiando l’unico jar coinvolto nella modifica, cioè jasper-runtime.jar, nella directory /common/lib il gioco è fatto. E’ stato necessario effettuare questa modifica sia sui sorgenti di tomcat della versione 5.0.28 che su quelli della 5.5.17 e 5.5.20. Non so se le nuove versioni, quelle che girano su Java6 funzioneranno in modo diverso nativamente…in realtà non ho ben capito se questo può definirsi un bug o cosa, (ho anche postato sulla mailing list di tomcat con esito negativo)…sta di fatto che per quanto mi riguarda costituisce un problema.
Download modified jars: jasper-runtime-5.0.28    jasper-runtime-5.5.17

| | More

No Comments

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a comment

WordPress Themes