文档章节

二维码服务拓展(支持logo,圆角logo,背景图,颜色配置)

小灰灰Blog
 小灰灰Blog
发布于 2017/07/28 17:23
字数 3243
阅读 960
收藏 74
点赞 0
评论 1

二维码的基础服务拓展

zxing 提供了二维码一些列的功能,在日常生活中,可以发现很多二维码并不仅仅是简单的黑白矩形块,有的添加了文字,加了logo,定制颜色,背景等,本片博文则着手于此,进行基础服务的拓展

本片博文拓展的功能点:

  • 支持在二维码中间添加logo
  • logo样式选择:支持圆角/直角logo,支持logo的边框选择
  • 二维码颜色选择(可自由将原来的黑白色进行替换)
  • 支持背景图片
  • 支持探测图形的前置色选择

一个包含上面所有功能点的二维码如下图

http://s2.mogucdn.com/mlcdn/c45406/170728_45a54147f26eh3lf1aiek04c1620h_300x300.png

准备

由于之前有一篇博文《spring-boot & zxing 搭建二维码服务》 较为消息的介绍了设计一个二维码服务的过程,因此这篇则不再整体设计上多做说明,主要的功能点将集中在以上几个功能点设计与实现上

源码地址: https://github.com/liuyueyi/quick-media

这篇博文,将不对二维码生成的细节进行说明,某些地方如有疑惑(如二维码生成时的一些参数,渲染逻辑等)请直接查看代码,or百度谷歌,或者私聊也可。

下面简单说明一下这个工程中与二维码相关的几个类的作用

1. QrCodeOptions.java

二维码的各种配置参数

2. QrCodeGenWrapper.java

封装了二维码的参数设置和处理方法,通常来讲对于使用者而言,只需要使用这个类中的方法即可实现二维码的生成,如生成上面的二维码测试代码如下

@Test
public void testGenColorCode() {
    String msg = "https://my.oschina.net/u/566591/blog/1359432";
    // 根据本地文件生成待logo的二维码, 重新着色位置探测图像
    try {
        String logo = "logo.jpg";
        String bg = "bg.png";
        BufferedImage img = QrCodeGenWrapper.of(msg)
                .setW(300)
                .setPreColor(0xff0000ff)
                .setBgColor(0xffFFFF00)
                .setDetectCornerPreColor(0xffff0000)
                .setPadding(2)
                .setLogo(logo)
                .setLogoStyle(QrCodeOptions.LogoStyle.ROUND)
                .setLogoBgColor(0xff00cc00)
                .setBackground(bg)
                .asBufferedImage();


        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ImageIO.write(img, "png", outputStream);
        System.out.println(Base64Util.encode(outputStream));
    } catch (Exception e) {
        System.out.println("create qrcode error! e: " + e);
        Assert.assertTrue(false);
    }
}

3.QrCodeUtil.java

二维码工具类,包括生成二维码矩阵信息,二维码图片渲染,输出BufferedIamge对象等

4. ImageUtil.java

图片处理辅助类,实现图片圆角化,添加边框,插入logo,绘制背景图等


设计与实现

1. 二维码颜色可配置

二维码颜色的选择,主要在将二维码矩阵转换成图的时候,选择不同的颜色进行渲染即可,我们主要的代码将放在 com.hust.hui.quickmedia.common.util.QrCodeUtil#toBufferedImage 方法中

先看一下实现逻辑

/**
 * 根据二维码配置 & 二维码矩阵生成二维码图片
 *
 * @param qrCodeConfig
 * @param bitMatrix
 * @return
 * @throws IOException
 */
public static BufferedImage toBufferedImage(QrCodeOptions qrCodeConfig, BitMatrixEx bitMatrix) throws IOException {
    int qrCodeWidth = bitMatrix.getWidth();
    int qrCodeHeight = bitMatrix.getHeight();
    BufferedImage qrCode = new BufferedImage(qrCodeWidth, qrCodeHeight, BufferedImage.TYPE_INT_RGB);

    for (int x = 0; x < qrCodeWidth; x++) {
        for (int y = 0; y < qrCodeHeight; y++) {
                qrCode.setRGB(x, y,
                        bitMatrix.get(x, y) ?
                                qrCodeConfig.getMatrixToImageConfig().getPixelOnColor() :
                            qrCodeConfig.getMatrixToImageConfig().getPixelOffColor());
        }
    }
    
    ...
}

注意

BitMatrixExcom.google.zxing.common.BitMatrix 的拓展,后面说明为什么这么做,

此处知晓 com.hust.hui.quickmedia.common.qrcode.BitMatrixEx#get 等同于 com.google.zxing.common.BitMatrix#get即可

说明

  • 上面的逻辑比较清晰,先创建一个置顶大小的图像,然后遍历 bitMatrix,对图像进行着色

  • bitMatrix.get(x, y) == true 表示该处为二维码的有效信息(这个是在二维码生成时决定,zxing的二维码生成逻辑负责生成BitMatrix对象,原理此处省略,因为我也没仔细研究),然后涂上配置的前置色;否则表示空白背景,涂上背景色即可

2. 位置探测图行可配置

位置探测图形就是二维码的左上角,右上角,左下角的三个矩形框(前面途中的三个红框),用于定位二维码使用,这里的实现确保它的颜色可以与二维码的前置色不同

经过上面的二维码颜色渲染,很容易就可以想到,在二维码的最终渲染时,对位置探测图形采用不同的颜色进行渲染即可,所以渲染代码如下

/**
 * 根据二维码配置 & 二维码矩阵生成二维码图片
 *
 * @param qrCodeConfig
 * @param bitMatrix
 * @return
 * @throws IOException
 */
public static BufferedImage toBufferedImage(QrCodeOptions qrCodeConfig, BitMatrixEx bitMatrix) throws IOException {
    int qrCodeWidth = bitMatrix.getWidth();
    int qrCodeHeight = bitMatrix.getHeight();
    BufferedImage qrCode = new BufferedImage(qrCodeWidth, qrCodeHeight, BufferedImage.TYPE_INT_RGB);

    for (int x = 0; x < qrCodeWidth; x++) {
        for (int y = 0; y < qrCodeHeight; y++) {
            if (bitMatrix.isDetectCorner(x, y)) { // 着色位置探测图形
                qrCode.setRGB(x, y,
                        bitMatrix.get(x, y) ?
                                qrCodeConfig.getDetectCornerColor().getPixelOnColor() :
                                qrCodeConfig.getDetectCornerColor().getPixelOffColor());
            } else { // 着色二维码主题
                qrCode.setRGB(x, y,
                        bitMatrix.get(x, y) ?
                                qrCodeConfig.getMatrixToImageConfig().getPixelOnColor() :
                                qrCodeConfig.getMatrixToImageConfig().getPixelOffColor());
            }
        }
    }
    
    ....
}

相比较与之前,在遍历逻辑中,多了一个是否为位置探测图形的分支判断

if (bitMatrix.isDetectCorner(x, y)) { // 着色位置探测图形
  qrCode.setRGB(x, y,
      bitMatrix.get(x, y) ?
        qrCodeConfig.getDetectCornerColor().getPixelOnColor() :
        qrCodeConfig.getDetectCornerColor().getPixelOffColor());
} 

所以我们的问题就是如何判断(x,y)坐标对应的位置是否为位置探测图形?

位置探测图形判定

这个判定的逻辑,就需要深入到二维码矩阵的生成逻辑中,直接给出对应代码位置

// Embed basic patterns
// The basic patterns are:
// - Position detection patterns
// - Timing patterns
// - Dark dot at the left bottom corner
// - Position adjustment patterns, if need be
com.google.zxing.qrcode.encoder.MatrixUtil#embedBasicPatterns


// 确定位置探测图形的方法
com.google.zxing.qrcode.encoder.MatrixUtil#embedPositionDetectionPatternsAndSeparators

// 自适应调整矩阵的方法
com.google.zxing.qrcode.encoder.MatrixUtil#maybeEmbedPositionAdjustmentPatterns

直接看代码,会发现位置探测图形的二维数组如下

private static final int[][] POSITION_DETECTION_PATTERN =  {
    {1, 1, 1, 1, 1, 1, 1},
    {1, 0, 0, 0, 0, 0, 1},
    {1, 0, 1, 1, 1, 0, 1},
    {1, 0, 1, 1, 1, 0, 1},
    {1, 0, 1, 1, 1, 0, 1},
    {1, 0, 0, 0, 0, 0, 1},
    {1, 1, 1, 1, 1, 1, 1},
};

private static final int[][] POSITION_ADJUSTMENT_PATTERN = {
    {1, 1, 1, 1, 1},
    {1, 0, 0, 0, 1},
    {1, 0, 1, 0, 1},
    {1, 0, 0, 0, 1},
    {1, 1, 1, 1, 1},
};

到这里,我们的判断就比较清晰了,位置探测图形有两种规格,5 or 7

在看具体的判定逻辑之前,先看 BitMatrixEx增强类,可以判定(x,y)坐标处是否为位置探测图形,内部判定逻辑和 BitMatrix中是否为二维码有效信息的判定一致

@Getter
@Setter
public class BitMatrixEx {
    private final int width;
    private final int height;
    private final int rowSize;
    private final int[] bits;


    private BitMatrix bitMatrix;

    public BitMatrixEx(BitMatrix bitMatrix) {
        this(bitMatrix.getWidth(), bitMatrix.getHeight());
        this.bitMatrix = bitMatrix;

    }

    private BitMatrixEx(int width, int height) {
        if (width < 1 || height < 1) {
            throw new IllegalArgumentException("Both dimensions must be greater than 0");
        }

        this.width = width;
        this.height = height;
        this.rowSize = (width + 31) / 32;
        bits = new int[rowSize * height];
    }



    public void setRegion(int left, int top, int width, int height) {
        int right = left + width;
        int bottom = top + height;

        for (int y = top; y < bottom; y++) {
            int offset = y * rowSize;
            for (int x = left; x < right; x++) {
                bits[offset + (x / 32)] |= 1 << (x & 0x1f);
            }
        }
    }


    public boolean get(int x, int y) {
        return bitMatrix.get(x, y);
    }


    public boolean isDetectCorner(int x, int y) {
        int offset = y * rowSize + (x / 32);
        return ((bits[offset] >>> (x & 0x1f)) & 1) != 0;
    }
}

位置判定逻辑

位置判定逻辑在 com.hust.hui.quickmedia.common.util.QrCodeUtil#renderResult 方法中,简单说一下这个方法的作用

直接看判定逻辑

// 获取位置探测图形的size,根据源码分析,有两种size的可能
// {@link com.google.zxing.qrcode.encoder.MatrixUtil.embedPositionDetectionPatternsAndSeparators}
ByteMatrix input = qrCode.getMatrix();
// 因为位置探测图形的下一位必然是0,所以下面的一行可以判定选择的是哪种规格的位置判定
int detectCornerSize = input.get(0, 5) == 1 ? 7 : 5;

for (int inputY = 0, outputY = topPadding; inputY < inputHeight; inputY++, outputY += multiple) {
    // Write the contents of this row of the barcode
    for (int inputX = 0, outputX = leftPadding; inputX < inputWidth; inputX++, outputX += multiple) {
        if (input.get(inputX, inputY) == 1) {
            // 二维码的有效信息设置(即传统二维码中黑色局域的确定)
            output.setRegion(outputX, outputY, multiple, multiple);
        }


        // 设置三个位置探测图形
        if (inputX < detectCornerSize && inputY < detectCornerSize // 左上角
                || (inputX < detectCornerSize && inputY >= inputHeight - detectCornerSize) // 左下脚
                || (inputX >= inputWidth - detectCornerSize && inputY < detectCornerSize)) { // 右上角
            res.setRegion(outputX, outputY, multiple, multiple);
        }
    }
}

3. 背景图支持

前面两个涉及到二维码本身的修改,接下来的背景 & logo则基本上无二维码无关,只是图片的操作而已,背景图支持,即将背景图作为图层,将二维码渲染在正中间即可

对于图片的覆盖,直接借用 java.awt 包下的工具类即可实现

/**
 * 绘制背景图
 *
 * @param source     原图
 * @param background 背景图
 * @param bgW        背景图宽
 * @param bgH        背景图高
 * @return
 * @throws IOException
 */
public static BufferedImage drawBackground(BufferedImage source, String background, int bgW, int bgH) throws IOException {
    int sW = source.getWidth();
    int sH = source.getHeight();


    // 背景的图宽高不应该小于原图
    if (bgW < sW) {
        bgW = sW;
    }

    if (bgH < sH) {
        bgH = sH;
    }


    // 获取背景图
    BufferedImage bg = getImageByPath(background);
    if (bg.getWidth() != bgW || bg.getHeight() != bgH) { // 需要缩放
        BufferedImage temp = new BufferedImage(bgW, bgH, BufferedImage.TYPE_INT_ARGB);
        temp.getGraphics().drawImage(bg.getScaledInstance(bgW, bgH, Image.SCALE_SMOOTH)
                , 0, 0, null);
        bg = temp;
    }


    // 绘制背景图
    int x = (bgW - sW) >> 1;
    int y = (bgH - sH) >> 1;
    Graphics2D g2d = bg.createGraphics();
    g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.8f)); // 透明度, 避免看不到背景
    g2d.drawImage(source, x, y, sW, sH, null);
    g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1.0f));
    g2d.dispose();
    bg.flush();
    return bg;
}

简单说一下上面的实现逻辑

  • 获取背景图
  • 根据置顶的背景图大小,对原背景图进行缩放
  • 将目标图片(二维码)绘制在背景图正中间

其中,我们对二维码的覆盖设置了透明度为0.8,确保不会完全覆盖背景图,导致完全看不到背景是什么,此处如有其他的需求场景可以进行可配置化处理

4. logo支持

其实logo的支持和背景的支持逻辑基本没什么差别,都是将一个图绘制在另一个图上

具体的实现如下, 先无视logo样式的选择问题

/**
 * 在图片中间,插入圆角的logo
 *
 * @param qrCode      原图
 * @param logo        logo地址
 * @param logoStyle   logo 的样式 (圆角, 直角)
 * @param logoBgColor logo的背景色
 * @throws IOException
 */
public static void insertLogo(BufferedImage qrCode,
                              String logo,
                              QrCodeOptions.LogoStyle logoStyle,
                              Color logoBgColor) throws IOException {
    int QRCODE_WIDTH = qrCode.getWidth();
    int QRCODE_HEIGHT = qrCode.getHeight();

    // 获取logo图片
    BufferedImage bf = getImageByPath(logo);
    int boderSize = bf.getWidth() / 15;
    // 生成圆角边框logo
    bf = makeRoundBorder(bf, logoStyle, boderSize, logoBgColor); // 边距为二维码图片的1/15

    // logo的宽高
    int w = bf.getWidth() > QRCODE_WIDTH * 2 / 10 ? QRCODE_WIDTH * 2 / 10 : bf.getWidth();
    int h = bf.getHeight() > QRCODE_HEIGHT * 2 / 10 ? QRCODE_HEIGHT * 2 / 10 : bf.getHeight();

    // 插入LOGO
    Graphics2D graph = qrCode.createGraphics();

    int x = (QRCODE_WIDTH - w) >> 1 ;
    int y = (QRCODE_HEIGHT - h) >> 1;

    graph.drawImage(bf, x, y, w, h, null);
    graph.dispose();
    bf.flush();
}

上面的主要逻辑,其实没啥区别,接下来主要关心的则是圆角图形生成以及边框的支持

5. 圆角图形

生成圆角图片是一个非常常见的需求

先借用new RoundRectangle2D.Float(0, 0, w, h, cornerRadius, cornerRadius)绘制一个圆角的画布出来

将原图绘制在画布上即可

/**
 * 生成圆角图片
 *
 * @param image        原始图片
 * @param cornerRadius 圆角的弧度
 * @return 返回圆角图
 */
public static BufferedImage makeRoundedCorner(BufferedImage image,
                                              int cornerRadius) {
    int w = image.getWidth();
    int h = image.getHeight();
    BufferedImage output = new BufferedImage(w, h,
            BufferedImage.TYPE_INT_ARGB);

    Graphics2D g2 = output.createGraphics();

    // This is what we want, but it only does hard-clipping, i.e. aliasing
    // g2.setClip(new RoundRectangle2D ...)

    // so instead fake soft-clipping by first drawing the desired clip shape
    // in fully opaque white with antialiasing enabled...
    g2.setComposite(AlphaComposite.Src);
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
    g2.setColor(Color.WHITE);
    g2.fill(new RoundRectangle2D.Float(0, 0, w, h, cornerRadius,
            cornerRadius));

    // ... then compositing the image on top,
    // using the white shape from above as alpha source
    g2.setComposite(AlphaComposite.SrcAtop);
    g2.drawImage(image, 0, 0, null);

    g2.dispose();

    return output;
}

6. 圆角边框的图片

上面实现圆角图片之后,再考虑生成一个带圆角边框的图片就很简单了,直接绘制一个大一号的存色边框,然后将圆角图片绘制上去即可

/**
 * <p>
 * 生成圆角图片 & 圆角边框
 *
 * @param image     原图
 * @param logoStyle 圆角的角度
 * @param size      边框的边距
 * @param color     边框的颜色
 * @return 返回带边框的圆角图
 */
public static BufferedImage makeRoundBorder(BufferedImage image,
                                            QrCodeOptions.LogoStyle logoStyle,
                                            int size, Color color) {
    // 将图片变成圆角
    int cornerRadius = 0;
    if (logoStyle == QrCodeOptions.LogoStyle.ROUND) {
        cornerRadius = image.getWidth() / 4;
        image = makeRoundedCorner(image, cornerRadius);
    }

    int w = image.getWidth() + size;
    int h = image.getHeight() + size;
    BufferedImage output = new BufferedImage(w, h,
            BufferedImage.TYPE_INT_ARGB);

    Graphics2D g2 = output.createGraphics();
    g2.setComposite(AlphaComposite.Src);
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
    g2.setColor(color == null ? Color.WHITE : color);
    g2.fill(new RoundRectangle2D.Float(0, 0, w, h, cornerRadius,
            cornerRadius));

    // ... then compositing the image on top,
    // using the white shape from above as alpha source
//        g2.setComposite(AlphaComposite.SrcAtop);
    g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1.0f));
    g2.drawImage(image, size / 2, size / 2, null);
    g2.dispose();

    return output;
}

测试

上面分别对每一个点进行了实现并加以简单说明,最后就是需要将上面的都串起来进行测试了,因为我们的工程是在前面已经搭建好的二维码服务上进行的,所以测试代码也比较简单,如下

@Test
public void testGenColorCode() {
    String msg = "https://my.oschina.net/u/566591/blog/1359432";
    // 根据本地文件生成待logo的二维码, 重新着色位置探测图像
    try {
        String logo = "logo.jpg";
        String bg = "bg.png";
        BufferedImage img = QrCodeGenWrapper.of(msg)
                .setW(300)
                .setPreColor(0xff0000ff)
                .setBgColor(0xffFFFF00)
                .setDetectCornerPreColor(0xffff0000)
                .setPadding(2)
                .setLogo(logo)
                .setLogoStyle(QrCodeOptions.LogoStyle.ROUND)
                .setLogoBgColor(0xff00cc00)
                .setBackground(bg)
                .asBufferedImage();


        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ImageIO.write(img, "png", outputStream);
        System.out.println(Base64Util.encode(outputStream));
    } catch (Exception e) {
        System.out.println("create qrcode error! e: " + e);
        Assert.assertTrue(false);
    }
}

测试执行示意图

http://s2.mogucdn.com/mlcdn/c45406/170728_2lebbba9b47037cc0g03hd42hf6ga_1224x639.gif


其他

项目源码: https://github.com/liuyueyi/quick-media

相关博文:

个人博客:一灰的个人博客

公众号获取更多:

https://static.oschina.net/uploads/img/201707/09205944_0PzS.jpg

© 著作权归作者所有

共有 人打赏支持
小灰灰Blog
粉丝 160
博文 150
码字总数 258693
作品 0
武汉
程序员
加载中

评论(1)

天籁111
天籁111
学习了
生成图片二维码工具--visual-qr-code

visual-qr-code 可以创建出精美的二维码,与传统的二维码不同的是,设置的背景图片或logo并不是只是在二维码中心,背景图片和logo都是半透明的,让二维码更好看 一、使用示例(详细情况源码中...

boat824109722 ⋅ 01/04 ⋅ 0

visual-qr-code 1.0 发布,可设置 Logo 的二维码生成

visual-qr-code可以创建出精美的二维码,与传统的二维码不同的是,设置的背景图片或logo并不是只是在二维码中心,背景图片和logo都是半透明的,让二维码更好看 一、使用示例(详细情况源码中的...

boat824109722 ⋅ 01/08 ⋅ 1

二维码在线生成api

二维码在线生成api,执行生成二维码,直接用标签调用接口地址即可。 接口名称:二维码在线生成api 接口平台:聚合数据 接口地址:http://liantu.api.juhe.cn/api.php 支持格式:json 请求方式...

熊babi ⋅ 2016/03/11 ⋅ 0

Java实现带logo的二维码

Java实现带logo的二维码 二维码应用到生活的各个方面,会用代码实现二维码,我想一定是一项加分的技能。好了,我们来一起实现一下吧。 我们实现的二维码是基于QR Code的标准的,QR Code是由日...

奇迹迪 ⋅ 05/28 ⋅ 0

boat824109722/visual-qr-code

visual-qr-code 该应用的功能是创建可以设置背景图片或者logo的二维码 一、使用示例(详细情况源码中的测试用例) 示例1: 测试代码 @Testpublic void testPOSITIONRECTANGLE() { e.printStac...

boat824109722 ⋅ 01/04 ⋅ 0

thinkphp5 生成二维码在模板中显示

thinkphp5 生成二维码 使用php qrcode类库 composer require endroid/qrcode 导入phpqrcode类库 2. 类库使用 a.$qrCode = new EndroidQrCodeQrCode();//实例化 b.设置生成二维码生成的各项...

phpervip ⋅ 2017/10/24 ⋅ 0

php qrcode 生成二维码后变成透明背景且按需调整大小并贴到图片的指定位置

发现自己快两个月没写博客,最近搞定毕业的相关事情了,稍微松点了,可以全身心地投入到工作中来,今天想起写写博客,记录下最近工作过的内容,供以后查看温习。打算建立个栏目专门存放工作的...

inite ⋅ 05/12 ⋅ 0

使用phpqrcode生成二维码

使用PHP语言生成二维码,还是挺有难度的,当然调用生成二维码图片的接口(比如:联图网http://www.liantu.com/的接口)除外,如果自己写代码生成,真的无从下手。然而,我们可以使用phpqrco...

new个对象 ⋅ 04/18 ⋅ 0

iOS开发-定制多样式二维码

二维码/条形码是按照某种特定的几何图形按一定规律在平台(一维/二维方向上)分布的黑白相间的图形纪录符号信息。使用若干个与二进制对应的几何形体来表示文字数值信息。 最常见的二维码功能...

04zhujunjie ⋅ 2015/11/02 ⋅ 0

bosco_liao/qrext4j

QrcGen 不再维护,改名为 “QRext4j”,关注此项目的OSCer请转移到此。。 本项目为QrcGen改名升级版(旧项目名称是随便起的 )。。。 QRext4j 一个简单易用的二维码生成器,可以自定义二维码...

bosco_liao ⋅ 2017/09/02 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

用SQL命令查看Mysql数据库大小

要想知道每个数据库的大小的话,步骤如下: 1、进入information_schema 数据库(存放了其他的数据库的信息) use information_schema; 2、查询所有数据的大小: select concat(round(sum(da...

源哥L ⋅ 17分钟前 ⋅ 0

两个小实验简单介绍@Scope("prototype")

实验一 首先有如下代码(其中@RestController的作用相当于@Controller+@Responsebody,可忽略) @RestController//@Scope("prototype")public class TestController { @RequestMap...

kalnkaya ⋅ 21分钟前 ⋅ 0

php-fpm的pool&php-fpm慢执行日志&open_basedir&php-fpm进程管理

12.21 php-fpm的pool pool是PHP-fpm的资源池,如果多个站点共用一个pool,则可能造成资源池中的资源耗尽,最终访问网站时出现502。 为了解决上述问题,我们可以配置多个pool,不同的站点使用...

影夜Linux ⋅ 31分钟前 ⋅ 0

微服务 WildFly Swarm 管理

Expose Application Metrics and Information 要公开关于我们的微服务的有用信息,我们需要做的就是将监视器模块添加到我们的pom.xml中: 这将使在管理和监视功能得到实现。从监控角度来看,...

woshixin ⋅ 31分钟前 ⋅ 0

java连接 mongo伪集群部署遇到的坑

部署mongo伪集群 #创建mongo数据存放文件地址mkdir -p /usr/local/config1/datamkdir -p /usr/local/config2/data mkdir -p /usr/local/config3/data mkdir -p /usr/local/config1/l......

努力爬坑人 ⋅ 32分钟前 ⋅ 0

React Native & Weex 区别

JS引擎 Weex使用V8, React native使用JSCore JS开发框架 ( Js Framework ) Weex基于vue.js(2W+ star)。小巧轻量的前端开发框架,组件化,数据绑定,2.0引入virtual dom。 ReactNative使用...

东东笔记 ⋅ 40分钟前 ⋅ 1

UIkit 分页组件动态加载简单实现

1. 问题描述 使用过UIkit分页组件的都清楚,UIkit的分页不能动态刷新数据,也就是不能在点击下一页的时候,动态从后台加载数据,并且刷新页数以及该页数上的数据,下面是一个简单实现,没有做...

影狼 ⋅ 41分钟前 ⋅ 0

Mobx入门之三:Provider && inject

上一节中<App/>组件传递状态temperatures给children -- <TemperatureInput />,如果组建是一个tree, 那么属性的传递则会非常繁琐。redux使用Provider给子组件提供store, connect将子组件和s...

pengqinmm ⋅ 43分钟前 ⋅ 0

魔兽世界 7.0版本 S23/S24/S25全职业普通+精锐套

  死亡骑士   (联盟)   (部落)   (精锐)   恶魔猎手   (联盟)   (部落)   (精锐)   德鲁伊   (联盟)   (部落)   (精锐)   猎人   (联盟) ...

wangchen1999 ⋅ 50分钟前 ⋅ 0

maven顶级pom和子pom的版本号批量修改

当一个版本发布,新起一个版本时,我们只需要手动修改一下项目中pom.xml的版本号就可以了。但是如果这个maven项目有很多的子模块项目,那么一个个手动的去改就显得费时费力又繁琐了。还好,m...

ArlenXu ⋅ 59分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部