/* * NOM DU FICHIER : FileDownload.java * * DATE DE CREATION : 2009/02/01 * * REMARQUES : * * * MODIFICATIONS : * * -no. de la version/révision : * -auteur : * -date : * -raison : * -nature : * * * 0. DECLARATIONS * */ package fr.ign.api.web; /* * 0.1. BIBLIOTHÉQUES DE SERVLETS */ import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.ServletException; /* * 0.2. BIBLIOTHÉQUES Java */ import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import org.apache.log4j.Logger; /** *

BUT DE LA SERVLET :

* * Cette servlet FileDownload permet de retourner un flux au client lui permettant de l'enregistrer. * * Elle est identifiée dans le descripteur de déploiement web.xml par :
*

 * <servlet-name>FileDownload</servlet-name>
 * <servlet-class>fr.ign.api.web.FileDownload</servlet-class>
 * <url-pattern>/geoportail/save</url-pattern>
 * 
* * @author DGR * @version v0.0.1, 2009/02/01 */ public class FileDownload extends HttpServlet { /* * 0.2. CHAMPS * * 0.2.1. CONSTANTES */ /** * Paramètre type de contenu 'CT'. */ private final static String gkCT_PARAMETER_NAME= "CT"; /** * Paramètre nom du fichier 'FN'. */ private final static String gkFN_PARAMETER_NAME= "FN"; /** * Paramètre données à retourner 'DT'. */ private final static String gkDT_PARAMETER_NAME= "DT"; /** * Content-Type par défaut. */ private final static String gkDEFAULT_CONTENT_TYPE= "application/xml"; /** * Nom du fichier par défaut. */ private final static String gkDEFAULT_FILENAME= "out"; /** * Trace Log4J de la servlet. */ private static final Logger logger= Logger.getLogger(FileDownload.class); /* * 0.2.2. VARIABLES D'INSTANCES */ /** * Configuration courante : * @see #init */ private ServletConfig _SC= null ; /* * 0.3. MÉTHODES * * 0.3.1. MÉTHODES DE LA CLASSE * * jamais */ /* * 0.3.2. MÉTHODES D'INSTANCE * * les prototypes sont ci-dessous */ /** * Sauvegarde de la configuration de la servlet : * @param config configuration de la servlet * @see java.lang.String getInitParameter (java.lang.String name); * @see java.util.Enumeration getInitParameterNames (); * @see ServletContext getServletContext (): */ private final void _setSC ( ServletConfig config ) { this._SC= config ; }// _setSC /** * Récupération de la configuration de la servlet : * @return configuration de la servlet lors de son initialisation */ private final ServletConfig _getSC ( ) { return this._SC ; }// _getSC /** * Initialisation de la servlet : * @param config configuration de la servlet * @throws javax.servlet.ServletException échec de l'initialisation de la servlet */ public final void init ( ServletConfig config ) throws ServletException { try { super.init(config) ; // toujours la première instruction _setSC(config) ; } catch (ServletException e) { throw e ; } }// init /** * Gestion de la requête HTTP DELETE : effacer un document sur le serveur. * @param rqst requête provenant de l'utilisateur * @param resp réponse du serveur à l'utilisateur * @throws javax.servlet.ServletException * @throws java.io.IOException */ public final void doDelete ( HttpServletRequest rqst, HttpServletResponse resp ) throws ServletException, IOException { resp.sendError(HttpServletResponse.SC_FORBIDDEN); return; }// doDelete /** * Gestion de la requête HTTP GET : récupérer une ressource sur le serveur. * @param rqst requête provenant de l'utilisateur. Le paramètre ct définit le type de contenu à retourner à l'application * cliente (Content-Type). Le paramètre fn définit le nom du fichier pour l'application cliente. Le paramètre obligatoire * dt contient les données à retourner à l'application cliente. * @param resp réponse du serveur à l'utilisateur * @throws javax.servlet.ServletException * @throws java.io.IOException */ public final void doGet ( HttpServletRequest rqst, HttpServletResponse resp ) throws ServletException, IOException { Map rqstParams= new HashMap(); String paramName= null; String paramValue= null; Enumeration pns= rqst.getParameterNames(); while (pns.hasMoreElements()) { paramName= (String)pns.nextElement(); paramValue= rqst.getParameter(paramName); rqstParams.put(paramName.toUpperCase(),paramValue); } paramName= FileDownload.gkDT_PARAMETER_NAME; if (!rqstParams.containsKey(paramName)) { logger.error("Missing data parameter"); resp.sendError(HttpServletResponse.SC_BAD_REQUEST); return; } paramName= FileDownload.gkCT_PARAMETER_NAME; if (!rqstParams.containsKey(paramName)) { rqstParams.put(paramName, FileDownload.gkDEFAULT_CONTENT_TYPE); } paramName= FileDownload.gkFN_PARAMETER_NAME; if (!rqstParams.containsKey(paramName)) { rqstParams.put(paramName, FileDownload.gkDEFAULT_FILENAME); } resp.setContentType("application/force-download"); resp.setHeader("Content-Transfer-Encoding", (String)rqstParams.get(FileDownload.gkCT_PARAMETER_NAME)); resp.setHeader("Pragma","no-cache"); resp.setHeader("Cache-Control","must-revalidate, post-check=0, pre-check=0, public"); resp.setHeader("Expires","0"); resp.setHeader("Content-disposition","attachment; filename="+(String)rqstParams.get(FileDownload.gkFN_PARAMETER_NAME)); ServletOutputStream os= resp.getOutputStream(); os.println((String)rqstParams.get(FileDownload.gkDT_PARAMETER_NAME)); os.flush(); return; }// doGet // Gestion de la requête HTTP HEAD ? /** * Gestion de la requête HTTP OPTIONS : savoir quelles autres méthodes * peuvent être utilisées pour ce document. * @param rqst requête provenant de l'utilisateur * @param resp réponse du serveur à l'utilisateur * @throws javax.servlet.ServletException * @throws java.io.IOException */ public final void doOptions ( HttpServletRequest rqst, HttpServletResponse resp ) throws ServletException, IOException { resp.sendError(HttpServletResponse.SC_FORBIDDEN); return; }// doOptions /** * Gestion de la requête HTTP POST : fournir des informations au serveur. * @param rqst requête provenant de l'utilisateur. Le paramètre ct définit le type de contenu à retourner à l'application * cliente (Content-Type). Le paramètre fn définit le nom du fichier pour l'application cliente. Le paramètre obligatoire * dt contient les données à retourner à l'application cliente. Le corps de la requête peut contenir les données à * retourner si le POST n'est pas du type "application/x-www-form-urlencoded". * @param resp réponse du serveur à l'utilisateur * @throws javax.servlet.ServletException * @throws java.io.IOException */ public void doPost ( HttpServletRequest rqst, HttpServletResponse resp ) throws ServletException, IOException { String contentType= rqst.getContentType(); if (contentType!=null) { // Cf. http://www.w3.org/TR/REC-html40/interact/forms.html#form-content-type contentType= contentType.toLowerCase(); //Si le POST est du type application/x-www-form-urlencoded //alors la requête peut être prise en charge par GET. if ("application/x-www-form-urlencoded".equals(contentType)) { this.doGet(rqst,resp); return; } //type multipart/form-data, interdit ! if ("multipart/form-data".equals(contentType)) { resp.sendError(HttpServletResponse.SC_FORBIDDEN); return; } } else { contentType= FileDownload.gkDEFAULT_CONTENT_TYPE; } // le corps du POST contient les données: resp.setContentType("application/force-download"); resp.setHeader("Content-Transfer-Encoding", contentType); resp.setHeader("Pragma","no-cache"); resp.setHeader("Cache-Control","must-revalidate, post-check=0, pre-check=0, public"); resp.setHeader("Expires","0"); resp.setHeader("Content-disposition","attachment; filename="+FileDownload.gkDEFAULT_FILENAME); InputStream is= rqst.getInputStream(); OutputStream os= resp.getOutputStream(); int nBytes; byte[] buff= new byte[1024]; while ((nBytes= is.read(buff))>-1) { os.write(buff,0,nBytes); } os.flush(); os.close(); is.close(); return; }// doPost /** * Gestion de la requête HTTP PUT : fournir un document au serveur. * @param rqst requête provenant de l'utilisateur * @param resp réponse du serveur à l'utilisateur * @throws javax.servlet.ServletException * @throws java.io.IOException */ public void doPut ( HttpServletRequest rqst, HttpServletResponse resp ) throws ServletException, IOException { resp.sendError(HttpServletResponse.SC_FORBIDDEN); return; }// doPut /** * Gestion de la requête HTTP TRACE : demander aux serveurs d'autorisation (proxies) * de se déclarer dans les en-t�tes HTTP. * @param rqst requête provenant de l'utilisateur * @param resp réponse du serveur à l'utilisateur * @throws javax.servlet.ServletException * @throws java.io.IOException */ public void doTrace ( HttpServletRequest rqst, HttpServletResponse resp ) throws ServletException, IOException { resp.sendError(HttpServletResponse.SC_FORBIDDEN); return; }// doTrace // Gestion de la requête HTTP CONNECT ? // Gestion de la requête HTTP LINK ? // Gestion de la requête HTTP UNLINK ? // Gestion de la requête HTTP PATCH ? /** * Destruction de la servlet : */ public void destroy ( ) { super.destroy() ; // toujours la dernière instruction }// destroy } // FileDownload