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