mercoledì 15 maggio 2013

PrimeFaces gestire messaggi di tipo p:growl e p:messages

Dalla versione 3.3 di prime faces è possibile condizionare la comparsa di messaggi in formato tradizionale (p:messages) oppure a scomparsa temporale (p:growl).
Nel mio caso avevo il seguente scenario.
Un form con un p:messages dichiarato e al suo interno un p:dialog.
Quando si verificava un errore di validazione nel p:dialog doveva comparirmi un p:message (interno al dialog) più a livello di pagina un p:growl (per comodità dell'utente).
Quindi non doveva essere visibile il p:messages standard della pagina che doveva gestire casistiche di errore relative al form e non al dialog.
Nel p:dialog ho definito il p:message interno così:


<p:messages  for="erroreFascicolo"  showDetail="true" autoUpdate="true" closable="true" escape="false" />  


Nel caso di errore di validazione lato java inserisco l'errore in questo modo:

FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR,"errore di validazione","");
FacesContext.getCurrentInstance().addMessage("erroreFascicolo", msg);


Sulla pagina invece ho definito i miei messaggi così:

<p:messages id="messages" globalOnly="true" showDetail="true" autoUpdate="true" closable="true" />  
<p:growl id="growl" for="erroreFascicolo" showDetail="true" autoUpdate="true" escape="false" life="15000"/>

L'attributo globalOnly="true" (di default è pari a false) significa che quel messaggio sarà visualizzato solo nel caso di messaggi aggiunti al contesto jsf senza id.
Quindi tutti i messaggi aggiunti genericamente sono gestiti dal p:messages mentre il p:growl si gestisce soltanto gli errori con id "erroreFascicolo".

martedì 14 maggio 2013

Problemi installazione Tomcat 7 come servizio su Windows 7 (64 bit)

Installando Tomcat 7 come servizio nella consueta maniera (utilizzando il service.bat) avevo il seguente errore allo start up del servizio:

"Windows could not start the Crowd (Apache Tomcat) on Local Computer. For more information, review the System Event Log. If this is a non-Microsoft service, contact the service vendor, and refer to service-specific error code 0."

Ho provato a seguire le istruzione contenute qui ma non sono riuscito a farlo funzionare.
Allora ho confrontato il servizio con un servizio a 32 bit già installato, utilizzando la modalità vista qui

Ho notato che mancavano i seguenti parametri sul tab Java:

Java Virtual Machine

Java ClassPath

Ho quindi inserito a mano sulla console del servizio i parametri:

Java Virtual Machine: C:\Program Files\Java\jdk1.6.0_20\jre\bin\server\jvm.dll
Java Classpath:  D:\apache-tomcat-7.0.39\bin\bootstrap.jar;D:\apache-tomcat-7.0.39\bin\tomcat-juli.jar;D:\apache-tomcat-7.0.39\bin\tomcat-juli.jar

Come nell'immagine sottostante


A questo punto il servizio è ripartito correttamente.

domenica 12 maggio 2013

Mapping tra java class e xsd

Nell'immagine allegata una tabella di riepilogo del mapping tra la  java class e l'xsd:


sabato 11 maggio 2013

Web service REST, non ereditarietà annotation

Nei servizi Web di tipo REST le annotazioni della superclasse valgono nella sottoclasse soltanto se quest'ultima a sua volta non ha annotazioni.
Quindi in questo caso:


public interface Itest
{
@GET@Produces("application/atom+xml")
int mioMetodo();
}
@Path("qwqwqw")
public class MyService implemets Itest
{
@Produces("application/atom+xml")
public int mioMetodo()
{
....
}

}


Le due annotazioni @GET e @Produces dell'interfaccia Itest non sono ereditate dalla classe implementante.

lunedì 29 aprile 2013

Script Ant per compilazione jasper report con groovy

In una web app con una serie di file jrxml creati con Groovy ecco uno script per la compilazione dei jrxml in modo da avere sempre i .jasper aggiornati.
I report sono stati creati con groovy, nel caso in cui fossero stati realizzati con Java standard allora si averebbe nella jrc come compiler la classe net.sf.jasperreports.engine.design.JRJdtCompiler invece della net.sf.jasperreports.compilers.JRGroovyCompiler.
I jrxml si trovano all'interno di una web app , sotto la directory reports.


 <project name="myProject" basedir="../" >
 <property file="ant/build.properties"/>
<target name="COMPILE-JASPER">
  <echo>Clean file jasper</echo>
  <delete verbose= "true" >
   <fileset dir="${webapp.target}/questionario" includes="*.jasper"/>
  </delete>
  <taskdef name="jrc" classname="net.sf.jasperreports.ant.JRAntCompileTask">
   <classpath refid="compile.classpath"/>
  </taskdef>
  <jrc srcdir ="${webapp.target}/questionario"
          destdir="${webapp.target}/questionario"
          keepjava="false"
          xmlvalidation="true"
          excludes="**/test/*.java,**/Test*.java,*.bak"
       compiler="net.sf.jasperreports.compilers.JRGroovyCompiler">
   <classpath refid="compile.classpath"/>
  </jrc>
 </target>

Lo script iniziale prevede la definizione di un file di properties build.properties dove sono definiti i valori del classpath e delle variabili a cui ci si riferisce nello script.



<?xml version="1.0" encoding="UTF-8"?>
<project>
 <property name="build.dir" value="${basedir}/build" />
 <property name="doc.dir" value="${basedir}/doc" />
 <property name="src" value="${basedir}/src" />
 <property name="test" value="${basedir}/test" />
 <property name="webapp.target" value="${basedir}/WebContent" />
 <property name="webapp.conf" value="${webapp.target}/conf" />
 <property name="webinf.dir" value="${webapp.target}/WEB-INF" />
 <property name="web.lib" value="${webinf.dir}/lib" />
 <property name="lib.lib" value="${basedir}/libProperties" />
 <property name="javac.debug" value="true" />
 <property name="compile.deprecation" value="true" />
 <property name="build.compiler" value="modern" />
 <property name="junit.fork" value="yes" />
 <property name="junit.showoutput" value="true" />
 <property environment="env" />
 <property name="env.COMPUTERNAME" value="${env.HOSTNAME}" />
 <property name="tomcat.home" value="${env.CATALINA_HOME}" />
 <property name="webapp.name" value="gianos-pro" />
 <property name="webapp.war" value="${webapp.name}.war" />
 <property name="webapp.ear" value="${webapp.name}.ear" />
 <property name="compile.jvm" value="1.6" />
 <property name="compile.debug" value="true" />
 <property name="compile.deprecation" value="false" />
 <property name="compile.optimize" value="false" />
 <path id="compile.classpath">
 .... altri jar utili al progetto .....
  <pathelement location="${web.lib}/jasperreports-4.7.0.jar"/>
  <pathelement location="${web.lib}/groovy-all-1.7.5.jar"/>
  <pathelement location="${web.lib}/jdt-compiler-3.1.1.jar"/>
  <pathelement location="${build.dir}/classes"/>
 </path>
</project>

sabato 27 aprile 2013

Windows 7 aggiungere messaggi custom allo start up del pc

Per inserire messaggi personalizzati all'avvio del pc bisogna modificare 2 chiavi nel registro di sistema.
Le chiavi sono :
  • legalnoticecaption;
  • legalnoticetext.
Da start digitare regedit quindi andare su HKEY_LOCAL_MACHINE/SOFTWARE/MICROSOFT/WINDOWS/CurrentVersion/Policies/System
Qui si trovano le due voci che si possono customizzare, la prima rappresenta l'intestazione dell'alert, la seconda il testo.
Saranno quindi sempre visibili al riavvio del sistema. Per rimuoverli è sufficiente cancellare il testo oppure cancellare direttamente le voci dal registro (per farlo è necessario essere amministratori del pc).


venerdì 26 aprile 2013

Web Service Rest con RestEasy

Resteasy è un framework realizzato da JBoss per realizzare servizi Rest (http://www.jboss.org/resteasy).
L'ho scaricato e testato su Tomcat 7, jdk 6 di riferimento.
Per realizzarlo ho creato una Web App, mettendo nella lib tutte le librerie del pacchetto tranne la el-api-1.0.jar, poichè andava in conflitto con le librerie di Tomcat 7 (linkage error).
Nel Web xml bisogna dichiarare la servlet di riferimento, in questo caso facciamo in modo che tutte le richieste che dopo il nome della web app hanno il suffisso /rest siano intercettate dalla servlet


<!-- Auto scan REST service -->
 <context-param>
  <param-name>resteasy.scan</param-name>
  <param-value>true</param-value>
 </context-param>
 
 <!-- this need same with resteasy servlet url-pattern -->
 <context-param>
  <param-name>resteasy.servlet.mapping.prefix</param-name>
  <param-value>/rest</param-value>
 </context-param>
 
 <listener>
  <listener-class>
   org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
  </listener-class>
 </listener>
 
 <servlet>
  <servlet-name>resteasy-servlet</servlet-name>
  <servlet-class>
   org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
  </servlet-class>
 </servlet>
 
 <servlet-mapping>
  <servlet-name>resteasy-servlet</servlet-name>
  <url-pattern>/rest/*</url-pattern>
 </servlet-mapping>
 

A questo punto dobbiamo scrivere il servizio Web.
Il servizio prende in input un intero e torna la lista dei numeri di Fibonacci fino a quell'intero assegnato.

Di seguito il codice


package it.test;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@Path("/calculator")
public class MessageService {
 @GET
 @Path("/{param}")
 public Response printMessage(@PathParam("param") int val) {
        List<Integer> fibNumbers=fib(val);
  return Response.status(200).entity(listaNumeri(fibNumbers)).build();
 }
 @GET
 @Path("lista/{param}")
 @Produces(MediaType.TEXT_PLAIN)
 public String getListaNumeri(@PathParam("param")int val){
   List<Integer> fibNumbers=fib(val);
   return listaNumeri(fibNumbers);
 }
 private String listaNumeri(List<Integer> lista){
  StringBuffer sb=new StringBuffer();
  sb.append("[ ");
  for(int i=0;i<lista.size();i++){
   sb.append(lista.get(i));
   if(i<lista.size()-1)
   sb.append(",");
  }
  sb.append(" ]");
  return sb.toString();
 }
 private  List<Integer> fib(int n) {
  List<Integer> retList=new ArrayList<Integer>();
        int prev1=0, prev2=1;
        for(int i=0; i<n; i++) {
            int savePrev1 = prev1;
            retList.add(savePrev1);
            prev1 = prev2;
            prev2 = savePrev1 + prev2;
        }
        return retList;
}
 
}



Gli url per ragiungere i 2 servizi sono:
  • http://localhost:8080/restfacile/rest/calculator/15 (richiama il metodo printMessage);
  • http://localhost:8080/restfacile/rest/calculator/lista/15 (richiama il metodo getListaNumeri).

Si può testare il servizio sia da url direttamente che con un client Java.
Per realizzare il client Java ho creato un progetto java normale, mettendo nelle dipendenze le classi di resteasy + il jar commons-logging-1.1.1.jar (altrimenti avevo errore di ClassNotFoundException).

Di seguito il client:


package start;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientResponse;
public class RestEasyClient {
 public static void main(String[] args) throws Exception {
   
  ClientRequest request = new ClientRequest(
    "http://localhost:8080/restfacile/rest/calculator/lista/15");
  ClientResponse<String> risposta=request.get(String.class);
  if (risposta.getStatus() != 200) {
   throw new RuntimeException("Errore di tipo : "
    + risposta.getStatus());
  }
  BufferedReader br = new BufferedReader(new InputStreamReader(
   new ByteArrayInputStream(risposta.getEntity().getBytes())));
  String output;
  System.out.println("Output ottenuto .... \n");
  while ((output = br.readLine()) != null) {
   System.out.println(output);
  }
 }

}