SERVEI D'UPLOAD

Introducció







Propósit

Aquest servei permet que poguem llegir tractar els fitxers que hagin adjuntat els usuaris des dels formularis HTML en el seu navegador Web. Aquest tractament pot ser llegir el fitxer de forma directa, desar-lo al sistema de fitxers o per exemple emmagatzemar-lo en una base de dades.

Context i Escenaris d'Ús

El Servei de Upload de Fitxers es troba ubicat dins els serveis continguts a la capa de Presentació de Canigó.

Versions i Dependències

Les dependències descrites a la següent url són requerides per tal de compilar i fer funcionar el projecte:
Dependències Servei d'Upload

A qui va dirigit

Aquest document va dirigit als següents perfils:

  1. Programador. Per conéixer l'ús del servei
  2. Arquitecte. Per conéixer quins són els components i la configuració del servei

Documents i Fonts de Referència

[1] Spring File Upload http://static.springframework.org/spring/docs/1.2.x/reference/mvc.html#mvc-multipart

Descripció Detallada

Arquitectura i Components

Els components podem classificar-los en:

  1. Interfícies i Components Genérics. Interfícies del servei i components d'ús general amb independència de la implementació escollida.
  2. Implementació basada en Spring
    Es pot trobar tota la documentació JavaDoc i el codi font referent aquests components a les següents urls:

+JavaDoc: http://canigo.ctti.gencat.net/confluence/canigodocs/site/canigo2_0/canigo-services-fileupload/apidocs/index.html
+Codi Font: http://canigo.ctti.gencat.net/confluence/canigodocs/site/canigo2_0/canigo-services-fileupload/xref/index.html

Instal.lació i Configuració

Instal.lació

La instal.lació del servei requereix de la utilització de la llibreria 'canigo-services-fileupload' i les dependències indicades a l'apartat 'Introducció-Versions i Dependències'.

Configuració

La configuració del Servei implica els següents pasos:

  1. Definir la implementació del Servei que s'usarà
  2. Definir la localització del fitxer de propietats del servei
  3. Definir les propietats del servei

Definició del Servei

Fitxer de configuració: canigo-services-fileupload.xml

Ubicació proposada: <PROJECT_ROOT>/src/main/resources/spring

Indicar el bean del servei (amb id 'fileUploadService') i la implementació escollida. Per la implementació 'FileUploadServiceImpl' definirem les següents propietats:

Propietat Requerit Descripció
maxAttachmentSize No Màxim tamany permés abans que es rebutgin els fitxers. Valor per defecte: 1 (no hi ha límit). Usar millor una referència per definir el seu valor en un fitxer extern (veure 'Definició de les Propietats del Servei')
logService No Referència al Servei de Traces
resolver Detector de càrrega de fitxers. Usar el valor
'org.springframework.web.multipart.commons.CommonsMultipartResolver'

Exemple:

<bean id="uploadResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
</bean>

<bean id="fileUploadService" class="net.gencat.ctti.canigo.services.fileupload.impl.
FileUploadServiceImpl">
    <property name="maxAttachmentSize" value="$\{fileUploadService.maxAttachmentSize\}"/>
    <property name="logService" ref="loggingService"/>
    <property name="resolver" ref="uploadResolver"/>
</bean>


Definició de la Localització del Fitxer de Propietats del Servei


Fitxer de configuració: canigo-services-configuration.xml
Ubicació proposada: <PROJECT_ROOT>/src/main/resources/spring

Seguint el propòsit general del Servei de Configuració definirem a la propietat 'basePropertyFiles' una nova localització pel fitxer de propietats del servei.

Exemple:

<bean id="configurationService" class="net.gencat.ctti.canigo.services.configuration.
springframework.beans.factory.config.HostPropertyPlaceholderConfigurer">
    <property name="basePropertyFiles">
        <list>
            <value>classpath:jdbc/jdbc.properties</value>
            <value>classpath:mail/mail.properties</value>
            <value>classpath:file/fileUploadService.properties</value>
            <value>classpath:file/fileService.properties</value>
        </list>
    </property>
</bean>


Definició de les Propietats del Servei

Fitxer de configuració: fileUploadService.properties
Ubicació proposada: <PROJECT_ROOT>/src/main/resources/file
En aquest fitxer definirem les propietats que permet el servei (veure 'Definició del Servei')
Exemple:
fileUploadService.maxAttachmentSize=1024


Utilització del Servei

La utilització del servei comporta 2 pasos:

  1. Definir la pàgina JSP
  2. Definir l'accés des de la classe Action

Definició de la pàgina JSP

A la pàgina JSP cal fer tenir en consideració:

  1. En el tag <form> (veure 'Servei de Tags') assegurar-se de definir les propietats i valors:
  2. method="post"
  3. enctype="multipart/form-data"

Exemple:

<fwk:form action="files.do" styleId="actionForm" reqCode="upload" width="500"
method="post" enctype="multipart/form-data">


  1. Usar el tag '<file>' (veure document 'Servei de Tags')
    <fwk:file styleId="tramitFile" property="tramitFile"/>


    Accés des de la classe Action

Canigó exposa una interfície d'utilització, "net.gencat.ctti.canigo.fileupload.FileUploadService", que amaga la implementació real. La interfície té el següent aspecte:

package net.gencat.ctti.canigo.services.fileupload*;*

...

/**
* Interface to detect fileUploads.
*
*/
public interface FileUploadService {
    public static final String FILE_UPLOAD_BEAN_FACTORY_KEY="FileUploadService";
    UploadedFiles getUploadedFiles(HttpServletRequest request, String[] fieldsToBind);
}


Aquesta interfíciee només exposa un métode 'getUploadedFiles' que a partir del 'HttpServletRequest' retorna un objecte de tipus UploadedFiles. Aquest objecte permet obtenir cadascun dels fitxers enviats.
Així, podem realitzar les següents crides:

  1. getFile(String tagId): obtenir el contingut del fitxer que s'adjuntat en el camp del formulari amb el nom indicat a 'tagId'
  2. isFileAvailable(String tagId): comprovar que s'ha adjuntat un fitxer en el camp del formulari amb nom indicat amb 'tagId'
  3. hasFiles: comprovar si s'han adjuntat fitxers
    public interface UploadedFiles {
        ...
        public UploadedFile getFile(String tagId);
        public boolean isFileAvailable(String tagId);
        public boolean hasFiles();
    }



    Per últim, una vegada obtingut un 'UploadFile' en concret podem obtenir la seva informació i les seves dades de vàries formes (veure la signatura dels mètodes continguts a la interfície).
    public interface UploadedFile {
        String getName();
             boolean isEmpty();
             String getOriginalFilename();
             String getContentType();
             long getSize();
             byte[] getBytes() throws IOException;
        InputStream getInputStream() throws IOException;
        void transferTo(File dest) throws IOException, IllegalStateException;
    }


    Val la pena observar que mitjançant el métode getInputStream es possible llegit l'objecte per tal de transferir-lo per entrada-sortida java convencional, però a més el mètode "transferTo" possibilita exportar el fitxer pujar a un destí de fitxer en el servidor.

    Si hi ha qualsevol error com per exemple que excedeixi el límit configurable de tamany de fitxers, la implementació llença una "net.gencat.ctti.canigo.services.fileupload.exception.FileServiceException" on s'especifican els detalls de l'error (error, codi d'error, capa i subsistema).

    Integració amb Altres Serveis

Integració amb el Servei Multiidioma i Excepcions

El Servei de Upload de Fitxers llença vàries excepcions amb codis per tal que el missatge pugui ser internacionalitzat. En el següent exemple es mostren els codis que s'han de definir:

canigo.services.fileupload.attachment_size_exceeded=Attachment size exceeded: {0} bytes (max: {1}*)*
canigo.services.fileupload.error_resolving_multipart_uploads=Error retrieving file {0} from request

Exemples

Exemple

Exemple de formulari


<fwk:form action="files.do" styleId="actionForm" reqCode="upload" width="500"
method="post" enctype="multipart/form-data">
    <fwk:text styleId="currentDir" property="currentDir"/>
    <fwk:file styleId="file" property="file"/>
    <fwk:submit styleId="uploadActionImage"/>
</fwk:form>











Exemple d'accés des de la Action


UploadedFiles files = FileUploadServiceUtils.getFiles(
context.getRequest(),
new String[] {"file1"});
if(files.hasFiles()){
    if(files.isFileAvailable("file1")){
        UploadedFile file1 = files.getFile("file1");
    }
}







En aquest cas hem fet servir el mètode estàtic "getFiles" de la classe auxiliar
"net.gencat.ctti.canigo.services.fileupload.FileUploadServiceUtils"
Aquest mètode permet utilitzar el servei sense haver de localitzar-lo expressament.