28/10/2013

[Java 4] Download file from portlet v1.0

Same scenario as last time, but a cleaner solution: link a servlet directly from a JSP page and have the server serve the file as a response instead of a new JSP.

Suppose we want the user to download some file identified by someFile, we should place this code in our JSP, issuing a GET from a particular servlet we wrote:

 <a href=" <%=(request.getContextPath() + "/ResourceServlet?method=getFile&idFile=someId")%>">  
 Grab your file  
 </a>  


Then, we should add this servlet to our portlet, we'll call it ResourceServlet, implementing our method getFile which accepts the id of the file to be downloaded as a parameter:

 import javax.servlet.ServletException;  
 import javax.servlet.ServletOutputStream;  
 import javax.servlet.http.HttpServlet;  
 import javax.servlet.http.HttpServletRequest;  
 import javax.servlet.http.HttpServletResponse;  
   
 import org.springframework.context.ApplicationContext;  
 import org.springframework.web.context.support.WebApplicationContextUtils;  
   
 import com.ibm.xmi.mod.InternalErrorException;  
   
   
 public class ResourceServlet extends HttpServlet {  
      private static final long serialVersionUID = 1L;  
   
      public static final String METHOD_GET_ATTACHMENT = "getFile" ;  
   
      public ResourceServlet() {  
           super();  
      }  
   
      protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
           String method=request.getParameter("method");  
           if (method != null && method.equalsIgnoreCase(METHOD_GET_ATTACHMENT)) {  
                this.getFile(request, response) ;  
           } else {  
                throw new ServletException("method <"+method+"> not defined for ResourceServlet");  
           }  
      }  
   
      protected void getFile(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
           String idFile=request.getParameter("idFile");  
   
           if (idFile == null || idFile.equalsIgnoreCase(""))  
           throw new ServletException("Invalid or non-existent idFile parameter in ResourceServlet.");  
   
           idFile = idFile.replaceAll("^\\s+|\\s+$", "") ; // Remove space  
   
           ServletOutputStream stream = null;  
           try {  
                ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(getServletContext());  
   
                if (context != null) {  
                     //get the file from the DB  
                     File f = [...]//someClass.getMyFile(idFile);  
                     if (f != null) {  
                          response.reset() ;  
                          stream = response.getOutputStream();  
                          response.setContentType("application/pdf");//or whatever type you need  
                          response.addHeader("Content-Disposition", "attachment; filename="+ f.getName());  
                          stream.write(f.getBytes(1,((int)f.length())));  
                     } else {  
                          throw new ServletException("file is null!");  
                     }  
                }   
           } catch (IOException ioe) {  
                throw new ServletException(ioe.getMessage());  
           } finally {  
                if (stream != null)  
                stream.close();  
           }  
      }  
   
      protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
           doGet(request, response);  
      }  
   
 }  
   


That's it; when the user clicks the link, the file is recovered from the database and prepared for the user to download, we no longer have to store it inside our WAR; the only downside is we're mixing servlets with our portlet.


No comments:

Post a Comment

With great power comes great responsibility