# HG changeset patch # User František Kučera # Date 1268518261 -3600 # Node ID a2e6f8fc4c345617a4f7db8584f91a5908f4b3e6 # Parent 619b0d3732eb69240870c4dd9ad818ca2567c4da Servlet pro zpřístupnění fotek, které se nacházejí ve zvláštním adresáři. diff -r 619b0d3732eb -r a2e6f8fc4c34 java/nekurak.net-web/src/java/cz/frantovo/nekurak/servlet/Fotky.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/java/nekurak.net-web/src/java/cz/frantovo/nekurak/servlet/Fotky.java Sat Mar 13 23:11:01 2010 +0100 @@ -0,0 +1,118 @@ +package cz.frantovo.nekurak.servlet; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Pattern; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * Servlet pro zpřístupnění fotek, které se nacházejí ve zvláštním adresáři. + * + * Má jeden inicializační parametr: + * adresar – cesta k adresáři na disku, kde se nacházejí fotky. + * např. /var/www/nekurak.net/fotky + * + * Očekává se struktura adresářů tohoto typu: + * Plné rozlišení: /var/www/nekurak.net/fotky/original/1.jpg + * Náhled fotky: /var/www/nekurak.net/fotky/nahled/1.jpg + * Lze ovlivnit konstantami níže + * @author fiki + */ +public class Fotky extends HttpServlet { + + /** Název inicializačního parametru */ + private static final String INIT_ADRESAR = "adresar"; + /** Název podadresáře obsahujícího fotku v plném rozlišení */ + private static final String PODADRESAR_ORIGINAL = "original"; + /** Název podadresáře obsahujícího výchozí náhled fotky */ + private static final String PODADRESAR_NAHLED = "nahled"; + private static final String PRIPONA = "jpg"; + private static final String LOMITKO = File.separator; + /** Regulární výraz */ + private static final String VZOR_CESTY = "^" + LOMITKO + "(" + PODADRESAR_ORIGINAL + "|" + PODADRESAR_NAHLED + ")" + LOMITKO + "\\d+\\." + PRIPONA + "$"; + private static final String MIME_TYP = "image/jpeg"; + private File adresar; + private static final Logger log = Logger.getLogger(Fotky.class.getSimpleName()); + + @Override + public void init() throws ServletException { + super.init(); + String initAdresar = getServletConfig().getInitParameter(INIT_ADRESAR); + adresar = new File(initAdresar); + if (adresar.isDirectory()) { + log.log(Level.INFO, "Servlet „Fotka“ byl úspěšně inicializován."); + log.log(Level.INFO, "Adresář s fotkami: " + initAdresar); + log.log(Level.INFO, "RegExp cesty: " + VZOR_CESTY); + } else { + throw new ServletException("Servlet „Fotka“ se nepodařilo inicializovat. Cesta: " + initAdresar); + } + } + + /** + * @param pozadavek pouze GET (není důvod podporovat POST) + * @param odpoved + * @throws ServletException např. pokud parametr id není číslo + * @throws IOException + */ + @Override + protected void doGet(HttpServletRequest pozadavek, HttpServletResponse odpoved) throws ServletException, IOException { + + String cesta = zkontrolujParametr(pozadavek.getPathInfo()); + File soubor = new File(adresar, cesta); + + if (soubor.isFile() && soubor.canRead()) { + + if (soubor.lastModified() > pozadavek.getDateHeader("If-Modified-Since")) { + /** Soubor se změnil nebo ho klient ještě nemá načtený. */ + odpoved.setContentType(MIME_TYP); + odpoved.setContentLength((int) soubor.length()); + odpoved.setDateHeader("Last-Modified", soubor.lastModified()); + + ServletOutputStream out = odpoved.getOutputStream(); + InputStream in = new FileInputStream(soubor); + + try { + byte[] bytes = new byte[1024]; + int bajtuNacteno; + while ((bajtuNacteno = in.read(bytes)) != -1) { + out.write(bytes, 0, bajtuNacteno); + } + } catch (Exception e) { + throw new ServletException("Chyba při odesílání obrázku klientovi.", e); + } finally { + in.close(); + out.close(); + } + } else { + /** Soubor se od posledního načtení klientem nezměnil → není potřeba ho posílat znova. */ + odpoved.setStatus(HttpServletResponse.SC_NOT_MODIFIED); + } + + } else { + /** Neexistující nebo nečitelný soubor → HTTP 404 chyba */ + odpoved.sendError(HttpServletResponse.SC_NOT_FOUND); + } + } + + /** + * @param cesta cesta požadovaná klientem: request.getPathInfo(); + * @throws ServletException pokud cesta nevyhovuje vzoru + */ + private static String zkontrolujParametr(String cesta) throws ServletException { + if (Pattern.matches(VZOR_CESTY, cesta)) { + /** cesta je v pořádku → pokračujeme */ + return cesta; + } else { + /** Chybná cesta → HTTP 500 chyba */ + throw new ServletException("Chybná cesta k obrázku: " + cesta); + } + } +} diff -r 619b0d3732eb -r a2e6f8fc4c34 java/nekurak.net-web/web/WEB-INF/web.xml --- a/java/nekurak.net-web/web/WEB-INF/web.xml Thu Mar 11 11:55:52 2010 +0100 +++ b/java/nekurak.net-web/web/WEB-INF/web.xml Sat Mar 13 23:11:01 2010 +0100 @@ -1,61 +1,80 @@ - 30 + 30 - - index.jsp + index.jsp - + - - 404 - /WEB-INF/chyby/404.jsp + + 404 + /WEB-INF/chyby/404.jsp - - 500 - /WEB-INF/chyby/500.jsp + + 500 + /WEB-INF/chyby/500.jsp - + + - atom - /WEB-INF/atom/atom.jsp + atom + /WEB-INF/atom/atom.jsp - + + + Servlet zpřístupňující fotky umístěné ve zvláštním adresáři + (data oddělená od aplikace). + + fotky + cz.frantovo.nekurak.servlet.Fotky + + + Adresář na disku, který obsahuje fotky podniků. + Musí existovat při startu aplikace. + + adresar + /var/www/nekurak.net/fotky + + + + - atom - /atom/* + fotky + /fotky/* - + + atom + /atom/* + + - - javax.servlet.jsp.jstl.fmt.fallbackLocale - cs + + javax.servlet.jsp.jstl.fmt.fallbackLocale + cs - - opravneny + opravneny - - Správa Nekuřák.net - /sprava/* - - - opravneny - + + Správa Nekuřák.net + /sprava/* + + + opravneny + - FORM - nekurakNET - - /?akce=prihlaseni - /?akce=prihlaseni&chyba=ano - + FORM + nekurakNET + + /?akce=prihlaseni + /?akce=prihlaseni&chyba=ano + -