美文网首页
Java中while循环的使用(二):反复识别验证码图片,直到正

Java中while循环的使用(二):反复识别验证码图片,直到正

作者: 墨色尘埃 | 来源:发表于2020-05-20 17:48 被阅读0次

批量发送邮件

上文中技术点二,用到了百度文字识别api,以及多次识别验证码,直到正确为止,用到了while循环

pom中引入百度api依赖

        <dependency>
            <groupId>com.baidu.aip</groupId>
            <artifactId>java-sdk</artifactId>
            <version>4.8.0</version>
        </dependency>

如果这种方式引入不进来,可以使用lib包下放入jar包的方式引入

image.png

然后pom.xml中引入

        <!--百度文字识别-->
        <dependency>
            <groupId>com.baidu.aip</groupId>
            <artifactId>java-sdk</artifactId>
            <version>4.11.0</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/lib/aip-java-sdk-4.11.1.jar</systemPath>
        </dependency>

利用百度文字识别API识别图像中的文字
https://cloud.baidu.com/doc/OCR/index.html

验证码识别的代码如下

    /**
     * 验证码,经过百度文字识别api之后,识别出图片中的文字
     * 递归调用,貌似有问题,返回多次数据
     *
     * @param userId
     * @return
     * @throws IOException
     */
    public String checkHandleCode(String userId) throws Exception {

        JSONArray wordsResult = checkWordsResult(userId);
        boolean jsonArrayEmptyFlag = true;
        while (jsonArrayEmptyFlag) {
            if (wordsResult.size() == 0 || org.springframework.util.StringUtils.isEmpty(wordsResult)) {
                wordsResult = null;
                jsonArrayEmptyFlag = false;
                wordsResult = checkWordsResult(userId);
            } else {
                jsonArrayEmptyFlag = false;
            }
        }

        com.alibaba.fastjson.JSONObject o = (com.alibaba.fastjson.JSONObject) wordsResult.get(0);
        String words = (String) o.get("words");

        //取出百度文字识别,未经处理的文字,判断是否为空
        //为空,获取下一张验证码继续识别
        //不为空,跳出循环,执行下一步

//        // 模拟出错状态
//        String[] randomArray = {words, null, ""};
//        int i = (int) (Math.random() * randomArray.length);
//        words = randomArray[i];

        boolean emptyFlag = true;
        while (emptyFlag) {
            if (org.springframework.util.StringUtils.isEmpty(words)) {
                words = null;
                emptyFlag = false;
                words = checkHandleCode(userId);
            } else {
                emptyFlag = false;
                break;
            }
        }

        //最原始的未经处理的文字,不为空之后,去除空格后的新String判断是否为空
        //为空,获取下一张验证码继续识别
        //不为空,跳出循环,执行下一步
        words = words.replace(" ", "");
        boolean replaceFlag = true;
        while (replaceFlag) {
            if (org.springframework.util.StringUtils.isEmpty(words)) {
                words = null;
                replaceFlag = false;
                words = checkHandleCode(userId);
            } else {
                replaceFlag = false;
                break;
            }
        }

        //判断新String是否是4位
        //不等于4,获取下一张验证码继续识别
        //等于4,跳出循环,执行下一步
        boolean fourCharFlag = true;
        while (fourCharFlag) {
            if (words.length() != 4) {
                //递归调用中,如果当前验证码不符合四位,又会调用自己的方法
                //但是上一个自己的方法还没有结束,变量生命周期没有结束(见引申),所以必须对该变量修改,恢复原值
                //引申:虚拟机栈描述的是JAVA方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧(STACKFRAME
                // )用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈和出栈的过程。
                words = null;
                fourCharFlag = false;
                words = checkHandleCode(userId);
            } else {
                fourCharFlag = false;
                break;
            }
        }
        return words;
    }

重点看这几段代码

        boolean emptyFlag = true;
        while (emptyFlag) {
            if (org.springframework.util.StringUtils.isEmpty(words)) {
                words = null;
                emptyFlag = false;
                words = checkHandleCode(userId);
            } else {
                emptyFlag = false;
                break;
            }
        }

第一次进入这里
先定义了一个局部变量boolean emptyFlag = true,进入while循环,如果上一步识别到的验证码图片上的words是空的话,则再次进行识别(即再次调用该方法,递归)

再次调用该方法,如果一切顺利,第二次进入到这里
然后会再次定义一个局部变量boolean emptyFlag = true,进入while循环,第二次判断识别到的验证码图片上的words
如果为空,则再次递归
如果不为空,则结束第二次的方法,返回第一次调用的方法中(返回第一次调用方法的while处)
这里一定要设置emptyFlag为false,因为是局部变量,如果第一次进到到if条件里没有设置的话,当第二次方法调用结束回到第一次方法的while处时,此处的emptyFlag还是true,就会进入死循环

image.png

递归的过程大概如下

image.png

相关文章

网友评论

      本文标题:Java中while循环的使用(二):反复识别验证码图片,直到正

      本文链接:https://www.haomeiwen.com/subject/ymygohtx.html