martedì 27 dicembre 2011

Gestire permessi per i file da terminale

Esistono 3 permessi attribuibili a un file o directory (per Ubuntu sono la stessa cosa):
  • r  che sta per read
  • x che sta per execute
  • w che sta per write
Esistono poi 3 tipologie di utenti:
  • Proprietario indicato con la lettera u
  • Gruppo indicato con la lettera g
  • Altri indicati con la lettera o

Se creiamo in una directory due file di testo (es. f1.txt e f2.txt) e poi scriviamo
ls -l  sul terminale (ossi elenca file e permessi)
otteniamo un risultato di questo tipo:

-rw-rw-r-- 1 carlo carlo 0 2011-12-28 00:10 f1.txt
-rw-rw-r-- 1 carlo carlo 0 2011-12-28 00:09 f2.txt


Il primo carattere ci dice se si tratta di un file o di una directory , se è un file compare il carattere - altrimenti la lettera d.
In questo caso, essendo 2 file abbiamo 2 -.
Il prosieguo della stringa si legge a gruppi di 3 e indica i permessi del proprietario del gruppo e degli altri utenti.
Quindi la stringa sopra incollata significa che per i 2 file il proprietario ha diritti di read e write  così come l'utente Gruppo.
Gli "altri" hanno solo il privilegio di lettura.
Per aggiungere/togliere permessi si utilizza il comando chmod con sintassi

chmod [tipo_utente] +/- [permessi] [nome_file_o_directory]

Esempio: aggiungere permesso di esecuzione all'utente Proprietario

chmod u+x f1.txt

Se richiediamo ls -l abbiamo adesso:

-rwxrw-r-- 1 carlo carlo    0 2011-12-28 00:10 f1.txt


Per togliere il permesso di lettura all'utente "Altri"


chmod o-r f1.txt

 Se richiediamo ls -l abbiamo adesso:

 -rwxrw---- 1 carlo carlo    0 2011-12-28 00:10 f1.txt







Leggere File di Properties settandone i parametri

Supponiamo di avere un file di Properties con nel messaggio dei placeholder, che servono per inserire testo dinamico a completamento.

Esempio il file test.properties così composto:

test=ciao {0} il tuo cognome è {1}


Per leggere il file ed effettuare la sostituzione dei parametri si utilizza la classe MessageFormat.

Properties p=new Properties();
p.load(new FileInputStream(("out/test.properties")));
System.out.println(MessageFormat.format(p.getProperty("test"), "Mario","Rossi"));


L'output sarà :

ciao Mario il tuo cognome è Rossi

Per versioni precedenti di Java come Java 4 si può utilizzare il metodo:

MessageFormat.format(p.getProperty("test"), new Object[]{"Mario","Rossi"})

domenica 25 dicembre 2011

Esempio utilizzo MDB

Nel seguente esempio proviamo a :
  • Definire una coda JMS su Jboss 5.1;
  • Realizzare un programma client java che scriva sulla coda dei messaggi;
  • Realizzare un Message Driven Bean che legga il messaggio e lo tolga dalla coda JMS.
DEFINIRE CODA JMS

Sotto la directory default deploy creare una directory denominata code dove andremo a definire la nostra coda JMS.

A questo punto dalla console di amministrazione di Jboss (utenza e pwd di default sono admin admin).




Cliccando su Add a new Resource e seguendo il menu definiamo il nome della coda "MiaCoda" e il JNDI name "code/MiaCoda".
Una volta terminata la procedura possiamo verificare il corretto funzionamento guardando sotto la directory deploy/code, troveremo il file xml MiaCoda-service.xml.

DEFINIRE CLIENT JAVA

Definiamo un semplice progetto Java su eclipse, inserendo nel classpath tutte le librerie presenti nella directory client di Jboss.

Il codice nel main del programma è il seguente:

import java.util.Properties;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;

public class MessageSender {

   
   
    public static void main(String[] args) throws Exception{
        ConnectionFactory connectionFactory;
        Destination destination;
        Properties p=new Properties();
        p.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
        p.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
        p.put(Context.PROVIDER_URL, "jnp://127.0.0.1:1099");
        Context ctx=new InitialContext(p);
        connectionFactory=(ConnectionFactory)ctx.lookup("/ConnectionFactory");
        destination=(Queue)ctx.lookup("/code/MiaCoda");
        System.out.println("La coda e la connessione sono stati recuperati");
        Connection connection=null;
        connection=connectionFactory.createConnection();
        Session session=connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        MessageProducer mp=session.createProducer(destination);
         TextMessage msg = session.createTextMessage();
          for (int i = 0; i < 5; i++) {
          msg.setText("Questo è il messaggio " + (i + 1));
          mp.send(msg);
          }
          connection.close();
          System.out.println("Messaggi inviati correttamente");
         
    }
   
}


Vengono scritti e inviati 5 messaggi.
Se proviamo ad eseguire il programma con Jboss acceso vediamo che da Console ci compare il seguente messaggio:

La coda e la connessione sono stati recuperati
Messaggi inviati correttamente


Quindi andando sulla console di amministrazione di Jboss in corrispondenza della coda "MiaCoda" troviamo:

Vediamo che risultano 0 consumer (nessuno ha letto i messaggi, non essendoci ancora l'MDB) e 5 messaggi presenti nella coda.




DEFINIRE IL MESSAGE DRIVEN BEAN

L' MDB ha il compito di connettersi alla coda e leggere i messaggi presenti.
Per realizzarlo creiamo un progetto Java inserendo nel classpath le librerie client di Jboss 5.1.
Per definire l'MDB annotiamo la classe con @MessageDriven, mentre la classe deve implementare l'interfaccia MessageListener (del package javax.jms).
Da notare la definizione dell'elemento activationConfig dove si specifica il tipo di Destination (in questo caso una coda) e il nome della coda ("code/MiaCoda").

Il codice è il seguente:

import javax.annotation.Resource;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.ejb.MessageDrivenContext;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

@MessageDriven(name="MessageBean",
activationConfig= {
        @ActivationConfigProperty(propertyName="destinationType",
                                    propertyValue="javax.jms.Queue"),
        @ActivationConfigProperty(propertyName="destination",
                                    propertyValue="code/MiaCoda")
                  }
        )

public class MessageBean implements MessageListener {
    @Resource
       private MessageDrivenContext mdc;

     
       public void onMessage(Message msg) {
         TextMessage tmsg = null;

       try
       {
             tmsg = (TextMessage) msg;
             System.out.println("MESSAGE BEAN: Messaggio ricevuto: " + tmsg.getText( ));
             System.out.println ("Metodo onMessage() richiamato");
       }
       catch (JMSException e) {
                               e.printStackTrace( );
                               mdc.setRollbackOnly( );
                              }
      catch (Throwable th)    {
                              th.printStackTrace();
                              }
       }
     
}


Una volta fatto ciò possiamo esportare il progetto come jar file all'interno della directory deploy di JBoss.

Una volta deployato subito si nota sulla console di Jboss che i messaggi messi nella coda sono stati consumati dall'MDB:


13:06:53,945 INFO  [STDOUT] MESSAGE BEAN: Messaggio ricevuto: Questo è il messaggio 2
13:06:53,945 INFO  [STDOUT] Metodo onMessage() richiamato
13:06:53,946 INFO  [STDOUT] MESSAGE BEAN: Messaggio ricevuto: Questo è il messaggio 3
13:06:53,946 INFO  [STDOUT] Metodo onMessage() richiamato
13:06:53,947 INFO  [STDOUT] MESSAGE BEAN: Messaggio ricevuto: Questo è il messaggio 1
13:06:53,947 INFO  [STDOUT] Metodo onMessage() richiamato
13:06:53,947 INFO  [STDOUT] MESSAGE BEAN: Messaggio ricevuto: Questo è il messaggio 4
13:06:53,948 INFO  [STDOUT] Metodo onMessage() richiamato
13:06:53,949 INFO  [STDOUT] MESSAGE BEAN: Messaggio ricevuto: Questo è il messaggio 5
13:06:53,950 INFO  [STDOUT] Metodo onMessage() richiamato


Andando sulla coda via console di amministrazione vediamo infatti che adesso il Campo Consumer count è pari a 1 mentre il Message Count a 0.
Tutti i messaggi sono stati letti quindi dall'MDB e la coda è stata svuotata.

SCRIVERE MESSAGGI SULLA CODA JMS VIA WEB APPLICATION

In questo caso realizziamo una semplice Web appplication con un form su cui si inserisce il messaggio in una textArea e si invia il tutto ad una servlet che si occupa di aggiungere il messaggio alla coda jms.
Si noti come in questo caso i riferimenti alla ConnectionFactory e alla Destination siano recuperati tramite l'annotazione @Resource e non tramite look up JNDI.

public class ScriviMessaggioSuCoda extends HttpServlet {
    private static final long serialVersionUID = 1L;
    @Resource(name="code/MiaCoda",mappedName="code/MiaCoda")
    private javax.jms.Destination codaTest;
    @Resource(name="ConnectionFactory",mappedName="ConnectionFactory")
    private javax.jms.ConnectionFactory connentionFactory;
    /**
     * @see HttpServlet#HttpServlet()
     */
    public ScriviMessaggioSuCoda() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        try
        {
        String messaggio=request.getParameter("txtMessage");
        Connection connection = connentionFactory.createConnection();
          connection=connentionFactory.createConnection();
        Session session=connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        MessageProducer mp=session.createProducer(codaTest);
        TextMessage msg = session.createTextMessage();
        msg.setText(messaggio);
        mp.send(msg);
        connection.close();
        System.out.println("Sending message");
        session.close ();
        PrintWriter wr=response.getWriter();
        wr.write("<b>Messaggio inviato</b>");
        wr.flush();
        }
        catch(Exception ex){
            ex.printStackTrace();
        }
         
       
    }

}

venerdì 23 dicembre 2011

Progetto di test Junit su Eclipse

Per creare un semplice progetto di Junit test su eclipse occorre:
  • Scaricarsi la libreria Junit da qui;
  • Inserire il jar di Junit nella lib del progetto e aggiungerla al classpath;
  • Scrivere una classe java che estenda la classe junit.framework.TestCase;
  • Definire una serie di metodi void con firma public void testXXXX();
  • Lanciare la classe scegliendo tra le opzioni run as Junit-test
Nel mio caso ad esempio volevo testare un metodo per la validazione della partita iva.
Ho preso quindi delle partite iva corrette e alcune sbagliate, scrivendo un metodo di questo tipo:

public void testPartitaIva(){
  PartitaIva p=PartitaIva.getInstance();
  System.out.println("Inizio test partita iva...");
  assertEquals(true, p.verificaPartitaIva("07973780013"));
  assertEquals(true, p.verificaPartitaIva("00875591000"));
  assertEquals(true, p.verificaPartitaIva("13212880150"));
  assertEquals(true, p.verificaPartitaIva("04914190824"));
  assertEquals(true, p.verificaPartitaIva("00905811006"));
  assertEquals(false, p.verificaPartitaIva("00905811007"));
  assertEquals(false, p.verificaPartitaIva("04914190825"));
  assertEquals(false, p.verificaPartitaIva("13212880151"));
  assertEquals(false, p.verificaPartitaIva("00875591009"));
  assertEquals(false, p.verificaPartitaIva("07973780016"));
  System.out.println("Partita iva ok");
       
    }


Eseguendolo come test Junit sulla console di Eclipse nel caso in cui non ci siano errori appare la seguente schermata:



mercoledì 21 dicembre 2011

Calcolare l'Md5 di una stringa

Un metodo statico per il calcolo dell'hash di una Stringa (MD5).


/**
  * Calcola l'hash
  * @param md5 la stringa in ingresso
  * @param encoding l'encoding (es utf-8,latin1...)
  * @return
  * @throws UnsupportedEncodingException
  */
 public static String MD5(String md5,String encoding) throws UnsupportedEncodingException {  
  try {        
   java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
   String s=new String(md5.getBytes(), encoding);
   byte[] array = md.digest(s.getBytes());       
   StringBuffer sb = new StringBuffer();       
   for (int i = 0; i < array.length; ++i) { 
    String hex=Integer.toHexString((array[i] & 0xFF)+0x100).substring(1);
    sb.append(hex);
   }        
   return sb.toString();     }
  catch (java.security.NoSuchAlgorithmException e) {   
   throw new IllegalArgumentException("Attenzione non esiste l'algoritmo di cifratura selezionato");
  }   
 } 


Ottenere informazioni sulla locazione di un War a runtime

Per conoscere esattamente il percorso completo (che varia da Sistemi Operativi ad Application Server) della context root della nostra web app a runtime è sufficiente eseguire il seguente codice sulla jsp:

<%ServletContext ctx=getServletContext(); %

Esempio risultati, su una web app deployata su jboss:

C:\ApplicationServers\jboss-5.1.0.GA\server\default\tmp\a6d6hk-yat7vh-gwg691ss-1-gwg69t38-9p\WebTest.war 
<%=ctx.getRealPath("") %>
>

mercoledì 14 dicembre 2011

Limitare via javascript il numero caratteri inseriti su textarea

Con questo javascript è possibile data una textarea limitare l'input dei caratteri inseriti avvisando l'utente di quanti caratteri stia inserendo (esponendogli il messaggio in una input text hidden).

Il javascript è il seguente:

function contaCaratteri(area, field, max){
    var cont= area.value.length;
    if (cont > max){
        area.value = area.value.substr(0, max);
       
        document.getElementById(field).value = 'Massimo ' + max + ' caratteri!';
      
       
       
      
    }else{
        if(cont>1){
        document.getElementById(field).value = 'Inseriti ' + cont + ' caratteri!';
        }
        else
        {
            document.getElementById(field).value = 'Inserito ' + cont + ' carattere!';
        }
    }
}


L'esempio HTML è questo (digitare all'interno della textarea):



venerdì 9 dicembre 2011

Lista dati con checkbox usando display tag

Con riferimento al post precedente vediamo lo stesso esempio fatto con display-tag.
In questo caso l'unica cosa poco carina mi sembra sia il fatto che per mostrare nell'header la checkbox che consente di fare i check e decheck massivi bisogna scrivere nel title direttamente l'html.

Ecco l'esempio:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
   
<%@taglib uri="http://displaytag.sf.net" prefix="display" %>
 <%@taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<div >
<form name="myForm" action="VisualizzaRisultati" method="post">

     <display:table name="sessionScope.lista"   cellspacing="0"
             id="r" >
       <display:column title="<input type='checkbox' name='selectall' onclick='javascript:checkDececkAll()' />" sortable="false" media="html">
     
       
        <input type="checkbox" name="idValue"  ${r.checked}/>
        <input type="hidden" name="txtValore" value=""/>
       </display:column>
       <display:column property="dataCreation" title="Data creazione"></display:column>
       <display:column property="location" title="Location"></display:column>
       <display:column property="name" title="Nome"></display:column>
       <display:column property="status" title="Status"></display:column>
     </display:table>
     <input type="button" name="InvioDati" value="Invia" onclick="javascript:invio()"/>
</form>
   </div>
</body>
<script language="javascript">
var checked=false;
function checkDececkAll()
{
    var field=document.myForm.idValue;
   
    if(checked){
        // uncheck
        for (var i = 0; i < field.length; i++){
            field[i].checked = false ;
        }
        checked=false;
    }
    else
        {
          //check
        for (var i = 0; i < field.length; i++){
            field[i].checked = true ;
        }
         checked=true;
    }
    }
function invio(){
    var field=document.myForm.idValue;
    var txt=document.myForm.txtValore;
    for(var i=0;i<field.length;i++){
        if(field[i].checked){
            field[i].value="ok";
            txt[i].value="ok";
        }
        else
            {
            field[i].value="ko";
            txt[i].value="ko";
            }
    }
    document.myForm.submit();
}
</script>
</html>

Lista dati con checkbox e possibilità di selezionare tutti gli elementi

E' questa una delle più classiche attività che capita fare sviluppando applicativi (in special modo gestionali).
Visualizziamo dei dati da una lista e li esponiamo a video , l'utente può quindi selezionarle tutte o nessuna o quelle che vuole lui e premendo il tasto invio dobbiamo inviare i dati, distinguendo tra selezionati e no.

Vediamo un immagine di esempio:

Vediamo come realizzarlo utilizzando jsp e jstl.
Lato javascript al momento dell'invio del form parte un evento che per ogni check selezionato va a settare un valore "ok" in un campo hidden.
Questo perchè lato server come parameter passeranno soltanto le check selezionate e a noi serve sapere per ogni elemento sia se è stato selezionato che se non lo è stato.


Ecco la jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
 <%@taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<form name="myForm" action="VisualizzaRisultati" method="post">
<table border="1">
<tr>
<td><input type="checkbox" name="chkAll" onclick="javascript:checkDececkAll()"/></td>
<td>Nome</td>
<td>Luogo</td>
<td>Status</td>
<td>Data</td>
</tr>
<c:forEach var="item" items="${lista}">
        <tr> 
              <td>
                  <input type="checkBox" name="idValue" id="idValue" value="ko" ${item.checked}>   
                  <input type="hidden" name="txtValore" value=""/>             
              </td>   
            <td>${item.name}</td>
            <td>${item.location}</td>
            <td>${item.status}</td>
            <td>${item.dataCreation}</td>
            </tr>       
    </c:forEach>
</table>
    <br>
    <input type="button" onclick="javascript:invio()" value="Prova"/>
    </form>
</body>

<script language="javascript">
var checked=false;
function checkDececkAll()
{
    var field=document.myForm.idValue;
    if(checked){
        // uncheck
        for (var i = 0; i < field.length; i++){
            field[i].checked = false ;
        }
        checked=false;
    }
    else
        {
          //check
        for (var i = 0; i < field.length; i++){
            field[i].checked = true ;
        }
         checked=true;
    }
    }
function invio(){
    var field=document.myForm.idValue;
    var txt=document.myForm.txtValore;
    for(var i=0;i<field.length;i++){
        if(field[i].checked){
            field[i].value="ok";
            txt[i].value="ok";
        }
        else
            {
            field[i].value="ko";
            txt[i].value="ko";
            }
    }
    document.myForm.submit();
}

</script>
</html>


Per gestire invece i valori lato server possiamo procedere in questo modo:


    List<Item> liste=(List<Item>)request.getSession().getAttribute("lista");
        String[] parametri=request.getParameterValues("txtValore");
        for(int i=0;i<parametri.length;i++){
            liste.get(i).setSelezionato((parametri[i].equals("ok")?true:false));
            liste.get(i).setChecked(parametri[i].equals("ok")?"checked":"");
        }
        request.getSession().setAttribute("lista", liste);
        RequestDispatcher rd=request.getRequestDispatcher("jsp/listaChkBox.jsp");
        rd.forward(request, response);



lunedì 5 dicembre 2011

Java esempio utilizzo JFreeChart

In questo post vediamo come generare un semplice grafico usando la libreria JFreeChart ( http://www.jfree.org/jfreechart/ ).
Partiamo da una jsp e inseriamo i dati di vendita di 3 soggetti, quindi invochiamo una servlet che utilizzando JFreeChart crea l'oggetto grafico scrivendolo come immagine png e rinviandola al client.

La jsp è un semplice form con 3 textBox in cui inserire i dati:
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form name="generateChart" method="post" action="Disegna">
<table>
<tr>
<td>Mario:</td><td><input type="text" id="txtMario" name="txtMario"/></td>
</tr>
<tr>
<td>Gino:</td><td><input type="text" id="txtGino" name="txtGino"/></td>
</tr>
<tr>
<td>Pino:</td><td><input type="text" id="txtPino" name="txtPino"/></td>
</tr>
<tr>
<td colspan="2"><input type="submit" name="btnInvio" value="Genera Grafico"/></td>
</tr>
</table>
</form>
</body>
</html>




La servlet è la seguente:

package it.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.DefaultCategoryDataset;
/**
 * Servlet implementation class FreeChartGenerator
 */
public class FreeChartGenerator extends HttpServlet {
    private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public FreeChartGenerator() {
        super();
        // TODO Auto-generated constructor stub
    }

    private JFreeChart getGrafico(double[] lista) 
    {
        String[] series=new String[]{"Mario","Gino","Pino"};
        DefaultCategoryDataset cds=new DefaultCategoryDataset();
        for(int i=0;i<lista.length;i++){
            cds.addValue(lista[i], "", series[i]);
        }
   
     JFreeChart hitsByFolderChart = ChartFactory.createBarChart( "Report
 Vendite", "Venditore", "Euro", cds, PlotOrientation.HORIZONTAL, false, 
false, false );
        
        return hitsByFolderChart;
//    
        
        
    }
    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        
        double d1=Double.valueOf(request.getParameter("txtMario"));
        double d2=Double.valueOf(request.getParameter("txtGino"));
        double d3=Double.valueOf(request.getParameter("txtPino"));
        double[] ld=new double[3];
        ld[0]=d1;
        ld[1]=d2;
        ld[2]=d3;
        JFreeChart chart=getGrafico(ld);
        response.setContentType("image/png");
        
        ChartUtilities.writeChartAsJPEG(response.getOutputStream(), chart, 500, 300);
        
    }

}




Il risultato finale, dopo aver inserito i seguenti dati sulla jsp:





Sarà il seguente:





domenica 4 dicembre 2011

Java generare un excel da una servlet

Tipicamente si richiede di esportare in formato excel o pdf dati provenienti da liste presenti a front end.
Una soluzione automatica e veloce per questo è utilizzare la libreria dispay tag.
Se però le richieste sono più articolate è necessario utilizzare librerie ad hoc.
Nell'esempio seguente  ci sono due liste diverse di dati (libri e persone) e si vuole vederle raggruppate in un unico excel.

In questo esempio vediamo come generare un excel con, sullo stesso foglio, prima i dati di una lista e poi dell'altra, frapponendo tra le due liste una riga vuota.
Per farlo ho utilizzato le librerie di Apache POI, già viste in altri post.

Il metodo doPost della servlet è il seguente:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try
        {
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment; filename=\""
                        + "export.xls" + "\"");
            ServletOutputStream out = response.getOutputStream();
            HSSFWorkbook wb=getExcel();
            wb.write(out);
            out.close();
        }
        catch(Exception ex){
            ex.printStackTrace();       
        }   
    }


L'oggetto HSSFWorkbook è così creato:

    private HSSFWorkbook getExcel() throws Exception{
        HSSFWorkbook workbook = new HSSFWorkbook();
        // qui si caricano i dati (es. da db) delle due liste persone e libri
        List<Persona> persone=getPersone();
        List<Libro> libri=getLibri();
        HSSFSheet firstSheet = workbook.createSheet("LISTE");
        // riga intestazione prima lista
        HSSFRow rowA = firstSheet.createRow(0);
        HSSFCell cellA = rowA.createCell(0);
        cellA.setCellValue(new HSSFRichTextString("Nome"));
        HSSFCell cellB = rowA.createCell(1);
        cellB.setCellValue(new HSSFRichTextString("Cognome"));
        HSSFCell cellC = rowA.createCell(2);
        cellC.setCellValue(new HSSFRichTextString("Eta'"));
        int i=1;
        for(Persona p:persone){
            HSSFRow riga=firstSheet.createRow(i);
            HSSFCell cellaNome=riga.createCell(0);
            cellaNome.setCellValue(new HSSFRichTextString(p.getNome()));
            HSSFCell cellaCognome=riga.createCell(1);
            cellaCognome.setCellValue(new HSSFRichTextString(p.getCognome()));
            HSSFCell cellaEta=riga.createCell(2);
            cellaEta.setCellValue(new HSSFRichTextString(String.valueOf(p.getEta())));
            i++;
           
        }
        // riga vuota
        HSSFRow rigaVuota=firstSheet.createRow(i);
        i++;
        // riga intestazione nuova lista
        HSSFRow rowLibro = firstSheet.createRow(i);
        HSSFCell cellAutore = rowLibro.createCell(0);
        cellAutore.setCellValue(new HSSFRichTextString("Autore"));
        HSSFCell cellTitolo = rowLibro.createCell(1);
        cellTitolo.setCellValue(new HSSFRichTextString("Titolo"));
        HSSFCell cellPrezzo = rowLibro.createCell(2);
        cellPrezzo.setCellValue(new HSSFRichTextString("Prezzo"));
        HSSFCell cellCodice = rowLibro.createCell(3);
        cellCodice.setCellValue(new HSSFRichTextString("Codice"));
        i++;
        for(Libro l:libri){
            HSSFRow riga=firstSheet.createRow(i);
            HSSFCell cellaAutore=riga.createCell(0);
            cellaAutore.setCellValue(new HSSFRichTextString(l.getAutore()));
            HSSFCell cellaTitolo=riga.createCell(1);
            cellaTitolo.setCellValue(new HSSFRichTextString(l.getTitolo()));
            HSSFCell cellaPrezzo=riga.createCell(2);
            cellaPrezzo.setCellValue(new HSSFRichTextString(formattaDouble(l.getPrezzo())));
            HSSFCell cellaCodice=riga.createCell(3);
            cellaCodice.setCellValue(new HSSFRichTextString(l.getCodice()));
            i++;
           
        }
       
        return workbook;
    }
    private String formattaDouble(double d){
        NumberFormat nf=NumberFormat.getCurrencyInstance(Locale.ITALY);
        nf.setCurrency(Currency.getInstance(Locale.ITALY));
        return nf.format(d);
    }

Java trovare il mime-type di un file

Una funzioncina per tirare fuori il mime-type di un file:


private String getMimeType(File file) {

        MimetypesFileTypeMap mime = new MimetypesFileTypeMap();
       
        return mime.getContentType(file);

    }

venerdì 2 dicembre 2011

Struts errore Module 'null' not found

Se capita un errore di questo tipo nel deploy di una Web App con Struts 1 il problema è dovuto al mancato caricamento della ActionServlet allo start up.
Bisogna ricordarsi di inserire nel web.xml il parametro load-on-startup.
Questo perchè di specifica la servlet è garantito che sia caricata prima della prima chiamata esplicita, se accediamo allo start up di una applicazione struts non è detto quindi che la servlet sia stata già richiamata.

Nel web.xml avremo quindi

<servlet-name>action</servlet-name>
  <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
  <init-param>
    <param-name>config</param-name>
    <param-value>/WEB-INF/struts-config.xml</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
  <servlet-name>action</servlet-name>
  <url-pattern>*.do</url-pattern>
</servlet-mapping>

giovedì 1 dicembre 2011

Messaggio di errore "Ant unable to locate tools.jar"

Capita a volte dopo aver installato Ant su Windows di incappare in questo errore.
Ant cerca il jar tools.jar dentro la jre e non dentro la jdk (magari c'è nel path qualche link che fa caricare nel classpath la jre come versione di Java.
Il modo corretto per far funzionare ant su Windows è il seguente:
1) Settare la variabile di ambiente JAVA_HOME(senza bin);
2) Settare la variabile di ambiente ANT_HOME (senza bin);
3) Inserire nella variabile di ambiente PATH, all'inizio in modo da essere sicuri che siano i primi valori caricati nel classpath, i valori %JAVA_HOME%\bin;%ANT_HOME%\bin.

Per verificare la correttezza dell'installazione da DOS digitare ant -version
Se tutto è andato per il verso giusto comparirà un messaggio del tipo

Apache Ant(TM) version 1.8.2 compiled on December 20 2010

martedì 29 novembre 2011

Redirect automatico da una pagina con conto alla rovescia

E' molto utile utilizzare il tag
<META http-equiv="Refresh" content="10;URL=http://www.nuovaurl.it">
dentro la sezione <head> dell'html, in modo da effettuare un redirezionamento a tempo (in questo caso 10 secondi) di una pagina Web.

Vediamo come abbinarlo al classico "conto alla rovescia", supponiamo di avere una pagina che ci informi che avverrà la redirezione al sito www.corriere.it dopo X secondi e di avere un informazione sulla pagina in merito a quanti secondi mancano alla redirect.
Per ottenere questo risultato si utilizza nell'onload del body della pagina il metodo setInterval, che accetta 2 parametri:
  1. La funzione javascript da richiamare;
  2. Il tempo in millisecondi che deve trascorrere tra una chiamata e l'altra.
Vediamo il codice HTML e Javascript di questo semplice esempio:

<html>

<head>
<title>Pagina di autorefresh</title>
<META http-equiv="Refresh" content="10;URL=http://www.corriere.it">
</head>
<body onload="javascript:setInterval('go()',1000)">
Sarai redirezionato al sito in
<div id="mioDiv">10
</div> secondi
</body>
</html>

<script language="javascript">
function go(){
var valore=parseInt(document.getElementById("mioDiv").innerHTML);
valore=valore-1;
document.getElementById("mioDiv").innerHTML=valore;

}
</script>


venerdì 25 novembre 2011

Java calcolo piano ammortamento alla francese

Questa classe provvede a calcolare il piano ammortamento alla francese (rata costante, quota capitale crescente e quota interesse decrescente), tornando una lista di oggetti Rata con le seguenti proprietà:
  • Numero Rata
  • Data Scadenza
  • Importo Rata
  • Quota Interessi
  • Quota Capitale
  • Debito Residuo
Di seguito posto il codice della classe, con un main di esempio invocazione:


package it.test;

import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
enum PERIODICITA
{
    MENSILE(12),
    TRIMESTRALE(4),
    QUADRIMESTRALE(3),
    SEMESTRALE(2),
    ANNUALE(1);
    PERIODICITA(int n)
    {
        this.n=n;
    }
    private int n;
    public int getN() {
        return n;
    }
    public void setN(int n) {
        this.n = n;
    }
   
   
}
class Rata
{
    private Date dataScadenza;
    private int numeroRata;
    private double importoRata;
    private double quotaCapitale;
    private double quotaInteressi;
    private double debitoResiduo;
   
   
    public Date getDataScadenza() {
        return dataScadenza;
    }
    public void setDataScadenza(Date dataScadenza) {
        this.dataScadenza = dataScadenza;
    }
    public String toString(){
        StringBuilder sb=new StringBuilder();
        sb.append("[");
        sb.append(" Numero rata: ");
        sb.append(formatNumber(this.numeroRata));
        sb.append(" Data Scadenza: ");
        sb.append(formatDate(this.dataScadenza));
        sb.append(" Importo: ");
        sb.append(formatNumber(this.importoRata));
        sb.append(" Quota Capitale: ");
        sb.append(formatNumber(this.quotaCapitale));
        sb.append(" Quota Interesse: ");
        sb.append(formatNumber(this.quotaInteressi));
        sb.append(" Debito Residuo: ");
        sb.append(formatNumber(this.debitoResiduo));
        sb.append(" ]");
        sb.append("\n");
       
       
        return sb.toString();
    }
    public int getNumeroRata() {
        return numeroRata;
    }
    public void setNumeroRata(int numeroRata) {
        this.numeroRata = numeroRata;
    }
    public double getImportoRata() {
        return importoRata;
    }
    public void setImportoRata(double importoRata) {
        this.importoRata = importoRata;
    }
    public double getQuotaCapitale() {
        return quotaCapitale;
    }
    public void setQuotaCapitale(double quotaCapitale) {
        this.quotaCapitale = quotaCapitale;
    }
    public double getQuotaInteressi() {
        return quotaInteressi;
    }
    public void setQuotaInteressi(double quotaInteressi) {
        this.quotaInteressi = quotaInteressi;
    }
    public double getDebitoResiduo() {
        return debitoResiduo;
    }
    public void setDebitoResiduo(double debitoResiduo) {
        this.debitoResiduo = debitoResiduo;
    }
    private String formatNumber(double number){
        NumberFormat nf=NumberFormat.getInstance(Locale.ITALY);
        nf.setGroupingUsed(true);
        nf.setMaximumFractionDigits(2);
        nf.setMinimumFractionDigits(2);
        return nf.format(number);
        }
    private String formatDate(Date d){
        SimpleDateFormat sdf=new SimpleDateFormat("dd/MM/yyyy");
        return sdf.format(d);
    }
   
}
/**
 * Piano di ammortamento a rata costante <br>
 * La rata è divisa in quota interessi e quota capitale, la quota di capitale sarà <br>
 * crescente mentre la quota di interessi decrescente.<br>
 * La somma del totale delle quote capitale deve restituire il capitale prestato.<br>
 *
 *
 *
 * @author
 *
 */
public class PianoAmmortamentoFrancese {
    private double rata;
    private double capitalePrestato;
    private double interesse;
    private PERIODICITA periodicita;
    private int durataMesiMutuo;
    private Date dataPrimaScadenza;
   
    public double getRata() {
        return rata;
    }
    public void setRata(double rata) {
        this.rata = rata;
    }
    public PianoAmmortamentoFrancese(double capitalePrestato,double interesse,PERIODICITA per,int durataMesiMutuo,Date dataPrimaScadenza){
        this.capitalePrestato=capitalePrestato;
        this.interesse=interesse;
        this.periodicita=per;
        this.durataMesiMutuo=durataMesiMutuo;
        this.dataPrimaScadenza=dataPrimaScadenza;
        calcolaImportoRata();
    }
    public List<Rata> getPianoAmmortamento(){
        List<Rata> myList=new LinkedList<Rata>();
        Rata rIn=new Rata();
        rIn.setDebitoResiduo(this.capitalePrestato);
        rIn.setDataScadenza(dataPrimaScadenza);
       
        Date dataScadenza=dataPrimaScadenza;
        int[] dati=getGiorniMesiAnnoFromDate(dataScadenza);
        int giorno=dati[0];
       
        double debitoResiduo=this.capitalePrestato;
        double quotaCapitale=0;
        double interesse=0;
        int numeroRata=0;
        myList.add(rIn);
        do
        {
            numeroRata++;
           
           
            dataScadenza=getDataSuccessiva(dataScadenza);
            int nuovoGiorno=getGiorniMesiAnnoFromDate(dataScadenza)[0];
            if(nuovoGiorno!=giorno){
                if(isGiornoAmmissibilePerData(dataScadenza, giorno)){
                    Calendar c=Calendar.getInstance();
                    c.setTime(dataScadenza);
                    c.set(Calendar.DAY_OF_MONTH, giorno);
                    dataScadenza=c.getTime();
                }
            }
            double[] quote=getQuoteDebito(debitoResiduo);
            Rata r=new Rata();
            quotaCapitale=quote[1];
            interesse=quote[0];
            debitoResiduo=debitoResiduo-quotaCapitale;
            r.setImportoRata(rata);
            r.setDataScadenza(dataScadenza);
            r.setDebitoResiduo(debitoResiduo);
            r.setQuotaCapitale(quotaCapitale);
            r.setQuotaInteressi(interesse);
            r.setNumeroRata(numeroRata);
            myList.add(r);
           
           
        }
        while((int)debitoResiduo!=0);
       
        return myList;
    }
    private void calcolaImportoRata(){

        rata= this.capitalePrestato*getFattoreA()*getFattoreB();
    }
    private double getFattoreB(){
        double numeratore=calcolaA()-(double)1;
        double denominatore=getFattoreA()-1;
        return numeratore/denominatore;
    }
    /**
     * Stiamo calcolando 1+ TA/PA dove TA è l'interesse e PA i periodi annui
     * @return
     */
    private double calcolaA(){
       
        return (double)1+this.interesse/(double)periodicita.getN();
       
    }
    private double esponenteA(){
        return (double)periodicita.getN()*anniRimborso();
       
    }
    private double getFattoreA(){
        return Math.pow(calcolaA(), esponenteA());
    }
   
    private double anniRimborso()
    {
        return (double)this.durataMesiMutuo/(double)12;
    }
    public static void main(String[] args) throws Exception
    {
        Date dataPrimaScadenza= creaData(26, 12, 2011);
       PianoAmmortamentoFrancese p=new PianoAmmortamentoFrancese((double)100000, 0.05,PERIODICITA.MENSILE, 24,dataPrimaScadenza);
      System.out.println(p.getPianoAmmortamento());
      
    }
    private double[] getQuoteDebito(double capitaleResiduo){
        double[] retVal=new double[2];
        double quotaInteressi=(this.interesse/(double)periodicita.getN())*capitaleResiduo;
        double quotaCapitale=rata-quotaInteressi;
        retVal[0]=quotaInteressi;
        retVal[1]=quotaCapitale;
        return retVal;
    }
    private int[] getGiorniMesiAnnoFromDate(Date d){
        Calendar c=Calendar.getInstance();
        c.setTime(d);
        int anno=c.get(Calendar.YEAR);
        int mese=c.get(Calendar.MONTH);
        int giorno=c.get(Calendar.DAY_OF_MONTH);
        int[] lista=new int[3];
        lista[0]=giorno;
        lista[1]=mese;
        lista[2]=anno;
        return lista;
    }
    private Date getDataSuccessiva(Date d){
        int p=12/this.periodicita.getN();
        Calendar c=Calendar.getInstance();
        c.setTime(d);
        c.add(Calendar.MONTH, p);
        return c.getTime();
    }
   private static Date creaData(int giorno,int mese,int anno){
        Calendar c=Calendar.getInstance();
        c.set(Calendar.YEAR, anno);
        c.set(Calendar.MONTH, mese-1);
        c.set(Calendar.DAY_OF_MONTH, giorno);
        return c.getTime();
    }
   private boolean isGiornoAmmissibilePerData(Date d,int giorno){
       boolean retVal=false;
       if(giorno<=28){
           retVal=true;
       }
       else
       {
           int mese=getGiorniMesiAnnoFromDate(d)[1];
           if(mese==Calendar.FEBRUARY){
               if(isLeapYear(getGiorniMesiAnnoFromDate(d)[2]) && giorno==29){
                   retVal=true;
               }
               else
               {
                   retVal=false;
               }
           }
           else if(giorno==31 ){
               if(mese!=Calendar.APRIL && mese !=Calendar.JUNE && mese !=Calendar.SEPTEMBER && mese !=Calendar.NOVEMBER)
               {
                   retVal=true;
               }
               else
               {
                   retVal=false;
               }
           }
       }
       return retVal;
   }
  
   /**
     * Un anno è bisestile se:<br>
     * 1) divisibile per 4<br>
     * 2) non secolare (a parte i secolari divisibili per 400)<br>
     * @param anno
     * @return
     */
    private boolean isLeapYear(int anno){
        boolean retVal=false;
        int div4=anno%4;
        if(div4==0){
            //divisibile per quattro
            int div100=anno%100;
            if(div100==0){
                // è un anno "secolare"
                int div400=anno%400;
                if(div400==0){
                    // però è divisibile anche per 400
                    retVal=true;
                }
                else
                {
                    // anno secolare non divisibile per 400
                    // non è bisestile
                    retVal=false;
                }
            }
            else
            {
                // divisibile per 4 e non secolare è bisestile
                retVal=true;
            }
        }
        return retVal;
    }
}

Jboss .bat per cancellare tutti i file di log

@ERASE  /Q   C:\jboss-4.0.5.GA\server\default\log server.log.????-??-??


L'indicazione /Q indica di non chiedere conferma alla cancellazione,  questo script praticamente cancella sia il server.log sia tutti i back_up, che tipicamente hanno il formato server.log.AAAA-MM-GG.


MySql creare backUp con data usando mysqldump su Windows

Per effettuare un back up di un db con una data (in questo caso con l'indicazione di giorno e ora) su windows si può creare un .bat di questo tipo:  

set giorno=%date:~0,2%
set mese=%date:~3,2%
set anno=%date:~6,4%
set ora=%time:~0,2%_%time:~3,2%_%time:~6,2%
set miadata=%giorno%_%mese%_%anno%_Ore_%ora%
mysqldump -uroot -proot test>c:\test_%miadata%.sql



Il risultato sarà un file di back up di questo tipo:test_25_11_2011_Ore_10_18_34.sql

domenica 20 novembre 2011

Javascript show/hide div

Spesso è utile visualizzare del testo statico on demand su pagina Web, il classico esempio è quello della visualizzazione di informazioni cliccando su un pulsante e poi farlo scomparire di nuovo ricliccando.
Il metodo Javascript è il seguente:

function showhide(id) {
    var state = document.getElementById(id).style.display;
        if (state == 'block') {
            document.getElementById(id).style.display = 'none';
            document.getElementById('spiega').value="Mostra Guida";
        } else {
            document.getElementById(id).style.display = 'block';
           
            document.getElementById('spiega').value="Nascondi Guida";
           
        }
    }

 Al caricamento vogliamo che non si veda il testo del div, quindi definiamo

<style type="text/css">
<!--

#spiegazioni {
   
    display: none;
}
-->
</style>

Sulla pagina HTML abbiamo

<form name="caricaBilancio" id="caricaBilancio" ENCTYPE="multipart/form-data" action="CaricaBilancio" method="post">

<input class="inputButton" id="spiega"    type="button" name="Guida"  title="Guida"  value="Mostra guida" onclick="javascript:showhide('spiegazioni')"/>

<div id="spiegazioni">
/// qui il nostro testo
Prova prova
</div>
Vediamo l'esempio cliccando sul pulsante


// qui il nostro testo Prova prova

Upload di un file via Web

Per effettuare l'upload di File via Web è molto utile utilizzare la libreria commons-fileupload-1.2.2.jar (per usarla c'è bisogno di avere nel classpath anche commons-io.jar.

Bisogna ricordarsi di scrivere dentro il tag Form ENCTYPE="multipart/form-data" altrimenti la chiamata al metodo isMultipartContent(request) torna false.

Ecco il form

<form name="caricaBilancio" id="caricaBilancio" ENCTYPE="multipart/form-data" action="CaricaBilancio" method="post">
<div class="contentResultCol" id="contentResultCol_M1472946676">
<div class="resultBodyObject" id="resultBodyObject_M1472946676">

<table  class="filterTable">
<tr class="filterTr"><td>Acquisisci *: </td>

<td>
<select id="ddlScelta" name="ddlScelta" class="input">
            <option value="B" selected="selected">Bilancio Azienda</option>
            <option value="V">Votazione Azienda</option>
        </select>


</td>
</tr>
<tr class="filterTr">
<td class="filterLabelTd" id="filterLabelTd_M994447656" valign="top">

        <span id="FormModifica_dataCostituzione_label">File Excel *</span>
        </td>
        <td class="filterInputTd" valign="top"><!-- CalendarField#input -->
        <span id="span_FormModifica_dataCostituzione"> <!-- FormField#boundedField -->
        <span class="" alt="" title=""> <input id="fileExcel"
            name="fileExcel" class="input" type="file" value="" size="100" width="100" title="FileExcel"/> </span> </span></td>
</tr>
</table>
<table class="buttonTable" align="left">
    <tr>
        <td><input class="inputButton" id="annulla"    type="button" name="Annulla"  title="Annulla"  value="Annulla" onclick="javascript:self.close();"/></td>
        <td><input class="inputButton" id="salva"   type="button" name="btnInvio" value="Invia Richiesta"    title="Invia Richiesta" onclick="javascript:validateForm()  "  /></td>
        <td><input class="inputButton" id="reset"   type="reset"  name="Cancella" title="Cancella" value="Cancella" /></td>
        <td><input class="inputButton" id="spiega"    type="button" name="Guida"  title="Guida"  value="Mostra guida" onclick="javascript:showhide('spiegazioni')"/></td>
      
   
    </tr>
</table>
</form>


Ecco il codice della Servlet che  effettuare la lettura

RequestDispatcher rd=request.getRequestDispatcher("jsp/CaricaBilancio.jsp");
        try
        {
        String valoreRichiesta="";
        boolean isMultipart = ServletFileUpload.isMultipartContent(request);
        if(isMultipart){
            // Create a factory for disk-based file items
            FileItemFactory factory = new DiskFileItemFactory();

            // Create a new file upload handler
            ServletFileUpload upload = new ServletFileUpload(factory);
            List<FileItem> items=upload.parseRequest(request);
            Iterator iter = items.iterator();
            while (iter.hasNext()) {
                FileItem item = (FileItem) iter.next();

                if (item.isFormField()) {
                    String name = item.getFieldName();
                   valoreRichiesta = item.getString();
                } else {
                    String fieldName = item.getFieldName();
                    String fileName = item.getName();
                    String contentType = item.getContentType();
                    boolean isInMemory = item.isInMemory();
                    long sizeInBytes = item.getSize();
                    log.info(String.format("Upload di file %s di tipo %s e di size %d", fileName,contentType,sizeInBytes));
                    if("B".equals(valoreRichiesta)){
                   
                    InputStream is=item.getInputStream();
                    ExcelCaricamentoDao ed=ExcelCaricamentoDaoImpl.getInstance();
                    BilancioExcel bil= ed.getBilancioFromExcel(is);
                    ed.persistBilancio(bil);
                    request.setAttribute("ok", "Inserimento del bilancio terminato correttamente");
                    }
                    else
                    {
                        InputStream is=item.getInputStream();
                        ExcelCaricamentoDao ed=ExcelCaricamentoDaoImpl.getInstance();
                        VotazioneExcel v=ed.getVotazioniFromExcel(is);
                        ed.persistVotazione(v);
                       
                        request.setAttribute("ok", "Inserimento della votazione terminato correttamente");
                    }
                   
                }
            }
           
        }
        }
        catch(Exception fex){
            String messaggio="";
            if(fex instanceof SQLException){
                if(fex.getMessage().startsWith("Duplicate entry"))
                {
                    messaggio="Attenzione nel foglio caricato sono presenti dei dati che non rispettano i vincoli di univocità del database. " +
                            " Si consiglia di ricontrollare di aver rispettato tutte le regole di caricamento. <br> Dettaglio Messaggio:";
                    messaggio=messaggio+fex.getMessage();
                }
                else
                {
                    messaggio="Attenzione si sono verificati dei problemi nell'inserimento dati sul db. <br>" +
                            "Si consiglia di ricontrollare di aver rispettato tutte le regole di caricamento. Dettaglio Messaggio: ";
                    messaggio=messaggio+fex.getMessage();
                }
            }
            if(messaggio.equals(""))
            {
                messaggio=fex.getMessage();
            }
            request.setAttribute("error", messaggio);
        }
        finally{
            rd.forward(request, response);
        }

Per la lettura del file Excel è molto utile utilizzare Apache POI (vedi post precedenti).