X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=zxingorg%2Fsrc%2Fcom%2Fgoogle%2Fzxing%2Fweb%2FDecodeServlet.java;h=a6713cd8397eb7de78624b85962c6e80ba0b42dd;hb=a0cd488502fb967949a1d7de2c3581efce583075;hp=7c69cc517fe1e8a7b1ae4c96e24261afcabc9792;hpb=ecff2b8654d7d349ef00aa7c4a604cb215dd3794;p=zxing.git diff --git a/zxingorg/src/com/google/zxing/web/DecodeServlet.java b/zxingorg/src/com/google/zxing/web/DecodeServlet.java index 7c69cc51..a6713cd8 100644 --- a/zxingorg/src/com/google/zxing/web/DecodeServlet.java +++ b/zxingorg/src/com/google/zxing/web/DecodeServlet.java @@ -1,5 +1,5 @@ /* - * Copyright 2008 Google Inc. + * Copyright 2008 ZXing authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,26 +16,34 @@ 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 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.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.params.HttpClientParams; +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.impl.client.DefaultHttpClient; import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; @@ -43,58 +51,66 @@ 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.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.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 */ public final class DecodeServlet extends HttpServlet { private static final long MAX_IMAGE_SIZE = 500000L; - private static final long EMAIL_CHECK_INTERVAL = 60000L; 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); + HINTS.put(DecodeHintType.POSSIBLE_FORMATS, possibleFormats); } private HttpClient client; 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(); HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); @@ -106,16 +122,12 @@ public final class DecodeServlet extends HttpServlet { 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 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"); @@ -135,6 +147,7 @@ public final class DecodeServlet extends HttpServlet { } HttpGet getRequest = new HttpGet(imageURI); + getRequest.addHeader("Connection", "close"); // Avoids CLOSE_WAIT socket issue? try { HttpResponse getResponse = client.execute(getRequest); @@ -149,14 +162,19 @@ public final class DecodeServlet extends HttpServlet { log.info("Decoding " + imageURI); InputStream is = getResponse.getEntity().getContent(); try { - processStream(is, response); + processStream(is, request, response); } finally { is.close(); } - } catch (InterruptedException ie) { + } catch (IllegalArgumentException iae) { + // Thrown if hostname is bad or null + getRequest.abort(); + response.sendRedirect("badurl.jspx"); + } catch (SocketException se) { + // Thrown if hostname is bad or null getRequest.abort(); response.sendRedirect("badurl.jspx"); - } catch (HttpException he) { + } catch (UnknownHostException uhe) { getRequest.abort(); response.sendRedirect("badurl.jspx"); } @@ -183,12 +201,12 @@ public final class DecodeServlet extends HttpServlet { log.info("Decoding uploaded file"); InputStream is = item.getInputStream(); try { - processStream(is, response); + processStream(is, request, response); } finally { is.close(); } } else { - throw new ServletException("File is too large: " + item.getSize()); + response.sendRedirect("badimage.jspx"); } break; } @@ -199,7 +217,8 @@ public final class DecodeServlet extends HttpServlet { } - private static void processStream(InputStream is, HttpServletResponse response) throws IOException { + private static void processStream(InputStream is, HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { BufferedImage image = ImageIO.read(is); if (image == null) { response.sendRedirect("badimage.jspx"); @@ -209,20 +228,47 @@ 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"); return; } - response.setContentType("text/plain"); - response.setCharacterEncoding("UTF-8"); - Writer out = new OutputStreamWriter(response.getOutputStream(), "UTF-8"); - try { - out.write(result.getText()); - } finally { - out.close(); + if (request.getParameter("full") == null) { + response.setContentType("text/plain"); + response.setCharacterEncoding("UTF8"); + Writer out = new OutputStreamWriter(response.getOutputStream(), "UTF8"); + try { + out.write(result.getText()); + } finally { + out.close(); + } + } else { + request.setAttribute("result", result); + byte[] rawBytes = result.getRawBytes(); + if (rawBytes != null) { + request.setAttribute("rawBytesString", arrayToString(rawBytes)); + } else { + request.setAttribute("rawBytesString", "(Not applicable)"); + } + 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); } } @@ -237,10 +283,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(); } }