X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=zxingorg%2Fsrc%2Fcom%2Fgoogle%2Fzxing%2Fweb%2FDecodeServlet.java;h=2f5e198f0e54f3b33edae7d12d4f9ee475563e63;hb=cbbe19fc92712a52b51b606461021235551babd0;hp=e60536c31fc55d3b0d11d8f163cd32d13aefdf99;hpb=04353cf105a84f2c81312e069fc64202e669c78d;p=zxing.git diff --git a/zxingorg/src/com/google/zxing/web/DecodeServlet.java b/zxingorg/src/com/google/zxing/web/DecodeServlet.java index e60536c3..2f5e198f 100644 --- a/zxingorg/src/com/google/zxing/web/DecodeServlet.java +++ b/zxingorg/src/com/google/zxing/web/DecodeServlet.java @@ -16,113 +16,122 @@ package com.google.zxing.web; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.BinaryBitmap; import com.google.zxing.DecodeHintType; +import com.google.zxing.LuminanceSource; import com.google.zxing.MultiFormatReader; import com.google.zxing.Reader; import com.google.zxing.ReaderException; import com.google.zxing.Result; -import com.google.zxing.client.j2se.BufferedImageMonochromeBitmapSource; +import com.google.zxing.client.j2se.BufferedImageLuminanceSource; import com.google.zxing.client.result.ParsedResult; import com.google.zxing.client.result.ResultParser; +import com.google.zxing.common.GlobalHistogramBinarizer; +import com.google.zxing.common.HybridBinarizer; + import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; +import org.apache.commons.lang.StringEscapeUtils; import org.apache.http.Header; -import org.apache.http.HttpException; import org.apache.http.HttpMessage; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; +import org.apache.http.HttpEntity; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; -import org.apache.http.conn.PlainSocketFactory; -import org.apache.http.conn.Scheme; -import org.apache.http.conn.SchemeRegistry; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.conn.scheme.PlainSocketFactory; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.conn.ssl.SSLSocketFactory; +import org.apache.http.conn.ClientConnectionManager; import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; +import org.apache.http.impl.conn.SingleClientConnManager; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpParams; import org.apache.http.params.HttpProtocolParams; -import javax.imageio.ImageIO; -import javax.mail.Authenticator; -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import java.io.Writer; +import java.net.SocketException; import java.net.URI; import java.net.URISyntaxException; import java.net.UnknownHostException; -import java.util.Arrays; import java.util.Hashtable; import java.util.List; -import java.util.Timer; +import java.util.Vector; import java.util.logging.Logger; +import javax.imageio.ImageIO; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + /** * {@link HttpServlet} which decodes images containing barcodes. Given a URL, it will * retrieve the image and decode it. It can also process image files uploaded via POST. - * - * @author Sean Owen (srowen@google.com) + * + * @author Sean Owen */ public final class DecodeServlet extends HttpServlet { private static final long MAX_IMAGE_SIZE = 500000L; - private static final long EMAIL_CHECK_INTERVAL = 2L * 60 * 1000; private static final Logger log = Logger.getLogger(DecodeServlet.class.getName()); static final Hashtable HINTS; static { - HINTS = new Hashtable(3); + HINTS = new Hashtable(5); HINTS.put(DecodeHintType.TRY_HARDER, Boolean.TRUE); + Vector possibleFormats = new Vector(); + possibleFormats.add(BarcodeFormat.UPC_A); + possibleFormats.add(BarcodeFormat.UPC_E); + possibleFormats.add(BarcodeFormat.EAN_8); + possibleFormats.add(BarcodeFormat.EAN_13); + possibleFormats.add(BarcodeFormat.CODE_39); + possibleFormats.add(BarcodeFormat.CODE_128); + possibleFormats.add(BarcodeFormat.ITF); + possibleFormats.add(BarcodeFormat.QR_CODE); + possibleFormats.add(BarcodeFormat.DATAMATRIX); + possibleFormats.add(BarcodeFormat.PDF417); + HINTS.put(DecodeHintType.POSSIBLE_FORMATS, possibleFormats); } - private HttpClient client; + private HttpParams params; + private SchemeRegistry registry; private DiskFileItemFactory diskFileItemFactory; - private Timer emailTimer; @Override - public void init(ServletConfig servletConfig) throws ServletException { + public void init(ServletConfig servletConfig) { Logger logger = Logger.getLogger("com.google.zxing"); logger.addHandler(new ServletContextLogHandler(servletConfig.getServletContext())); - String emailAddress = servletConfig.getInitParameter("emailAddress"); - String emailPassword = servletConfig.getInitParameter("emailPassword"); - if (emailAddress == null || emailPassword == null) { - throw new ServletException("emailAddress or emailPassword not specified"); - } - - HttpParams params = new BasicHttpParams(); + params = new BasicHttpParams(); HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); - SchemeRegistry registry = new SchemeRegistry(); + registry = new SchemeRegistry(); registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); registry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443)); - client = new DefaultHttpClient(new ThreadSafeClientConnManager(params, registry), params); - diskFileItemFactory = new DiskFileItemFactory(); - Authenticator emailAuthenticator = new EmailAuthenticator(emailAddress, emailPassword); - emailTimer = new Timer("Email decoder timer", true); - emailTimer.schedule(new DecodeEmailTask(emailAddress, emailAuthenticator), 0L, EMAIL_CHECK_INTERVAL); - log.info("DecodeServlet configured"); } @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - + protected void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { String imageURIString = request.getParameter("u"); if (imageURIString == null || imageURIString.length() == 0) { response.sendRedirect("badurl.jspx"); @@ -141,10 +150,33 @@ public final class DecodeServlet extends HttpServlet { return; } - HttpGet getRequest = new HttpGet(imageURI); + ClientConnectionManager connectionManager = new SingleClientConnManager(params, registry); + HttpClient client = new DefaultHttpClient(connectionManager, params); + + HttpUriRequest getRequest = new HttpGet(imageURI); + getRequest.addHeader("Connection", "close"); // Avoids CLOSE_WAIT socket issue? try { - HttpResponse getResponse = client.execute(getRequest); + + HttpResponse getResponse; + try { + getResponse = client.execute(getRequest); + } catch (IllegalArgumentException iae) { + // Thrown if hostname is bad or null + getRequest.abort(); + response.sendRedirect("badurl.jspx"); + return; + } catch (SocketException se) { + // Thrown if hostname is bad or null + getRequest.abort(); + response.sendRedirect("badurl.jspx"); + return; + } catch (UnknownHostException uhe) { + getRequest.abort(); + response.sendRedirect("badurl.jspx"); + return; + } + if (getResponse.getStatusLine().getStatusCode() != HttpServletResponse.SC_OK) { response.sendRedirect("badurl.jspx"); return; @@ -153,22 +185,19 @@ public final class DecodeServlet extends HttpServlet { response.sendRedirect("badimage.jspx"); return; } + log.info("Decoding " + imageURI); - InputStream is = getResponse.getEntity().getContent(); + HttpEntity entity = getResponse.getEntity(); + InputStream is = entity.getContent(); try { processStream(is, request, response); } finally { + entity.consumeContent(); is.close(); } - } catch (InterruptedException ie) { - getRequest.abort(); - response.sendRedirect("badurl.jspx"); - } catch (HttpException he) { - getRequest.abort(); - response.sendRedirect("badurl.jspx"); - } catch (UnknownHostException uhe) { - getRequest.abort(); - response.sendRedirect("badurl.jspx"); + + } finally { + connectionManager.shutdown(); } } @@ -209,8 +238,8 @@ public final class DecodeServlet extends HttpServlet { } - private static void processStream(InputStream is, HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { + private static void processStream(InputStream is, ServletRequest request, + HttpServletResponse response) throws ServletException, IOException { BufferedImage image = ImageIO.read(is); if (image == null) { response.sendRedirect("badimage.jspx"); @@ -220,7 +249,9 @@ public final class DecodeServlet extends HttpServlet { Reader reader = new MultiFormatReader(); Result result; try { - result = reader.decode(new BufferedImageMonochromeBitmapSource(image), HINTS); + LuminanceSource source = new BufferedImageLuminanceSource(image); + BinaryBitmap bitmap = new BinaryBitmap(new GlobalHistogramBinarizer(source)); + result = reader.decode(bitmap, HINTS); } catch (ReaderException re) { log.info("DECODE FAILED: " + re.toString()); response.sendRedirect("notfound.jspx"); @@ -240,12 +271,24 @@ public final class DecodeServlet extends HttpServlet { request.setAttribute("result", result); byte[] rawBytes = result.getRawBytes(); if (rawBytes != null) { - request.setAttribute("rawBytesString", Arrays.toString(rawBytes)); + request.setAttribute("rawBytesString", arrayToString(rawBytes)); } else { request.setAttribute("rawBytesString", "(Not applicable)"); } - ParsedResult parsedResult = ResultParser.parseReaderResult(result); + String text = result.getText(); + if (text != null) { + request.setAttribute("text", StringEscapeUtils.escapeXml(text)); + } else { + request.setAttribute("text", "(Not applicable)"); + } + ParsedResult parsedResult = ResultParser.parseResult(result); request.setAttribute("parsedResult", parsedResult); + String displayResult = parsedResult.getDisplayResult(); + if (displayResult != null) { + request.setAttribute("displayResult", StringEscapeUtils.escapeXml(displayResult)); + } else { + request.setAttribute("displayResult", "(Not applicable)"); + } request.getRequestDispatcher("decoderesult.jspx").forward(request, response); } } @@ -261,10 +304,31 @@ public final class DecodeServlet extends HttpServlet { return true; } + private static String arrayToString(byte[] bytes) { + int length = bytes.length; + StringBuilder result = new StringBuilder(length << 2); + int i = 0; + while (i < length) { + int max = Math.min(i + 8, length); + for (int j = i; j < max; j++) { + int value = bytes[j] & 0xFF; + result.append(Integer.toHexString(value / 16)); + result.append(Integer.toHexString(value % 16)); + result.append(' '); + } + result.append('\n'); + i += 8; + } + for (int j = i - 8; j < length; j++) { + result.append(Integer.toHexString(bytes[j] & 0xFF)); + result.append(' '); + } + return result.toString(); + } + @Override public void destroy() { log.config("DecodeServlet shutting down..."); - emailTimer.cancel(); } }