zoukankan      html  css  js  c++  java
  • 使用SSM框架 搭建属于自己的APP二维码合成、解析、下载

      最近公司的app上线了,在推广APP的时候出现了一个问题,因为Android和IOS的下载地址不一样,那么在推广的时候就要推广两个二维码,这样比较麻烦,如何简化我们的推广,让IOS用户扫描二维码的时候自动跳转到苹果应用市场,让Android用户扫描二维码的时候自动跳转到安卓应用市场呢。这时候我百度了一下,发现市面上确实有一些这样的网站帮助我们合成二维码,但是在使用这些二维码的时候,我发现了一些问题,因为这些网站把自己的短网址放到了二维码中,在用户使用QQ扫描二维码的时候,QQ自动屏蔽了这个短网址,这样就无法跳转到指定的下载页面了。

      于是,我决定自己用java搭建一个属于自己APP二维码合成网站。我的思路是这样的:

      1、用户在前台表单提交APP的IOS和Android下载地址。

      2、后台接收IOS和Android下载地址然后生成一个UUID,把这三个信息存储在数据库中。

      3、定义一个@RequestMapping地址,通过地址中传递的UUID,在数据库中查询到IOS和Android

      4、把当前服务器的网址+@RequestMapping地址+UUID合成二维码返回给前端显示

      5、用户扫描的二维码实际上是访问了我们事先定义的@RequestMapping地址,通过用户的http请求,我们可以获取到用户的手机操作系统是IOS还是Android,这样就可以跳转到指定的地址了。

      项目选型,我使用Spring SpringMVC MyBatis现在最流行的框架,然后用maven搭建项目,在二维码的生成和解析的时候,使用google的zxing jar。

      添加的依赖pom.xml

    <?xml version="1.0"?>
    <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <modelVersion>4.0.0</modelVersion>
      <parent>
        <groupId>com.jiafuwei.spring</groupId>
        <artifactId>spring-parent</artifactId>
        <version>0.0.1-SNAPSHOT</version>
      </parent>
      
      <groupId>com.jiafuwei.spring</groupId>
      <artifactId>spring-mvc-web</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <packaging>war</packaging>
      
      <name>spring-mvc-web Maven Webapp</name>
      <url>http://maven.apache.org</url>
      
      <properties>
              <spring.version>4.2.7.RELEASE</spring.version>
            <jackson.version>2.6.7</jackson.version>
            <!-- mybatis版本号 -->  
            <mybatis.version>3.2.6</mybatis.version> 
            <!-- freemarker模板包版本 -->
            <freemarker.version>2.3.23</freemarker.version> 
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      </properties>
      
      
      <dependencies>
         <!-- freemarker依赖 -->
         <dependency>
           <groupId>org.freemarker</groupId>
           <artifactId>freemarker</artifactId>
           <version>${freemarker.version}</version>
         </dependency>
          
        <!-- spring mvc 框架 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
          
            <dependency>  
                <groupId>org.springframework</groupId>  
                <artifactId>spring-jdbc</artifactId>  
                <version>${spring.version}</version>  
            </dependency>
            
            <dependency>  
                <groupId>org.springframework</groupId>  
                <artifactId>spring-context-support</artifactId>  
                <version>${spring.version}</version>  
            </dependency>
            
            <dependency>  
                <groupId>org.springframework</groupId>  
                <artifactId>spring-test</artifactId>  
                <version>${spring.version}</version>  
            </dependency> 
            
            <dependency>
                  <groupId>c3p0</groupId>
                  <artifactId>c3p0</artifactId>
                  <version>0.9.1.2</version>
            </dependency>
            
             <!-- 导入Mysql数据库链接jar包 -->  
            <dependency>
                  <groupId>mysql</groupId>
                  <artifactId>mysql-connector-java</artifactId>
                 <version>5.1.4</version>
            </dependency> 
            
            <!-- mybatis核心包 -->  
            <dependency>  
                <groupId>org.mybatis</groupId>  
                <artifactId>mybatis</artifactId>  
                <version>${mybatis.version}</version>  
            </dependency>  
            <!-- mybatis/spring包 -->  
            <dependency>  
                <groupId>org.mybatis</groupId>  
                <artifactId>mybatis-spring</artifactId>  
                <version>1.2.2</version>  
            </dependency> 
            
             <!-- 上传组件包 -->  
            <dependency>  
                <groupId>commons-fileupload</groupId>  
                <artifactId>commons-fileupload</artifactId>  
                <version>1.3.1</version>  
            </dependency>  
            <dependency>  
                <groupId>commons-io</groupId>  
                <artifactId>commons-io</artifactId>  
                <version>2.4</version>  
            </dependency>  
            <dependency>  
                <groupId>commons-codec</groupId>  
                <artifactId>commons-codec</artifactId>  
                <version>1.9</version>  
            </dependency> 
        
        <!-- servlet -->
        <dependency>
                <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>
        
        <!-- jsp/jstl/core 页面标签 -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>
        
        <!-- SLF4J API -->
        <!-- SLF4J 是一个日志抽象层,允许你使用任何一个日志系统,并且可以随时切换还不需要动到已经写好的程序 -->
        <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
               <version>1.7.22</version>
        </dependency>
        
        <!-- Log4j 日志系统(最常用) -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.22</version>
        </dependency>
        
        <!-- jackson -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>${jackson.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>${jackson.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>${jackson.version}</version>
        </dependency>
          
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>3.8.1</version>
          <scope>test</scope>
        </dependency>
        
        <!-- 二维码 -->
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>core</artifactId>
            <version>3.1.0</version>
        </dependency>
        
        <dependency>  
            <groupId>com.google.zxing</groupId>  
            <artifactId>javase</artifactId>  
            <version>3.0.0</version>  
        </dependency> 
        
         
        
        <!-- swagger2整合springmvc快速生成rest风格接口文档 -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.5.0</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.5.0</version>
        </dependency>
        
      </dependencies>
      
      <build>
        <finalName>spring-mvc-web</finalName>
      </build>
    </project>
    View Code

      二维码生成、解析工具类ZXingCodeUtil.java

    package com.jiafuwei.spring.util;
    
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics2D;
    import java.awt.image.BufferedImage;
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.IOException;
    
    import java.util.HashMap;
    import java.util.Map;
    import javax.imageio.ImageIO;
    import javax.servlet.http.HttpServletRequest;
    import com.google.zxing.BarcodeFormat;
    import com.google.zxing.Binarizer;
    import com.google.zxing.BinaryBitmap;
    import com.google.zxing.DecodeHintType;
    import com.google.zxing.EncodeHintType;
    import com.google.zxing.LuminanceSource;
    import com.google.zxing.MultiFormatReader;
    import com.google.zxing.MultiFormatWriter;
    import com.google.zxing.NotFoundException;
    import com.google.zxing.Result;
    import com.google.zxing.WriterException;
    import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
    import com.google.zxing.common.BitMatrix;
    import com.google.zxing.common.HybridBinarizer;
    import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
    
    
    /**
     * @Description: (二维码生成工具类)
     * @author jiafuwei
     * @date:2017-03-01 下午05:27:13
     */
    public class ZXingCodeUtil {
        private static final int QRCOLOR = 0xFF000000;   //默认是黑色
        private static final int BGWHITE = 0xFFFFFFFF;   //背景颜色
    
    
        public static void main(String[] args) throws WriterException{  
            try {  
                //getLogoQRCode("https://www.baidu.com/", null, "跳转到百度的二维码");
                //getQRCode("https://www.baidu.com/", null, "跳转到百度的二维码");
                
            }  
            catch (Exception e)  {  
                e.printStackTrace();  
            }  
        }  
        
        /**
         * 二维码解析
         * @param file 二维码图片文件
         * @return 解析结果
         */
        public static String parseQRCode(File file) {
            BufferedImage image;  
            try {  
                image = ImageIO.read(file);  
                LuminanceSource source = new BufferedImageLuminanceSource(image);  
                Binarizer binarizer = new HybridBinarizer(source);  
                BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);  
                Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>();  
                hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");  
                Result result = new MultiFormatReader().decode(binaryBitmap, hints);// 对图像进行解码  
                return result.getText();
            } catch (IOException e) {  
                e.printStackTrace(); 
                return null;
            } catch (NotFoundException e) {  
                e.printStackTrace();
                return null;
            }  
        }
        
        
        /**
         * 生成不带logo的二维码
         * @param qrUrl 链接地址
         * @param request 请求
         * @param productName 二维码名称
         * @param file 上传路径+文件名
         * @return
         */
        public static String getQRCode(String qrUrl,HttpServletRequest request,String productName,File file ) {
            // String filePath = request.getSession().getServletContext().getRealPath("/") + "resources/images/logoImages/llhlogo.png";
            //filePath是二维码logo的路径,但是实际中我们是放在项目的某个路径下面的,所以路径用上面的,把下面的注释就好
            
            String content = qrUrl;
            try {  
                ZXingCodeUtil zp = new ZXingCodeUtil();
                BufferedImage image = zp.getQR_CODEBufferedImage(content, BarcodeFormat.QR_CODE, 400, 400, zp.getDecodeHintType());
                image.flush();
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                baos.flush();
                ImageIO.write(image, "png", baos);
                //二维码生成的路径,但是实际项目中,我们是把这生成的二维码显示到界面上的,因此下面的折行代码可以注释掉
                //可以看到这个方法最终返回的是这个二维码的imageBase64字符串
                //前端用 <img src="data:image/png;base64,${imageBase64QRCode}"/> 其中${imageBase64QRCode}对应二维码的imageBase64字符串
                //new File("E:/" + new Date().getTime() + "test.png")
                //判断目标文件所在的目录是否存在  
                if(!file.getParentFile().exists()) {  
                    //如果目标文件所在的目录不存在,则创建父目录  
                    System.out.println("目标文件所在目录不存在,准备创建它!");  
                    if(!file.getParentFile().mkdirs()) {  
                        System.out.println("创建目标文件所在目录失败!");  
                    }  
                }
                ImageIO.write(image, "png", file); 
               
                String imageBase64QRCode =  new sun.misc.BASE64Encoder().encodeBuffer(baos.toByteArray());
                baos.close();
                return imageBase64QRCode;
            }
            catch (Exception e){
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * 生成带logo的二维码图片
         * @param qrUrl 链接地址
         * @param request 请求
         * @param productName 二维码名称
         * @param logoFile logo文件
         * @param createFile 生成的文件路径
         * @return
         */
        public static String getLogoQRCode(String qrUrl,HttpServletRequest request,String productName,File logoFile,File createFile) {
            // String filePath = request.getSession().getServletContext().getRealPath("/") + "resources/images/logoImages/llhlogo.png";
            //filePath是二维码logo的路径,但是实际中我们是放在项目的某个路径下面的,所以路径用上面的,把下面的注释就好
            String content = qrUrl;
            try{  
                ZXingCodeUtil zp = new ZXingCodeUtil();
                BufferedImage bim = zp.getQR_CODEBufferedImage(content, BarcodeFormat.QR_CODE, 400, 400, zp.getDecodeHintType());
                return zp.addLogo_QRCode(bim, logoFile , new LogoConfig(), productName, createFile);
            }
            catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        /** * 给二维码图片添加Logo * * @param qrPic * @param logoPic */
        public String addLogo_QRCode(BufferedImage bim, File logoPic, LogoConfig logoConfig, String productName, File createFile) {
            try {
                /** * 读取二维码图片,并构建绘图对象 */
                BufferedImage image = bim;
                Graphics2D g = image.createGraphics();
    
                /** * 读取Logo图片 */
                BufferedImage logo = ImageIO.read(logoPic);
                /** * 设置logo的大小,本人设置为二维码图片的20%,因为过大会盖掉二维码 */
                int widthLogo = logo.getWidth(null)>image.getWidth()*3/10?(image.getWidth()*3/10):logo.getWidth(null), 
                    heightLogo = logo.getHeight(null)>image.getHeight()*3/10?(image.getHeight()*3/10):logo.getWidth(null);
    
                /** * logo放在中心 */
                 int x = (image.getWidth() - widthLogo) / 2;
                 int y = (image.getHeight() - heightLogo) / 2;
                 /** * logo放在右下角 * int x = (image.getWidth() - widthLogo); * int y = (image.getHeight() - heightLogo); */
    
                //开始绘制图片
                g.drawImage(logo, x, y, widthLogo, heightLogo, null);
                // g.drawRoundRect(x, y, widthLogo, heightLogo, 15, 15);
                // g.setStroke(new BasicStroke(logoConfig.getBorder()));
                // g.setColor(logoConfig.getBorderColor());
                // g.drawRect(x, y, widthLogo, heightLogo);
                g.dispose();
    
                //把商品名称添加上去,商品名称不要太长哦,这里最多支持两行。太长就会自动截取啦
                if (productName != null && !productName.equals("")) {
                    //新的图片,把带logo的二维码下面加上文字
                    BufferedImage outImage = new BufferedImage(400, 445, BufferedImage.TYPE_4BYTE_ABGR);
                    Graphics2D outg = outImage.createGraphics();
                    //画二维码到新的面板
                    outg.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null);
                    //画文字到新的面板
                    outg.setColor(Color.BLACK); 
                    outg.setFont(new Font("宋体",Font.BOLD,30)); //字体、字型、字号 
                    int strWidth = outg.getFontMetrics().stringWidth(productName);
                    if (strWidth > 399) {
                        // //长度过长就截取前面部分
                        // outg.drawString(productName, 0, image.getHeight() + (outImage.getHeight() - image.getHeight())/2 + 5 ); //画文字
                        //长度过长就换行
                        String productName1 = productName.substring(0, productName.length()/2);
                        String productName2 = productName.substring(productName.length()/2, productName.length());
                        int strWidth1 = outg.getFontMetrics().stringWidth(productName1);
                        int strWidth2 = outg.getFontMetrics().stringWidth(productName2);
                        outg.drawString(productName1, 200  - strWidth1/2, image.getHeight() + (outImage.getHeight() - image.getHeight())/2 + 12 );
                        BufferedImage outImage2 = new BufferedImage(400, 485, BufferedImage.TYPE_4BYTE_ABGR);
                        Graphics2D outg2 = outImage2.createGraphics();
                        outg2.drawImage(outImage, 0, 0, outImage.getWidth(), outImage.getHeight(), null);
                        outg2.setColor(Color.BLACK); 
                        outg2.setFont(new Font("宋体",Font.BOLD,30)); //字体、字型、字号 
                        outg2.drawString(productName2, 200  - strWidth2/2, outImage.getHeight() + (outImage2.getHeight() - outImage.getHeight())/2 + 5 );
                        outg2.dispose(); 
                        outImage2.flush();
                        outImage = outImage2;
                    }else {
                        outg.drawString(productName, 200  - strWidth/2 , image.getHeight() + (outImage.getHeight() - image.getHeight())/2 + 12 ); //画文字 
                    }
                    outg.dispose(); 
                    outImage.flush();
                    image = outImage;
                }
                logo.flush();
                image.flush();
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                baos.flush();
                ImageIO.write(image, "png", baos);
    
                //二维码生成的路径,但是实际项目中,我们是把这生成的二维码显示到界面上的,因此下面的折行代码可以注释掉
                //可以看到这个方法最终返回的是这个二维码的imageBase64字符串
                //前端用 <img src="data:image/png;base64,${imageBase64QRCode}"/> 其中${imageBase64QRCode}对应二维码的imageBase64字符串
                if(!createFile.getParentFile().exists()) {  
                    //如果目标文件所在的目录不存在,则创建父目录  
                    System.out.println("目标文件所在目录不存在,准备创建它!");  
                    if(!createFile.getParentFile().mkdirs()) {  
                        System.out.println("创建目标文件所在目录失败!");  
                    }  
                }
                ImageIO.write(image, "png", createFile); 
               
                String imageBase64QRCode =  new sun.misc.BASE64Encoder().encodeBuffer(baos.toByteArray());
                baos.close();
                return imageBase64QRCode;
            }
            catch (Exception e){
                e.printStackTrace();
            }
            return null;
        }
    
    
        /** * 构建初始化二维码 * * @param bm * @return */
        public BufferedImage fileToBufferedImage(BitMatrix bm){
            BufferedImage image = null;
            try
            {
                int w = bm.getWidth(), h = bm.getHeight();
                image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
    
                for (int x = 0; x < w; x++)
                {
                    for (int y = 0; y < h; y++)
                    {
                        image.setRGB(x, y, bm.get(x, y) ? 0xFF000000 : 0xFFCCDDEE);
                    }
                }
    
            }
            catch (Exception e){
                e.printStackTrace();
            }
            return image;
        }
    
        /** * 生成二维码bufferedImage图片 * * @param content * 编码内容 * @param barcodeFormat * 编码类型 * @param width * 图片宽度 * @param height * 图片高度 * @param hints * 设置参数 * @return */
        public BufferedImage getQR_CODEBufferedImage(String content, BarcodeFormat barcodeFormat, int width, int height, Map<EncodeHintType, ?> hints) {
            MultiFormatWriter multiFormatWriter = null;
            BitMatrix bm = null;
            BufferedImage image = null;
            try{
                multiFormatWriter = new MultiFormatWriter();
                // 参数顺序分别为:编码内容,编码类型,生成图片宽度,生成图片高度,设置参数
                bm = multiFormatWriter.encode(content, barcodeFormat, width, height, hints);
                int w = bm.getWidth();
                int h = bm.getHeight();
                image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
    
                // 开始利用二维码数据创建Bitmap图片,分别设为黑(0xFFFFFFFF)白(0xFF000000)两色
                for (int x = 0; x < w; x++){
                    for (int y = 0; y < h; y++) {
                        image.setRGB(x, y, bm.get(x, y) ? QRCOLOR : BGWHITE);
                    }
                }
            }
            catch (WriterException e){
                e.printStackTrace();
            }
            return image;
        }
    
        /** * 设置二维码的格式参数 * * @return */
        public Map<EncodeHintType, Object> getDecodeHintType() {
            // 用于设置QR二维码参数
            Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
            // 设置QR二维码的纠错级别(H为最高级别)具体级别信息
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
            // 设置编码方式
            hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
            hints.put(EncodeHintType.MARGIN, 0);
            hints.put(EncodeHintType.MAX_SIZE, 350);
            hints.put(EncodeHintType.MIN_SIZE, 100);
    
            return hints;
        }
    }
    
        class LogoConfig {
            // logo默认边框颜色
            public static final Color DEFAULT_BORDERCOLOR = Color.WHITE;
            // logo默认边框宽度
            public static final int DEFAULT_BORDER = 2;
            // logo大小默认为照片的1/5
            public static final int DEFAULT_LOGOPART = 5;
    
            private final int border = DEFAULT_BORDER;
            private final Color borderColor;
            private final int logoPart;
    
            /** * Creates a default config with on color {@link #BLACK} and off color * {@link #WHITE}, generating normal black-on-white barcodes. */
            public LogoConfig(){
                this(DEFAULT_BORDERCOLOR, DEFAULT_LOGOPART);
            }
    
            public LogoConfig(Color borderColor, int logoPart){
                this.borderColor = borderColor;
                this.logoPart = logoPart;
            }
    
            public Color getBorderColor() {
                return borderColor;
            }
    
            public int getBorder(){
                return border;
            }
    
            public int getLogoPart() {
                return logoPart;
            }
        }
    View Code

      8位短uuid生成工具类

    package com.jiafuwei.spring.util;
    
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics2D;
    import java.awt.image.BufferedImage;
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.IOException;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.UUID;
    
    import javax.imageio.ImageIO;
    import javax.servlet.http.HttpServletRequest;
    import com.google.zxing.BarcodeFormat;
    import com.google.zxing.EncodeHintType;
    import com.google.zxing.MultiFormatWriter;
    import com.google.zxing.WriterException;
    import com.google.zxing.common.BitMatrix;
    import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
    
    
    /**
     * @Description: 短uuid生成
     * @author jiafuwei
     * @date:2017-03-02 下午05:27:13
     */
    public class UuidUtil {
       
    
    
        public static void main(String[] args) throws WriterException{  
            String uuid = generateShortUuid();
            System.out.println(uuid);
        }  
    
        public static String[] chars = new String[] { "a", "b", "c", "d", "e", "f",  
            "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s",  
            "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5",  
            "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I",  
            "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",  
            "W", "X", "Y", "Z" };  
    
    
        public static String generateShortUuid() {  
            StringBuffer shortBuffer = new StringBuffer();  
            String uuid = UUID.randomUUID().toString().replace("-", "");  
            for (int i = 0; i < 8; i++) {  
                String str = uuid.substring(i * 4, i * 4 + 4);  
                int x = Integer.parseInt(str, 16);  
                shortBuffer.append(chars[x % 0x3E]);  
            }  
            return shortBuffer.toString();  
        
        }  
        
        
        
    }
    
       
    View Code

      核心控制器

    package com.jiafuwei.spring.controller;
    
    import java.io.BufferedInputStream;
    import java.io.File;  
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.util.Date;  
    import java.util.HashMap;
    import java.util.Map;
      
    import javax.servlet.http.HttpServletRequest;  
    import javax.servlet.http.HttpServletResponse;
      
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;  
    import org.springframework.ui.ModelMap;  
    import org.springframework.web.bind.annotation.RequestMapping;  
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RequestParam;  
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.multipart.MultipartFile;  
    import org.springframework.web.multipart.MultipartHttpServletRequest;
    import org.springframework.web.multipart.commons.CommonsMultipartFile;
    
    import com.jiafuwei.spring.po.JsonResult;
    import com.jiafuwei.spring.po.QRCode;
    import com.jiafuwei.spring.service.IQRCodeService;
    import com.jiafuwei.spring.util.UuidUtil;
    import com.jiafuwei.spring.util.ZXingCodeUtil;
      
    @Controller  
    public class UploadController {  
        final Logger logger = LoggerFactory.getLogger(getClass());
        
        @Autowired
        private IQRCodeService qRCodeService;
     
        /*
         * 通过流的方式上传文件
         * @RequestParam("file") 将name=file控件得到的文件封装成CommonsMultipartFile 对象
         */
        @RequestMapping("fileUpload")
        public String  fileUpload(@RequestParam("file") CommonsMultipartFile file,HttpServletRequest request,
                ModelMap model) throws IOException {
             
             
            //用来检测程序运行时间
            long  startTime=System.currentTimeMillis();
            String path = request.getSession().getServletContext().getRealPath("upload"); 
            String fileName = file.getOriginalFilename();
            System.out.println("fileName:"+fileName);
            
            File targetFile = new File(path, fileName);  
            if(!targetFile.exists()){  
                targetFile.mkdirs();  
            } 
            file.transferTo(targetFile);
            
            model.addAttribute("fileUrl", request.getContextPath()+"/upload/"+fileName);  
            
           
            long  endTime=System.currentTimeMillis();
            System.out.println("方法一的运行时间:"+String.valueOf(endTime-startTime)+"ms");
            return "/result"; 
        }
      
        
        @RequestMapping("fileUploadLogo")
        @ResponseBody
        public String  fileUploadLogo(@RequestParam("file") CommonsMultipartFile file,HttpServletRequest request,
                ModelMap model) throws IOException {
             
             
            //用来检测程序运行时间
            long  startTime=System.currentTimeMillis();
            String path = request.getSession().getServletContext().getRealPath("upload"); 
            String fileName = file.getOriginalFilename();
            System.out.println("fileName:"+fileName);
            
            File targetFile = new File(path, fileName);  
            if(!targetFile.exists()){  
                targetFile.mkdirs();  
            } 
            file.transferTo(targetFile);
            
            model.addAttribute("fileUrl", request.getContextPath()+"/upload/"+fileName);  
            
           
            long  endTime=System.currentTimeMillis();
            System.out.println("方法一的运行时间:"+String.valueOf(endTime-startTime)+"ms");
            return "result"; 
        }
        
        /**
         * APP 合成二维码生成
         * @param request
         * @param model
         * @return
         * @throws IOException
         */
        @RequestMapping("synthesisQRCode")
        @ResponseBody
        public JsonResult  SynthesisQRCode(HttpServletRequest request,
                @RequestParam(value="file",required=false) CommonsMultipartFile logoFile,
                @RequestParam(value="ios_url",required=true) String ios_url,
                @RequestParam(value="android_url",required=true) String android_url,
                ModelMap model) throws IOException {
            
             logger.info("SynthesisQRCode - {}", "开始了");
             logger.info("path - {}", request.getSession().getServletContext().getRealPath("/"));
             
             StringBuffer url = request.getRequestURL();  
             String tempContextUrl = url.delete(url.length() - request.getRequestURI().length(), url.length()).append(request.getContextPath()).append("/").toString(); 
             logger.info("tempContextUrl - {}", tempContextUrl);
             
             String key_id = UuidUtil.generateShortUuid();
             QRCode qRCode = new QRCode();
             qRCode.setAndroid_url(android_url);
             qRCode.setIos_url(ios_url);
             qRCode.setKey_id(key_id);
             int intInsert = qRCodeService.insert(qRCode);
             
             String path = request.getSession().getServletContext().getRealPath("upload");
             String fileName = new Date().getTime() + "qrcode.png";
             File createFile = new File(path+"/"+fileName);
             
             //访问路径 服务器地址+ findAppUrl + key_id
             String urltxt = tempContextUrl+"findAppUrl/"+key_id;
             logger.info("urltxt - {}", urltxt);
             
             //生成二维码
             String imageBase64QRCode = "";
             if(logoFile != null){
                 String logoFileName = logoFile.getOriginalFilename();
                 File targetFile = new File(path, logoFileName);  
                 if(!targetFile.exists()){  
                     targetFile.mkdirs();  
                 } 
                 logoFile.transferTo(targetFile);
                 imageBase64QRCode = ZXingCodeUtil.getLogoQRCode(urltxt, request, "", targetFile, createFile);
                 //删除上传的logo
                 targetFile.delete();
             }else{
                 imageBase64QRCode = ZXingCodeUtil.getQRCode(urltxt, request, "", createFile);
             }
             
             //二维码地址
             String qrcode_path = tempContextUrl+"upload/"+fileName;
             
             JsonResult jsonResult = new JsonResult();
             Map data = new HashMap<String, String>();
             data.put("recreateFlag", "0");
             data.put("qrcode_path", qrcode_path);
             data.put("accessKey", "13598992");
             data.put("shortUrl", urltxt);
             jsonResult.setData(data);
             jsonResult.setMeg("生成成功");
             jsonResult.setRes(1);
         
            return jsonResult; 
        }
        
        /**
         * url链接或者文本生成二维码
         * @param request
         * @param model
         * @return
         * @throws IOException
         */
        @RequestMapping("urlQRCode")
        @ResponseBody
        public JsonResult  UrlQRCode(HttpServletRequest request,ModelMap model,
                @RequestParam(value="file",required=false) CommonsMultipartFile logoFile,
                @RequestParam(value="urltxt",required=false) String urltxt) throws IOException {
            
             logger.info("UrlQRCode - {}", "开始了");
             logger.info("页面传递的文本内容- {}", urltxt);
             
             StringBuffer url = request.getRequestURL();  
             String tempContextUrl = url.delete(url.length() - request.getRequestURI().length(), url.length()).append(request.getContextPath()).append("/").toString(); 
             
             
             String path = request.getSession().getServletContext().getRealPath("upload");
             String fileName = new Date().getTime() + "url.png";
             File createFile = new File(path+"/"+fileName);
             //生成二维码
             String imageBase64QRCode = "";
             if(logoFile != null){
                 String logoFileName = logoFile.getOriginalFilename();
                 File targetFile = new File(path, logoFileName);  
                 if(!targetFile.exists()){  
                     targetFile.mkdirs();  
                 } 
                 logoFile.transferTo(targetFile);
                 imageBase64QRCode = ZXingCodeUtil.getLogoQRCode(urltxt, request, "", targetFile, createFile);
                 //删除上传的logo
                 targetFile.delete();
             }else{
                 imageBase64QRCode = ZXingCodeUtil.getQRCode(urltxt, request, "", createFile);
             }
             
             //二维码地址
             String qrcode_path = tempContextUrl+"upload/"+fileName;
             
             JsonResult jsonResult = new JsonResult();
             Map data = new HashMap<String, String>();
             data.put("qrcode_path", qrcode_path);
             data.put("qrcode", imageBase64QRCode);
             jsonResult.setData(data);
             jsonResult.setMeg("生成成功");
             jsonResult.setRes(1);
         
            return jsonResult; 
        }
        
        /**
         * 二维码下载
         * @param qrcode_path
         * @param request
         * @param response
         * @throws IOException
         */
        @RequestMapping("/download")  
        public void downloadFile(@RequestParam(value="qrcode_path",required=true) String qrcode_path,
                HttpServletRequest request, HttpServletResponse response) throws IOException {    
            
            String destUrl = qrcode_path;
            // 建立链接    
            URL url = new URL(destUrl);    
            HttpURLConnection httpUrl = (HttpURLConnection) url.openConnection();    
            // 连接指定的资源    
            httpUrl.connect();    
            // 获取网络输入流    
            BufferedInputStream bis = new BufferedInputStream(httpUrl.getInputStream());    
          
            response.setContentType("application/x-msdownload");    
            response.setHeader("Content-Disposition", "attachment; filename="+java.net.URLEncoder.encode(new Date().getTime()+"url.png","UTF-8"));    
            OutputStream out = response.getOutputStream();    
            byte[] buf = new byte[1024];    
            if (destUrl != null) {    
                BufferedInputStream br = bis;    
                int len = 0;    
                while ((len = br.read(buf)) > 0){    
                    out.write(buf, 0, len);    
                }                   
                br.close();    
            }    
            out.flush();    
            out.close();    
        } 
        
        
        /**
         * 二维码解析
         * @param request
         * @param model
         * @return
         * @throws IOException
         */
        @RequestMapping("parseQRCode")
        @ResponseBody
        public JsonResult  ParseQRCode(HttpServletRequest request,ModelMap model,
                @RequestParam(value="file",required=false) CommonsMultipartFile logoFile) throws IOException {
            
             logger.info("ParseQRCode - {}", "开始了");
             
             StringBuffer url = request.getRequestURL();  
             String tempContextUrl = url.delete(url.length() - request.getRequestURI().length(), url.length()).append(request.getContextPath()).append("/").toString(); 
            
             String path = request.getSession().getServletContext().getRealPath("upload");
             
             String logoFileName = logoFile.getOriginalFilename();
             File targetFile = new File(path, logoFileName);  
             if(!targetFile.exists()){  
                 targetFile.mkdirs();  
             } 
             logoFile.transferTo(targetFile);
             
             String text = ZXingCodeUtil.parseQRCode(targetFile);
             
             targetFile.delete();
             
             logger.info("解析结果 - {}", text);
             
             JsonResult jsonResult = new JsonResult();
             Map data = new HashMap<String, String>();
             data.put("text", text);
             jsonResult.setData(data);
             jsonResult.setMeg("生成成功");
             jsonResult.setRes(1);
         
            return jsonResult; 
        }
    } 
    View Code

       最后搭建完成的项目如下:

      一、APP二维码合并,用苹果手机扫描自动打开App Store页面下载APP,用安卓手机扫码自动打开应用页面下载APP。

      

        二、网址生成二维码

       三、生成的二维码识别

     

     

      项目源码 : https://github.com/jiafuweiJava/spring-integration

      演示地址:http://demo.jiafuwei.win:9191/

  • 相关阅读:
    IIS与ASP.NET中的线程池
    IIS与ASP.NET中的队列
    让ASP.NET OutputCache使用http.sys kernel-mode cache
    微软的坑:Url重写竟然会引起IIS内核模式缓存不工作
    实际案例:在现有代码中通过async/await实现并行
    困扰多日的C#调用Haskell问题竟然是Windows的一个坑
    C#调用haskell遭遇Attempted to read or write protected memory
    经过实际验证的C#调用Haskell的方法
    Haskell中cabal install glib遇到的问题
    Haskell ghci中调用pandoc的API进行markdown转换
  • 原文地址:https://www.cnblogs.com/jiafuwei/p/6522195.html
Copyright © 2011-2022 走看看