长URL转换成短URL

最近公司业务需求将url转为二维码,但是遇到url太长,转成的二维码无法扫描,要先将url转成短码处理,自己写了一个测试,分享学习一下! 

package alfri.test;

import java.awt.BasicStroke;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Shape;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Hashtable;
import java.util.List;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

@Controller
@Scope("singleton")
@RequestMapping("/test")
public class LongUrl2ShortUrl {

    private static long num = 922337203685477580L;// 模拟发号器发出的数字

    /**
     * @Description: 请求生成二维码
     * @author YL
     * @date 2018-11-23下午11:54:37
     * @param request
     * @param response
     */

    @RequestMapping("/getQRCode")
    @ResponseBody
    public void getQRCode(HttpServletRequest request, HttpServletResponse response) {
        String longUrl = "https://www.baidu.com/"; // 长链接

        String shortUrl = getShortUrl(longUrl, num++);// 短链接码

        shortUrl = "http://127.0.0.1:8080/web/test/" + shortUrl;// 短连接拼接url

        // 画出二维码
        BufferedImage image = null;
        ServletOutputStream iStream = null;
        try {
            image = QRCodeUtil.createImage(shortUrl, "", false);
            iStream = response.getOutputStream();
            ImageIO.write(image, "jpeg", iStream);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (iStream == null) {
                try {
                    iStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }

    }

    /**
     * 
     * @Description: 传入长链接及分发的数字
     * @author YL
     * @date 2018-11-23下午11:09:33
     * @param longUrl
     * @param num
     * @return 短连接编码 (未做长度限制及打乱)
     */
    private static String getShortUrl(String longUrl, long num) {

        String shortUrl = tenTo62(num);

        ShortUrl su = new ShortUrl();
        su.setShorturl(shortUrl);
        su.setLongurl(longUrl);

        shortUrl = setShortUrl(su);// 数据库存储短链接码及长链接

        return shortUrl;

    }

    /**
     * 
     * @Description: 数据库存储短链接码及长链接
     * @author YL
     * @date 2018-11-23下午11:12:45
     * @param su
     * @return 短链接码
     */
    private static String setShortUrl(ShortUrl su) {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String datestr = sdf.format(new Date().getTime() + 60000);
        su.setExpdate(datestr);

        String sql = "SELECT longurl FROM ashorurl WHERE shorturl = :shorturl AND expdate >= now()";
        String sqlStr = "INSERT INTO ashorurl (shorturl,longurl,expdate) VALUES (:shorturl,:longurl,:expdate) ";

        List<ShortUrl> sulist = new ArrayList<>();

        // sulist = jdbcTemplate.query(sql, su,ShortUrl.class);//执行sql语句

        if (sulist.size() > 0) {
            String shorturl = sulist.get(0).getShorturl();
            return shorturl;
        } else {

            // jdbcTemplate.update(sqlStr, su);// 执行sql语句插入记录
            return su.getShorturl();
        }

    }

    /**
     * 
     * @Description: 发号器分发的数字 十进制转62进制
     * @author YL
     * @date 2018-11-23下午11:10:42
     * @param num
     * @return 短链接码
     */
    private static String tenTo62(long num) {
        StringBuilder sb = new StringBuilder();
        char[] charArray = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".toCharArray();

        long remainder = 0;

        do {
            remainder = num % 62;
            // System.out.println(remainder);
            sb.append(charArray[(int) remainder]);
            num = num / 62;
        } while (num > 61);

        sb.append(charArray[(int) num]);
        StringBuffer sbStr = new StringBuffer();

        char[] chars = sb.toString().toCharArray();
        for (int i = chars.length - 1; i >= 0; i--) {
            sbStr.append(chars[i]);
        }
        return sbStr.toString();
    }

    /**
     * @Description: 扫描二维码重定向url
     * @author YL
     * @date 2018-11-23下午11:50:06
     * @param shortUrl
     *            短链接码
     * @return
     */

    @RequestMapping("/{shortUrl}")
    public String testPathVariable(@PathVariable("shortUrl") String shortUrl) {
        ShortUrl su = new ShortUrl();
        su.setShorturl(shortUrl);
        String longUrl = getLongUrl(su);
        return "redirect:" + longUrl;

    }

    /**
     * @Description: 获取长链接url
     * @author YL
     * @date 2018-11-23下午11:50:59
     * @param su
     * @return
     */

    private String getLongUrl(ShortUrl su) {
        String sql = "SELECT * FROM ashorurl WHERE shorturl = :shorturl AND expdate >= now()";

        List<ShortUrl> sulist = new ArrayList<>();
        // sulist = jdbcTemplate.query(sql, su, ShortUrl.class); //从数据库中查出长链接

        String longurl = null;
        if (sulist.size() > 0) {
            longurl = sulist.get(0).getLongurl();
        }
        return longurl;

    }

}

/**
 * @ClassName: ShortUrl
 * @Description: 短连接实体类
 * @author Administrator
 * @date 2018-11-23
 * 
 */

class ShortUrl {

    String shorturl;// 短连接

    String longurl;// 长链接

    String expdate;// 失效时间

    public String getShorturl() {
        return shorturl;
    }

    public void setShorturl(String shorturl) {
        this.shorturl = shorturl;
    }

    public String getLongurl() {
        return longurl;
    }

    public void setLongurl(String longurl) {
        this.longurl = longurl;
    }

    public String getExpdate() {
        return expdate;
    }

    public void setExpdate(String expdate) {
        this.expdate = expdate;
    }

}

/**
 * @ClassName: QRCodeUtil
 * @Description: 二维码工具类
 * @author Administrator
 * @date 2018-11-23
 * 
 */

class QRCodeUtil {

    private static final String CHARSET = "utf-8";
    private static final String FORMAT_NAME = "JPG";
    // 二维码尺寸
    private static final int QRCODE_SIZE = 200;
    // LOGO宽度
    private static final int WIDTH = 60;
    // LOGO高度
    private static final int HEIGHT = 60;

    /**
     * @Description: 创建二维码图片
     * @author YL
     * @date 2018-11-23下午11:52:24
     * @param content
     * @param imgPath
     * @param needCompress
     * @return
     * @throws Exception
     */

    public static BufferedImage createImage(String content, String imgPath, boolean needCompress) throws Exception {
        Hashtable hints = new Hashtable();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
        hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
        hints.put(EncodeHintType.MARGIN, 1);
        BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, hints);
        int width = bitMatrix.getWidth();
        int height = bitMatrix.getHeight();
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
            }
        }
        if (imgPath == null || "".equals(imgPath)) {
            return image;
        }
        // 插入图片
        QRCodeUtil.insertImage(image, imgPath, needCompress);
        return image;
    }

    /**
     * @Description: 插入logo
     * @author YL
     * @date 2018-11-23下午11:52:45
     * @param source
     * @param imgPath
     * @param needCompress
     * @throws Exception
     */

    private static void insertImage(BufferedImage source, String imgPath, boolean needCompress) throws Exception {
        File file = new File(imgPath);
        if (!file.exists()) {
            System.err.println("" + imgPath + "   该文件不存在!");
            return;
        }
        Image src = ImageIO.read(new File(imgPath));
        int width = src.getWidth(null);
        int height = src.getHeight(null);
        if (needCompress) { // 压缩LOGO
            if (width > WIDTH) {
                width = WIDTH;
            }
            if (height > HEIGHT) {
                height = HEIGHT;
            }
            Image image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH);
            BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            Graphics g = tag.getGraphics();
            g.drawImage(image, 0, 0, null); // 绘制缩小后的图
            g.dispose();
            src = image;
        }
        // 插入LOGO
        Graphics2D graph = source.createGraphics();
        int x = (QRCODE_SIZE - width) / 2;
        int y = (QRCODE_SIZE - height) / 2;
        graph.drawImage(src, x, y, width, height, null);
        Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);
        graph.setStroke(new BasicStroke(3f));
        graph.draw(shape);
        graph.dispose();
    }


}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值