批量发送邮件
上文中技术点二,用到了百度文字识别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
网友评论