/** Copyright (c) 2007 Ricebridge. BSD License. */ package com.ricebridge.example.updown; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.util.Properties; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.fileupload.FileItemIterator; import org.apache.commons.fileupload.FileItemStream; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.fileupload.util.Streams; /** A servlet that handles upload and download requests. */ public class UpDownServlet extends HttpServlet { private static final long serialVersionUID = 1L; public static final String NUM_LINES = UpDownServlet.class.getName()+"-NUM_LINES"; public static final String INPUT_ERRORS = UpDownServlet.class.getName()+"-INPUT_ERRORS"; public static final String DATABASE_ERRORS = UpDownServlet.class.getName()+"-DATABASE_ERRORS"; private CsvUploader mCsvUploader = new CsvUploader(); private CsvDownloader mCsvDownloader = new CsvDownloader(); /** THESE ARE HARDCODED FOR SECURITY. DON'T USE HIDDEN FORM FIELDS. */ private String mTableName = "ClothingItem"; private String mIdentityColumn = "SKU"; /** Start an upload or download depending on the action parameter. */ public void service( HttpServletRequest pRequest, HttpServletResponse pResponse ) throws IOException { try { HttpSession session = pRequest.getSession(); // these are displayed on the JSP page session.setAttribute(NUM_LINES, null); session.setAttribute(INPUT_ERRORS, null); session.setAttribute(DATABASE_ERRORS, null); // we use the apache fileupload component ServletFileUpload upload = new ServletFileUpload(); FileItemIterator itemI = upload.getItemIterator( pRequest ); InputStream in = null; String action = null; Properties props = new Properties(); // get the form fields until we have file // note that the file has to be the last form field // as multipart data is provided as a stream while( itemI.hasNext() ) { FileItemStream item = itemI.next(); String name = item.getFieldName(); if( item.isFormField() ) { String value = Streams.asString( item.openStream() ); if( "action".equals(name) ) { action = value; } else { // set other form fields as properties // to be used by CsvSpecHandler props.setProperty( name, value ); } } else { // this is the CSV file in = item.openStream(); break; } } // look at the action if( "upload".equals(action) ) { doUpload( in, props, pRequest, pResponse ); } else if( "download".equals(action) ) { doDownload( props, pRequest, pResponse ); } else { throw new Exception("unknown action: ["+action+"]"); } } catch( Exception e ) { // you'll probably want to put in better logging here e.printStackTrace(); throw new IOException(e.toString()); } } /** Upload a CSV file. */ public void doUpload( InputStream pIn, Properties pProperties, HttpServletRequest pRequest, HttpServletResponse pResponse ) throws Exception { // get and store database connection Connection con = getConnection(); mCsvUploader.setDatabaseContext(con, mTableName, mIdentityColumn); // do the actual upload mCsvUploader.process(pIn, pProperties); // set results for display to user HttpSession session = pRequest.getSession(); session.setAttribute(NUM_LINES, new Long(mCsvUploader.getNumLines())); session.setAttribute(INPUT_ERRORS, mCsvUploader.getInputErrors()); session.setAttribute(DATABASE_ERRORS, mCsvUploader.getDatabaseErrors()); // redirect back to upload page pResponse.sendRedirect("upload.htm"); } /** Download a CSV file. */ public void doDownload( Properties pProperties, HttpServletRequest pRequest, HttpServletResponse pResponse ) throws Exception { // get and store database connection Connection con = getConnection(); mCsvDownloader.setDatabaseContext( con, mTableName ); // setup HTTP response // we can't set Content-length since we don't know it in advance pResponse.setContentType("text/csv"); pResponse.setHeader("Content-disposition", "attachment; filename="+ mTableName+".csv"); // stream data down mCsvDownloader.process( pResponse.getOutputStream(), pProperties); // no need for redirect as browser asks user to save CSV file } /** Get a connection to the database. * You'll want to change this to your own database connection details * and strategy. */ public static Connection getConnection() throws Exception { Class.forName( "com.mysql.jdbc.Driver" ); return DriverManager.getConnection( "jdbc:mysql://127.0.0.1:3306/test", "root", ""); } }