精华内容
下载资源
问答
  • JAVA 实现 QQ 邮箱发送验证码功能(不局限于框架)本来想实现 QQ 登录,有域名一直没用过,还得备案,好麻烦,只能过几天再更新啦。先把实现的发送邮箱验证码更能更新了。老规矩,更多内容在注释山聊。首先还是先放上...

    JAVA 实现 QQ 邮箱发送验证码功能(不局限于框架)

    本来想实现 QQ 登录,有域名一直没用过,还得备案,好麻烦,只能过几天再更新啦。

    先把实现的发送邮箱验证码更能更新了。

    老规矩,更多内容在注释山聊。

    首先还是先放上成功的截图:

    7b904876e7135693596fcf09243d4cce.png

    (1)准备阶段 - 获取授权码

    授权码(这个授权码是让 JAVA 程序来登录发送者的 QQ 邮箱的,相当于登动态密码)

    获取步骤:

    点击【设置】>【账户】>【POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务】

    efde31fc71d4f5d736342bb37ec6f77f.png

    (2)加载相关 jar 包

    使用 Maven 的话,直接拷贝下面的就可以:

    javax.activation

    activation

    1.1.1

    javax.mail

    mail

    1.4.7

    org.apache.commons

    commons-email

    1.5

    (3)代码编写 - 示例

    请根据提示自行修改配置

    package com.xpwi.action;

    import org.apache.commons.mail.SimpleEmail;

    import org.springframework.context.annotation.Scope;

    import org.springframework.stereotype.Controller;

    import org.springframework.web.bind.annotation.RequestMapping;

    import org.springframework.web.bind.annotation.ResponseBody;

    @Controller

    @Scope("prototype")

    @RequestMapping("/email")

    public class EmailValidateAction {

    //邮箱验证

    //*.do 的格式是 Spring MVC 拦截的一种配置,请自行修改

    @RequestMapping("/sendCode.do")

    @ResponseBody

    public int emailValidate(){

    SimpleEmail email=new SimpleEmail();//创建一个HtmlEmail实例对象

    try {

    //填写邮箱服务器,如是QQ邮箱服务器,直接用:smtp.qq.com

    email.setHostName("邮箱服务器");

    email.setCharset("utf-8");

    //设置收件人

    email.addTo("收件人邮箱地址");

    //设置发送人邮箱,和用户名

    email.setFrom("发件人邮箱地址","发件人署名(随意写)");

    //配置邮箱加授权码,相当于等于自己的邮箱

    email.setAuthentication("发送者的邮箱","发送者的授权码");

    //使用安全链接

    email.setSSLOnConnect(true);

    //设置邮件的主题

    email.setSubject("注册验证码");

    //设置邮件的内容,自行修改动态验证码

    email.setMsg("尊敬的用户:你好!\n 注册验证码为:123444" +"\n"+" (有效期为一分钟)");

    //发送

    email.send();

    }catch (Exception e){

    e.printStackTrace();

    //返回 0 表示失败

    return 0;

    }

    //返回 1 表示发送成功

    return 1;

    }

    }

    更多文章链接

    展开全文
  • java ssh框架实现简单的邮箱发送

    千次阅读 2017-03-03 18:31:09
    全xml配置的ssh框架 在spring.xml中配置: true true  30000 发送邮件工具类: package cn.dupenghui.util; import java.util.Properties; import javax.mail.Session; import javax.ma

    全xml配置的ssh框架

    在spring.xml中配置:

    <!-- spring发送邮件的bean配置开始 -->
    <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
    <!-- 基于校验规则的邮件发送方式 -->
    <!-- SMTP协议介绍 -->
    <property name="javaMailProperties">
    <props>
    <!-- 必须进行授权认证,它的目的就是阻止他人任意乱发邮件 -->
    <prop key="mail.smtp.auth">true</prop>
    <!-- SMTP加密方式:连接到一个TLS保护连接 -->
    <prop key="mail.smtp.starttls.enable">true</prop> 
    <!-- 设置邮件发送超时时间 -->
    <prop key="mail.smtp.timeout">30000</prop>
    </props>
    </property>
    </bean>
    <bean id="sendMail" class="cn.dupenghui.util.SendMailUtil">
    <property name="mailSender" ref="mailSender"></property>
    </bean>
    <!-- spring发送邮件的bean配置结束 -->


    发送邮件工具类:

    package cn.dupenghui.util;

    import java.util.Properties;
    import javax.mail.Session;
    import javax.mail.internet.InternetAddress;
    import javax.mail.internet.MimeMessage;
    import org.springframework.mail.MailException;
    import org.springframework.mail.javamail.JavaMailSenderImpl;

    public class SendMailUtil {

    private static JavaMailSenderImpl mailSender;

    //静态变量注入提供的get和set方法不能是静态方法,否则会报错,

    public  JavaMailSenderImpl getMailSender() {
    return mailSender;
    }
    public  void setMailSender(JavaMailSenderImpl mailSender) {
    SendMailUtil.mailSender = mailSender;
    }

    /**
    * 即时发送简单内容邮件

    * @param reciveEmail
    *            接收邮箱
    * @param subject
    *            邮件主题
    * @param Text
    *            邮件内容
    * @return
    */
    public static boolean sendEmail(String reciveEmail, String subject,
    String Text) throws Exception {
    // SimpleMailMessage ssm = new SimpleMailMessage();
    // ssm.setFrom(SetSystemProperty.getKeyValue("MAILSENDER_USERNAME"));// cndona@163.com
    // ssm.setTo(reciveEmail);
    // ssm.setSubject(subject);
    // ssm.setSentDate(new Date());

    // ssm.setText(Text);


    Properties props = new Properties(); // 用于连接邮件服务器的参数配置(发送邮件时才需要用到)
    Session session = Session.getDefaultInstance(props); // 根据参数配置,创建会话对象(为了发送邮件准备的)
    MimeMessage message = new MimeMessage(session); // 创建邮件对象
    // 2. From: 发件人
    // 其中 InternetAddress 的三个参数分别为: 邮箱, 显示的昵称(只用于显示, 没有特别的要求), 昵称的字符集编码
    // 真正要发送时, 邮箱必须是真实有效的邮箱。
    message.setFrom(new InternetAddress(SetSystemProperty
    .getKeyValue("MAILSENDER_USERNAME"), " ", "UTF-8"));


    // 3. To: 收件人
    message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(
    reciveEmail, "USER_CC", "UTF-8"));
    // 4. Subject: 邮件主题
    message.setSubject(subject, "UTF-8");


    // 5. Content: 邮件正文(可以使用html标签)
    message.setContent(Text, "text/html;charset=UTF-8");



    mailSender.setHost(SetSystemProperty.getKeyValue("MAILSENDER_HOST"));
    mailSender.setUsername(SetSystemProperty
    .getKeyValue("MAILSENDER_USERNAME"));
    mailSender.setPort(Integer.valueOf(SetSystemProperty
    .getKeyValue("MAILSENDER_PORT")));
    mailSender.setPassword(SetSystemProperty
    .getKeyValue("MAILSENDER_PASSWORD"));

    try {
    mailSender.send(message);
    return true;
    } catch (MailException e) {
    e.printStackTrace();
    return false;
    }
    }
    }
    展开全文
  • 基于java框架-网易企业邮箱集成接口 ,可以实现对企业邮件的用户帐号进行管理接口源码
  • 所用到的有:eclipse+maven+testng+log4j+Excel在这里将以登录163邮箱后新建联系人作为例子框架搭建步骤:1、新建maven工程,在pom.xml文件中导入项目需要的jar包,需要导入的有 selenium-java,testng,log4j,poi...

    所用到的有:eclipse+maven+testng+log4j+Excel

    在这里将以登录163邮箱后新建联系人作为例子

    框架搭建步骤:

    1、新建maven工程,在pom.xml文件中导入项目需要的jar包,需要导入的有 selenium-java,testng,log4j,poi和poi-ooxml。最后两个是用于操作Excel的

    2、在工程中新建4个Package,分别命名为:

    cn.appModules:存放业务逻辑的封装方法

    cn.pageObjects:存放页面元素

    cn.testCase:存放测试用例

    cn.util:存放工具类

    3.在工程根目录下新建一个log4j.xml文件存放log4j的配置信息,一个objectMap.properties文件存放页面元素定位方式和定位表达式

    pom.xml文件的内容如下:

    4.0.0

    Selenium

    DataFrameWork

    0.0.1-SNAPSHOT

    jar

    DataFrameWork

    http://maven.apache.org

    UTF-8

    junit

    junit

    3.8.1

    test

    org.seleniumhq.selenium

    selenium-java

    2.53.1

    org.testng

    testng

    6.9.9

    test

    log4j

    log4j

    1.2.17

    org.apache.poi

    poi

    3.17

    org.apache.poi

    poi-ooxml

    3.17

    一、首先实现log4j打印日志功能

    log4j.xml文件内容如下:

    在cn.util包下新建log类,代码如下

    package cn.util;

    import org.apache.log4j.Logger;

    public class log {

    //初始化Logger对象

    private static Logger log=Logger.getLogger(log.class.getName());

    //定义一个静态方法,可以打印自定义的某个测试用例开始执行的日志信息

    public static void startTestCase(String CaseName){

    log.info("======================================================================");

    log.info("************* "+CaseName+" 用例开始执行"+" *************");

    }

    //定义一个静态方法,可以打印自定义的某个测试用例结束执行的日志信息

    public static void endTestCase(String CaseName){

    log.info("************* "+CaseName+" 用例执行结束"+" *************");

    log.info("======================================================================");

    }

    //定义一个静态info方法,打印自定义的info级别的日志信息

    public static void info(String message){

    log.info(message);

    }

    //定义一个静态的warn方法,打印自定义的warn级别的日志信息

    public static void warn(String message){

    log.warn(message);

    }

    //定义一个静态的error方法,打印自定义的error级别的日志信息

    public static void error(String message){

    log.error(message);

    }

    //定义一个静态的fatal方法,打印自定义的fatal级别的日志信息

    public static void fatal(String message){

    log.fatal(message);

    }

    //定义一个静态的debug方法,打印自定义的debug级别的日志信息

    public static void debug(String message){

    log.debug(message);

    }

    }

    二、封装截图方法。在cn.util包下新建FileUtil工具类、DataUtil工具类和Screenshot类

    FileUtil类代码如下:

    packagecn.util;importjava.io.File;importjava.io.IOException;//FileUtil 类用于创建目录和文件,此例子只是用此类的创建目录的方法

    public classFileUtil{public static booleancreateFile(String destFileName){

    File file=newFile(destFileName);if(file.exists()){

    log.info("创建单个文件"+destFileName+"失败,目标文件已存在!");return false;

    }if(destFileName.endsWith(file.separator)){

    log.info("创建单个文件"+destFileName+"失败,目标文件不能为目录!");return false;

    }//判断目标文件所在目录是否存在

    if(!file.getParentFile().exists()){//如果目标文件所在的目录不存在,则创建父目录

    log.info("目录文件所在目录不存在,准备创建它!");if(!file.getParentFile().mkdirs()){

    log.info("创建目标文件所在目录失败!");return false;

    }

    }//创建目标问价

    try{if(file.createNewFile()){

    log.info("创建单个文件"+destFileName+"成功!");return true;

    }else{

    log.info("创建单个文件"+destFileName+"失败!");return false;

    }

    }catch(IOException e){

    e.printStackTrace();

    log.info("创建单个文件"+destFileName+"失败!"+e.getMessage());return false;

    }

    }public static booleancreateDir(String destDirName){

    File dir=newFile(destDirName);if(dir.exists()){

    log.info("创建目录"+destDirName+"失败,目标目录已存在");return false;

    }//创建目录

    if(dir.mkdirs()){

    log.info("创建目录"+destDirName+"成功!");return true;

    }else{

    log.info("创建目录"+destDirName+"失败!");return false;

    }

    }

    }

    DataUtil类代码如下:

    packagecn.util;importjava.util.Date;//DataUtil类主要用于生成年、月、日、时、分、秒的信息,用于生成保存截图文件目录名和文件名

    public classDataUtil{//格式化输入日期,@return 返回字符型日期

    public staticString format(java.util.Date date,String format){

    String result="";try{if(date != null){

    java.text.DateFormat df=newjava.text.SimpleDateFormat(format);

    result=df.format(date);

    }

    }catch(Exception e){

    e.printStackTrace();

    }returnresult;

    }//返回年份 @return返回年份

    public static intgetYear(java.util.Date date){

    java.util.Calendar c=java.util.Calendar.getInstance();

    c.setTime(date);returnc.get(java.util.Calendar.YEAR);

    }//返回月份 @return返回月份

    public static intgetMonth(java.util.Date date){

    java.util.Calendar c=java.util.Calendar.getInstance();

    c.setTime(date);return c.get(java.util.Calendar.MONTH)+1;

    }//返回在月份中的第几天 @return返回月份中的第几天

    public static intgetDay(java.util.Date date){

    java.util.Calendar c=java.util.Calendar.getInstance();

    c.setTime(date);returnc.get(java.util.Calendar.DAY_OF_MONTH);

    }/** 返回小时

    * @param date

    * 日期

    * @return返回小时*/

    public static intgetHour(java.util.Date date){

    java.util.Calendar c=java.util.Calendar.getInstance();

    c.setTime(date);returnc.get(java.util.Calendar.HOUR_OF_DAY);

    }/** 返回分钟

    * @param date

    * 日期

    * @return返回分钟*/

    public static intgetMinute(java.util.Date date){

    java.util.Calendar c=java.util.Calendar.getInstance();

    c.setTime(date);returnc.get(java.util.Calendar.MINUTE);

    }/** 返回秒

    * @param date

    * 日期

    * @return返回秒*/

    public static intgetSecond(java.util.Date date){

    java.util.Calendar c=java.util.Calendar.getInstance();

    c.setTime(date);returnc.get(java.util.Calendar.SECOND);

    }

    }

    Screenshot类实现截图操作,代码如下:

    packagecn.util;importjava.io.File;importjava.util.Date;importorg.apache.commons.io.FileUtils;importorg.openqa.selenium.OutputType;importorg.openqa.selenium.TakesScreenshot;importorg.openqa.selenium.WebDriver;public classScreenshot{public static voidmethod(WebDriver driver,String CaseName) {try{//生成日期对象

    Date date=newDate();//调用DateUtil类中的方法,生成截图所在的文件夹日期类型

    String picDir="C:\\"+"errorScreenshot"+"\\"+String.valueOf(DataUtil.getYear(date))+"-"

    +String.valueOf(DataUtil.getMonth(date))+"-"+String.valueOf(DataUtil.getDay(date));if(!newFile(picDir).exists()){

    FileUtil.createDir(picDir);

    }//调用DataUtil类中的方法,生成截图文件的时间名称

    String filePath=picDir+"//"+String.valueOf(DataUtil.getHour(new Date()))+"时"+String.valueOf(DataUtil.getMinute(new Date()))+"分"+String.valueOf(DataUtil.getSecond(new Date()))+"秒"+CaseName+".png";//进行截图,并将文件内容保存在srcFile对象中

    File srcFile=((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);//File scrFile = new File("");//scrFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);//将截图文件内容写入磁盘中,生成截图文件

    FileUtils.copyFile(srcFile, newFile(filePath));

    }catch(Exception e){

    log.info("截图失败");

    }

    }

    }

    三、在cn.util包下新建ExcelUtil类,用于读写Excel表格。代码如下:

    packagecn.util;importjava.io.File;importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.io.IOException;importjava.util.ArrayList;importjava.util.List;importorg.apache.poi.hssf.usermodel.HSSFWorkbook;importorg.apache.poi.ss.usermodel.CellType;importorg.apache.poi.ss.usermodel.Row;importorg.apache.poi.ss.usermodel.Sheet;importorg.apache.poi.ss.usermodel.Workbook;importorg.apache.poi.xssf.usermodel.XSSFCell;importorg.apache.poi.xssf.usermodel.XSSFRow;importorg.apache.poi.xssf.usermodel.XSSFSheet;importorg.apache.poi.xssf.usermodel.XSSFWorkbook;public classExcelUtil {private staticXSSFSheet excelWSheet;private staticXSSFWorkbook excelWBook;private staticXSSFCell cell;private staticXSSFRow row;//指定要操作的excel文件的路径及sheet名称

    public static void setExcelFile(String path,String sheetName) throwsException{

    FileInputStream excelFile;try{

    excelFile= newFileInputStream(path);

    excelWBook= newXSSFWorkbook(excelFile);

    excelWSheet=excelWBook.getSheet(sheetName);

    }catch(Exception e) {

    e.printStackTrace();

    }

    }//读取excel文件指定单元格数据(此方法只针对.xlsx后辍的Excel文件)

    public static String getCellData(int rowNum,int colNum) throwsException{try{//获取指定单元格对象

    cell =excelWSheet.getRow(rowNum).getCell(colNum);//获取单元格的内容//如果为字符串类型,使用getStringCellValue()方法获取单元格内容,如果为数字类型,则用getNumericCellValue()获取单元格内容

    String cellData =cell.getStringCellValue();returncellData;

    }catch(Exception e) {return "";

    }

    }//在EXCEL的执行单元格中写入数据(此方法只针对.xlsx后辍的Excel文件) rowNum 行号,colNum 列号

    public static void setCellData(int rowNum,int colNum,String Result) throwsException{try{//获取行对象

    row =excelWSheet.getRow(rowNum);//如果单元格为空,则返回null

    cell =row.getCell(colNum);if(cell == null){

    cell=row.createCell(colNum);

    cell.setCellValue(Result);

    }else{

    cell.setCellValue(Result);

    }

    FileOutputStream out= newFileOutputStream(Constant.TestDataExcelFilePath);//将内容写入excel中

    excelWBook.write(out);

    out.flush();

    out.close();

    }catch(Exception e) {

    e.printStackTrace();

    }

    }//从EXCEL文件中获取测试数据

    public static Object[][] getTestData(String excelFilePath,String sheetName) throwsIOException{//声明一个file文件对象

    File file = newFile(excelFilePath);//创建一个输入流

    FileInputStream in = newFileInputStream(file);//声明workbook对象

    Workbook workbook = null;//判断文件扩展名

    String fileExtensionName = excelFilePath.substring(excelFilePath.indexOf("."));if(fileExtensionName.equals(".xlsx")){

    workbook= newXSSFWorkbook(in);

    }else{

    workbook= newHSSFWorkbook(in);

    }//获取sheet对象

    Sheet sheet =workbook.getSheet(sheetName);//获取sheet中数据的行数,行号从0始

    int rowCount = sheet.getLastRowNum()-sheet.getFirstRowNum();

    List records = new ArrayList();//读取数据(省略第一行表头)

    for(int i=1; i

    Row row =sheet.getRow(i);//声明一个数组存每行的测试数据,excel最后两列不需传值

    String[] fields = new String[row.getLastCellNum()-2];//excel倒数第二列为Y,表示数据行要被测试脚本执行,否则不执行

    if(row.getCell(row.getLastCellNum()-2).getStringCellValue().equals("y")){for(int j=0; j

    fields[j] = row.getCell(j).getCellTypeEnum() == CellType.STRING ? row.getCell(j).getStringCellValue() : ""+row.getCell(j).getNumericCellValue();//使用下面这行代码会报错不知怎么解决,如果哪位知道解决方法求告知//fields[j] = row.getCell(j).getCellType() == CellType.STRING ? row.getCell(j).getStringCellValue() : ""+row.getCell(j).getNumericCellValue();

    }

    records.add(fields);

    }

    }//将list转为Object二维数据

    Object[][] results = newObject[records.size()][];//设置二维数据每行的值,每行是一个object对象

    for(int i=0; i

    results[i]=records.get(i);

    }returnresults;

    }public static intgetLastColumnNum(){//返回数据文件最后一列的列号,如果有12列则返回11

    return excelWSheet.getRow(0).getLastCellNum()-1;

    }

    }

    四、封装显示等待方法(因为有些地方需要用到就做了个简单的封装)。在cn.util包下新建WaitMethod类,代码如下:

    packagecn.util;importorg.openqa.selenium.By;importorg.openqa.selenium.NoSuchElementException;importorg.openqa.selenium.WebDriver;importorg.openqa.selenium.support.ui.ExpectedConditions;importorg.openqa.selenium.support.ui.WebDriverWait;//显示等待封装方法

    public classWaitMethod {public static void xsWait(WebDriver driver,By by,inttime){try{

    WebDriverWait wait=newWebDriverWait(driver,time);

    wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(by));

    }catch(NoSuchElementException e){

    log.info("等待:"+time+"秒没有找到 "+ by +" 元素");

    Screenshot.method(driver,"显示等待"+by+"元素"+time+"秒超时");

    log.info("调用Screenshot.method方法截图");

    }

    }

    }

    在cn.pageObjects包下新建WaitByElement类,代码如下:(因为上面所写的显示等待方法需要传入By类型的参数,这里为了方便就另写了显示等待需要传入的几个By类型元素)

    packagecn.pageObjects;importorg.openqa.selenium.By;public classWaitByElement {//登录界面的frame

    public static By loginFrame=By.xpath("//*[@id='loginDiv']/iframe[@frameborder='0']");//首页未读邮件按钮

    public static By weiduButton=By.id("_mail_tabitem_0_3text");//通讯录页面的 新建联系人按钮

    public static By addLinMan=By.xpath("//span[text()='新建联系人']");//新建联系人界面的 确定按钮

    public static By confirmButton=By.xpath("//div[@role='button']/span[text()='确 定']");

    }

    五、定位元素,这里使用UI Map定位元素,目的是能够使用配置文件存储被测页面上元素的定位方式和定位表达式,做到定位数据和程序的分离。

    在cn.util包下新建ObjectMap工具类,读取objectMap.properties文件中配置页面元素的定位表达式。代码如下:

    packagecn.util;importjava.io.FileInputStream;importjava.io.IOException;importjava.util.Properties;importorg.openqa.selenium.By;public classObjectMap {

    Properties properties;publicObjectMap(String propFile){

    properties=newProperties();try{

    FileInputStream in=newFileInputStream(propFile);

    properties.load(in);

    in.close();

    }catch(IOException e){

    log.info("读取文件对象出错");

    e.printStackTrace();

    }

    }public By getLocator(String ElenmentNameInpropFile) throwsException{//根据变量ElenmentNameInpropFile,从属性配置文件中读取对应的配置对象

    String locator=properties.getProperty(ElenmentNameInpropFile);//将配置对象中定位类型存储到locatorType变量,将定位表达式的值存储到locatorValue变量

    String locatorType=locator.split(">")[0];

    String locatorValue=locator.split(">")[1];//在Eclipse中的配置文件均默认为ISO-8859-1编码存储,使用getBytes方法可以将字符//转换为UTF-8编码,以此解决在配置文件中读取中文乱码的问题

    locatorValue=new String(locatorValue.getBytes("ISO-8859-1"),"UTF-8");//输出locatorType变量值和locatorValue变量值,验证赋值是否正确

    log.info("获取的定位类型为:"+locatorType+"\t定位表达式为:"+locatorValue);//根据locatorType的变量值内容判断返回何种定位方式的By对象

    if(locatorType.toLowerCase().equals("id"))returnBy.id(locatorValue);else if(locatorType.toLowerCase().equals("name"))returnBy.name(locatorValue);else if((locatorType.toLowerCase().equals("classname"))||(locatorType.

    toLowerCase().equals("class")))returnBy.className(locatorValue);else if((locatorType.toLowerCase().equals("tagname"))||(locatorType.

    toLowerCase().equals("tag")))returnBy.tagName(locatorValue);else if((locatorType.toLowerCase().equals("linktext"))||(locatorType.

    toLowerCase().equals("link")))returnBy.linkText(locatorValue);else if(locatorType.toLowerCase().equals("partiallinktext"))returnBy.partialLinkText(locatorValue);else if((locatorType.toLowerCase().equals("cssselector"))||(locatorType.

    toLowerCase().equals("css")))returnBy.cssSelector(locatorValue);else if(locatorType.toLowerCase().equals("xpath"))returnBy.xpath(locatorValue);elselog.info("输入的locator type未在程序中被定义:"+locatorType);throw new Exception("输入的locator type未在程序中被定义:"+locatorType);

    }

    }

    然后在新建的objectMap.properties文件中添加所需的元素定位方式和定位表达式,内容如下:

    #登录页面

    loginpage.intologin=id>lbNormal

    loginpage.loginframe=xpath>//*[@id='loginDiv']/iframe[@frameborder='0']

    loginpage.username=name>email

    loginpage.password=name>password

    loginpage.loginbutton=id>dologin

    #首页

    homepage.shouyetext=id>_mail_tabitem_0_3text

    homepage.addressbook=id>_mail_tabitem_1_4text

    #通讯录页面

    addressbookpage.addlinkman=xpath>//span[text()='新建联系人']

    #新建联系人页面

    addressbookpage.name=id>input_N

    addressbookpage.email=xpath>//div[@id='iaddress_MAIL_wrap']/dl/dd/div/input

    addressbookpage.phonenumber=xpath>//div[@id='iaddress_TEL_wrap']/dl/dd/div/input

    addressbookpage.confirmbutton=xpath>//div[@role='button']/span[text()='确 定']

    最后实现各个页面元素的定位。在cn.pageObject包下新建LoginPage类实现登录页面各个元素的定位,代码如下:

    packagecn.pageObjects;importorg.openqa.selenium.WebDriver;importorg.openqa.selenium.WebElement;importcn.util.ObjectMap;public classLoginPage {//指定页面元素定位表达式配置文件的绝对路径

    private ObjectMap objectMap=new ObjectMap("F:\\Eclipse\\DataFrameWork\\objectMap.properties");privateWebElement element;privateWebDriver driver;publicLoginPage(WebDriver driver){this.driver=driver;

    }//返回进入密码登录页面元素对象

    public WebElement intoLogin() throwsException{//使用objectMap类中的getLocator方法获取配置文件中关于用户名的定位方式和定位表达式

    element=driver.findElement(objectMap.getLocator("loginpage.intologin"));returnelement;

    }//返回登录页面的frame元素对象

    public WebElement loginFrame() throwsException{//使用objectMap类中的getLocator方法获取配置文件中关于用户名的定位方式和定位表达式

    element=driver.findElement(objectMap.getLocator("loginpage.loginframe"));returnelement;

    }//返回登录页面用户名输入框元素对象

    public WebElement userName() throwsException{//使用objectMap类中的getLocator方法获取配置文件中关于用户名的定位方式和定位表达式

    element=driver.findElement(objectMap.getLocator("loginpage.username"));returnelement;

    }//返回登录页面密码输入框元素对象

    public WebElement passWord() throwsException{//使用objectMap类中的getLocator方法获取配置文件中关于用户名的定位方式和定位表达式

    element=driver.findElement(objectMap.getLocator("loginpage.password"));returnelement;

    }//返回登录页面登录按钮元素对象

    public WebElement loginButton() throwsException{//使用objectMap类中的getLocator方法获取配置文件中关于用户名的定位方式和定位表达式

    element=driver.findElement(objectMap.getLocator("loginpage.loginbutton"));returnelement;

    }

    }

    在cn.pageObject包下新建HomePage类实现首页各个元素的定位,代码如下:

    packagecn.pageObjects;importorg.openqa.selenium.WebDriver;importorg.openqa.selenium.WebElement;importcn.util.ObjectMap;public classHomePage {//指定页面元素定位表达式配置文件的绝对路径

    private ObjectMap objectMap=new ObjectMap("F:\\Eclipse\\DataFrameWork\\objectMap.properties");privateWebElement element;privateWebDriver driver;publicHomePage(WebDriver driver){this.driver=driver;

    }//返回 首页 元素对象

    public WebElement shouyeText() throwsException{//使用objectMap类中的getLocator方法获取配置文件中关于用户名的定位方式和定位表达式

    element=driver.findElement(objectMap.getLocator("homepage.shouyetext"));returnelement;

    }//返回 通讯录 元素对象

    public WebElement tongxunId() throwsException{

    element=driver.findElement(objectMap.getLocator("homepage.addressbook"));returnelement;

    }

    }

    在cn.pageObject包下新建LinkmanPage类实现通讯录页面各个元素的定位,代码如下:

    packagecn.pageObjects;importorg.openqa.selenium.WebDriver;importorg.openqa.selenium.WebElement;importcn.util.ObjectMap;public classLinkmanPage {privateWebElement element;privateWebDriver driver;//指定元素定位表达式配置文件的绝对路径

    private ObjectMap objectMap=new ObjectMap("F:\\Eclipse\\DataFrameWork\\objectMap.properties");publicLinkmanPage(WebDriver driver){this.driver=driver;

    }//返回通讯录页面中的 新建联系人 元素

    public WebElement addressBook() throwsException{

    element=driver.findElement(objectMap.getLocator("addressbookpage.addlinkman"));returnelement;

    }

    }

    在cn.pageObject包下新建AddressBookPage类实现建联系人界面各个元素的定位,代码如下:

    packagecn.pageObjects;importorg.openqa.selenium.WebDriver;importorg.openqa.selenium.WebElement;importcn.util.ObjectMap;public classAddressBookPage {privateWebElement element;privateWebDriver driver;//指定定位元素表达式配置文件的绝对路径

    private ObjectMap objectMap=new ObjectMap("F:\\Eclipse\\DataFrameWork\\objectMap.properties");publicAddressBookPage(WebDriver driver){this.driver=driver;

    }//返回新建联系人界面的 姓名输入框

    public WebElement inputName() throwsException{

    element=driver.findElement(objectMap.getLocator("addressbookpage.name"));returnelement;

    }//返回新建联系人界面的 电子邮箱输入框

    public WebElement inputEmail() throwsException{

    element=driver.findElement(objectMap.getLocator("addressbookpage.email"));returnelement;

    }//返回新建联系人界面的 手机号码输入框

    public WebElement inputPhonenumber() throwsException{

    element=driver.findElement(objectMap.getLocator("addressbookpage.phonenumber"));returnelement;

    }//返回新建联系人界面的 确定按钮

    public WebElement inputConfirmbutton() throwsException{

    element=driver.findElement(objectMap.getLocator("addressbookpage.confirmbutton"));returnelement;

    }

    }

    六、封装登录和新建联系人方法

    在cn.appModules包下新建LoginAction类,实现登录操作的封装方法

    packagecn.appModules;//封装登录操作

    importorg.openqa.selenium.WebDriver;importcn.pageObjects.LoginPage;importcn.pageObjects.WaitByElement;importcn.util.WaitMethod;importcn.util.log;public classLoginAction {public static voidexecute(WebDriver driver,String userName,String passWord)throwsException{

    log.info("浏览器最大化");//浏览器最大化

    driver.manage().window().maximize();

    log.info("实例化LoginPage对象");//实例化LoginPage对象

    LoginPage login=newLoginPage(driver);

    log.info("点击进入密码登录按钮");//点击进入密码登录按钮

    login.intoLogin().click();

    log.info("显示等待"+WaitByElement.loginFrame+" 元素5秒");//显示等待

    WaitMethod.xsWait(driver,WaitByElement.loginFrame,5);

    log.info("进入登录界面的frame");//控制权交给登录界面的frame

    driver.switchTo().frame(login.loginFrame());

    log.info("输入用户名"+userName);//输入用户名

    login.userName().sendKeys(userName);

    log.info("输入密码"+passWord);//输入密码

    login.passWord().sendKeys(passWord);

    log.info("点击登录按钮");//点击登录按钮

    login.loginButton().click();//Thread.sleep(5000);

    }

    }

    在cn.appModules包下新建AddContactPersonAction类,实现新建联系人操作的封装方法。代码如下:

    packagecn.appModules;importorg.openqa.selenium.WebDriver;importcn.pageObjects.AddressBookPage;importcn.pageObjects.HomePage;importcn.pageObjects.LinkmanPage;importcn.pageObjects.WaitByElement;importcn.util.Screenshot;importcn.util.WaitMethod;importcn.util.log;public classAddContactPersonAction {//新建联系人封装方法

    public static voidexecute(WebDriver driver,String userName,String passWord,

    String Name,String Email,String Phonenumber)throwsException {

    log.info("调用登录封装方法");//调用登录封装方法

    try{

    LoginAction.execute(driver,userName, passWord);

    }catch(Exception e) {

    log.info("登录进入163邮箱首页失败");

    Screenshot.method(driver,"登录进入163邮箱首页失败");

    }

    log.info("显示等待"+WaitByElement.weiduButton+" 元素");//显示等待

    WaitMethod.xsWait(driver,WaitByElement.weiduButton,10);

    log.info("实例化HomePage对象");//实例化HomePage对象

    HomePage homePage=newHomePage(driver);

    log.info("点击 通讯录");//点击 通讯录

    homePage.tongxunId().click();

    log.info("显示等待"+WaitByElement.addLinMan+" 元素");//显示等待

    WaitMethod.xsWait(driver, WaitByElement.addLinMan, 5);

    log.info("实例化LinkmanPage对象");//实例化LinkmanPage对象

    LinkmanPage linkmanPage=newLinkmanPage(driver);

    log.info("点击 新建联系人");//点击 新建联系人

    linkmanPage.addressBook().click();

    log.info("显示等待"+ WaitByElement.confirmButton+" 元素");//显示等待

    WaitMethod.xsWait(driver, WaitByElement.confirmButton, 5);

    log.info("实例化AddressBookPage");//实例化AddressBookPage

    AddressBookPage addressbookPage=newAddressBookPage(driver);

    log.info("输入联系人姓名:"+Name);//输入联系人姓名

    addressbookPage.inputName().sendKeys(Name);

    log.info("输入联系人电子邮箱:"+Email);//输入联系人电子邮箱

    addressbookPage.inputEmail().sendKeys(Email);

    log.info("输入联系人手机号码:"+Phonenumber);//输入联系人手机号码

    addressbookPage.inputPhonenumber().sendKeys(Phonenumber);

    log.info("点击新建联系人界面的 确定按钮");//点击新建联系人界面的 确定按钮

    addressbookPage.inputConfirmbutton().click();

    }

    }

    七、建立常量类和Excel表格数据

    在cn.util包下新建Constant类,代码如下:

    packagecn.util;//定义常量

    public classConstant {//定义测试网址

    public static final String url="https://mail.163.com/";//定义Excel测试数据文件的路径

    public static final String TestDataExcelFilePath="E:\\Datas\\data.xlsx";//定义在Excel 文件中包含测试数据的Sheet名称

    public static final String TestDataExcelFileSheet="Sheet1";

    }

    新建一个Excel表,命名为:data.xlsx ,数据入下图所示:

    1a164b033d556a72f3dc2cc560e4aa8b.png

    用户名、密码根据实际情况填写。注意:手机号这种超长数字类的单元格要设置成文本类型(单元格左上角有个绿三角)

    八、测试类。

    在cn.testCase包下新建TestEmail163addContactPerson类。代码如下:

    packagecn.testCase;importjava.io.IOException;importorg.apache.log4j.xml.DOMConfigurator;importorg.openqa.selenium.WebDriver;importorg.openqa.selenium.chrome.ChromeDriver;importorg.testng.Assert;importorg.testng.annotations.AfterMethod;importorg.testng.annotations.BeforeClass;importorg.testng.annotations.BeforeMethod;importorg.testng.annotations.DataProvider;importorg.testng.annotations.Test;importcn.appModules.AddContactPersonAction;importcn.util.Constant;importcn.util.ExcelUtil;importcn.util.Screenshot;importcn.util.log;public classTestEmail163addContactPerson {publicWebDriver driver;

    String url=Constant.url;//定义dataprovider,并命名为testData

    @DataProvider(name="testData")public static Object[][] data() throwsIOException{/**调用ExcelUtil类中的getTestData静态方法,获取Excel数据文件中倒数第二列

    *标记为y的测试数据行,函数参数为常量Constant.TestDataExcelFilePath和常量

    *Constant.TestDataExcelFileSheet,指定数据文件的路径和Sheet名称*/

    //System.out.println(Constant.TestDataExcelFilePath);//System.out.println(Constant.TestDataExcelFileSheet);

    log.info("调用ExcelUtil类中的getTestData静态方法获取Excel中标记为y的测试数据");returnExcelUtil.getTestData(Constant.TestDataExcelFilePath,Constant.TestDataExcelFileSheet);

    }//使用名称为testData的dataProvider作为测试方法的测试数据集//测试方法一个使用了10个参数,对应到Excel数据文件的1~10列

    @Test(dataProvider="testData")public voidtestAddContactPerson(String CaseRow,String CaseName,String UserName,

    String PassWord,String Name,String Email,String PhoneNumber,

    String AssertName,String AssertEmail,String AssertPhoneNumber)throwsException{

    log.startTestCase(CaseName);

    driver.get(url);

    log.info("访问网页"+url);try{

    log.info("调用AddContactPersonAction类的execute方法");//调用新建联系人封装方法,并传入相应参数

    AddContactPersonAction.execute(driver,UserName, PassWord,Name, Email,PhoneNumber);

    }catch(Exception e) {/** 执行AddContactPersonAction类的execute方法失败时,catch语句可以捕获AssertionError类型

    * 的异常,并设置Excel中测试数据行的执行结果为“测试失败”。由于Excel中的序号格式被默认设定

    * 为带有一位小数点,所以使用 split("[.]"[0]) 语句获取序号的整数部分,并传给setCellData函

    * 数在对应序号的测试数据行的最后一列设定“测试失败”*/ExcelUtil.setCellData(Integer.parseInt(CaseRow.split("[.]")[0]),

    ExcelUtil.getLastColumnNum(),"测试失败");

    log.info("添加联系人失败");

    Screenshot.method(driver,"添加联系人失败");

    log.info("调用Screenshot.method方法进行截图");

    log.endTestCase(CaseName);//调用Assert.fail方法将此测试用例设定为执行失败,后续测试代码将不被执行

    Assert.fail("执行AddContactPersonAction类的execute方法失败");

    }

    Thread.sleep(3000);

    log.info("调用AddContactPersonAction类的execute方法后休眠3秒");try{

    log.info("断言页面是否包含联系人姓名:"+AssertName);//断言页面是否包含AssertName变量的关键字

    Assert.assertTrue(driver.getPageSource().contains(AssertName));

    }catch(AssertionError error){

    log.info("断言通讯录页面是否包含联系人姓名:"+AssertName +" 失败");

    ExcelUtil.setCellData(Integer.parseInt(CaseRow.split("[.]")[0]),

    ExcelUtil.getLastColumnNum(),"测试失败");

    Screenshot.method(driver,"断言联系人姓名为"+AssertName+"失败");

    log.info("调用Screenshot.method方法进行截图");

    log.endTestCase(CaseName);

    Assert.fail("断言通讯录页面是否包含联系人姓名的关键字失败");

    }try{

    log.info("断言页面是否包含联系人邮箱:"+AssertEmail);//断言页面是否包含AssertEmail变量的关键字

    Assert.assertTrue(driver.getPageSource().contains(AssertEmail));

    }catch(AssertionError error){

    log.info("断言通讯录页面是否包含联系人邮箱地址:"+AssertEmail+" 失败");

    ExcelUtil.setCellData(Integer.parseInt(CaseRow.split("[.]")[0]),

    ExcelUtil.getLastColumnNum(),"测试失败");

    log.info("调用Screenshot.method方法进行截图");

    Screenshot.method(driver,"断言联系人邮箱为"+AssertEmail+"失败");

    log.endTestCase(CaseName);

    Assert.fail("断言通讯录页面是否包含联系人邮箱地址的关键字失败");

    }try{

    log.info("断言通讯录页面是否包含联系人手机号码:"+AssertPhoneNumber);//断言页面是否包含AssertPhoneNumber变量的关键字

    Assert.assertTrue(driver.getPageSource().contains(AssertPhoneNumber));

    }catch(AssertionError error){

    ExcelUtil.setCellData(Integer.parseInt(CaseRow.split("[.]")[0]),

    ExcelUtil.getLastColumnNum(),"测试失败");

    log.info("断言通讯录页面是否包含联系人手机号码:"+AssertPhoneNumber+" 失败");

    Screenshot.method(driver,"断言联系人手机号码为"+AssertPhoneNumber+"失败");

    log.info("调用Screenshot.method方法进行截图");

    log.endTestCase(CaseName);

    Assert.fail("断言通讯录页面是否包含联系人手机号码关键字失败");

    }

    ExcelUtil.setCellData(Integer.parseInt(CaseRow.split("[.]")[0]),

    ExcelUtil.getLastColumnNum(),"测试成功");

    log.info("新建联系人全部断言成功,在Excel的测试数据文件“测试执行结果”列中写入“测试成功”");

    log.endTestCase(CaseName);

    }

    @BeforeClasspublic void beforeClass() throwsException{//读取Log4j.xml配置文件信息

    DOMConfigurator.configure("Log4j.xml");//使用Constant类中的常量,设定测试数据的文件路径和Sheet名称

    ExcelUtil.setExcelFile(Constant.TestDataExcelFilePath,Constant.TestDataExcelFileSheet);

    log.info("使用Constant类中的常量,设定测试数据的文件路径:"+Constant.TestDataExcelFilePath);

    log.info("使用Constant类中的常量,设定测试数据的Sheet名称:"+Constant.TestDataExcelFileSheet);

    }

    @BeforeMethodpublic voidbeforeMethod(){

    System.setProperty("webdriver.chrome.driver","E://chromedriver.exe");

    driver=newChromeDriver();

    log.info("启动浏览器");

    }

    @AfterMethodpublic voidafterMethod(){

    driver.quit();

    log.info("关闭浏览器");

    }

    }

    运行TestEmail163addContactPerson测试类后,结果如下几图所示:

    testng运行结果:

    a0560cd149476e91c46a79e6450f3cbb.png

    log4j打印日志:

    76d143eebd67d9fc76bafbf224c107c5.png

    错误截图:

    900a2da849b01f195d5b89d43c0ef331.png

    Excel表格用例执行结果列自动写入结果:

    22d768b8869001d57cd34394045d5cf7.png

    如果有错误或不足之处,欢迎指正(^∀^)

    展开全文
  • JAVA 实现 QQ 邮箱发送验证码功能(不局限于框架)本来想实现 QQ 登录,有域名一直没用过,还得备案,好麻烦,只能过几天再更新啦。先把实现的发送邮箱验证码更能更新了。老规矩,更多内容在注释山聊。首先还是先放上...

    JAVA 实现 QQ 邮箱发送验证码功能(不局限于框架)

    本来想实现 QQ 登录,有域名一直没用过,还得备案,好麻烦,只能过几天再更新啦。

    先把实现的发送邮箱验证码更能更新了。

    老规矩,更多内容在注释山聊。

    首先还是先放上成功的截图:

    7b904876e7135693596fcf09243d4cce.png

    (1)准备阶段 - 获取授权码

    授权码(这个授权码是让 JAVA 程序来登录发送者的 QQ 邮箱的,相当于登动态密码)

    获取步骤:

    点击【设置】>【账户】>【POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务】

    efde31fc71d4f5d736342bb37ec6f77f.png

    (2)加载相关 jar 包

    使用 Maven 的话,直接拷贝下面的就可以:

    javax.activation

    activation

    1.1.1

    javax.mail

    mail

    1.4.7

    org.apache.commons

    commons-email

    1.5

    (3)代码编写 - 示例

    请根据提示自行修改配置

    package com.xpwi.action;

    import org.apache.commons.mail.SimpleEmail;

    import org.springframework.context.annotation.Scope;

    import org.springframework.stereotype.Controller;

    import org.springframework.web.bind.annotation.RequestMapping;

    import org.springframework.web.bind.annotation.ResponseBody;

    @Controller

    @Scope("prototype")

    @RequestMapping("/email")

    public class EmailValidateAction {

    //邮箱验证

    //*.do 的格式是 Spring MVC 拦截的一种配置,请自行修改

    @RequestMapping("/sendCode.do")

    @ResponseBody

    public int emailValidate(){

    SimpleEmail email=new SimpleEmail();//创建一个HtmlEmail实例对象

    try {

    //填写邮箱服务器,如是QQ邮箱服务器,直接用:smtp.qq.com

    email.setHostName("邮箱服务器");

    email.setCharset("utf-8");

    //设置收件人

    email.addTo("收件人邮箱地址");

    //设置发送人邮箱,和用户名

    email.setFrom("发件人邮箱地址","发件人署名(随意写)");

    //配置邮箱加授权码,相当于等于自己的邮箱

    email.setAuthentication("发送者的邮箱","发送者的授权码");

    //使用安全链接

    email.setSSLOnConnect(true);

    //设置邮件的主题

    email.setSubject("注册验证码");

    //设置邮件的内容,自行修改动态验证码

    email.setMsg("尊敬的用户:你好!\n 注册验证码为:123444" +"\n"+" (有效期为一分钟)");

    //发送

    email.send();

    }catch (Exception e){

    e.printStackTrace();

    //返回 0 表示失败

    return 0;

    }

    //返回 1 表示发送成功

    return 1;

    }

    }

    更多文章链接

    展开全文
  • JAVA 实现 QQ 邮箱发送验证码功能(不局限于框架) 本来想实现 QQ 登录,有域名一直没用过,还得备案,好麻烦,只能过几天再更新啦。 先把实现的发送邮箱验证码更能更新了。 老规矩,更多内容在注释山聊。 首先还是...
  • Java SSM框架 Spring入门及IOC详解 版权声明:本文为博主原创文章,未经博主允许不得转载。 转载联系邮箱:1363119685@qq.com Copyright © 2018 DAR林克斯 保留所有权利 Java SSM框架 Spring入门及IOC 一、Spring...
  • Java邮箱注册

    2018-09-04 17:38:18
    该项目使用的是SSM框架,由于是单表查询,业务逻辑比较简单,因此只配上Controller层
  • 用法查看 https://blog.csdn.net/qq_32371887/article/details/72821291 注意配置的邮箱不要被标记为垃圾邮件
  • Java SSM框架 Spring的AOP编程 版权声明:本文为博主原创文章,未经博主允许不得转载。 转载联系邮箱:1363119685@qq.com Copyright © 2018 DAR林克斯 保留所有权利 一、AOP编程的概念: AOP:Aspect Oriented ...
  • 本文是根据吴晓华编著的《Selenium WebDriver 实战宝典》的16.3节:...关键字驱动的实现原理就是利用了java的反射机制P.S如果我写的不太清楚,建议购买吴晓华编著的《Selenium WebDriver 实战宝典》一书step1:创...
  • Jeecg-P3是一个微服务框架,采用插件式模式开发;业务插件以JAR方式提供,松耦合可插拔支持独立部署,也可无缝集成Jeecg平台中,目前jeecg已经提供了在线聊天,我的邮箱等一系列插件。
  • 邮箱 银行卡号 密码 持久化加密 存储的时候上面的信息都需要加密,密码为不可逆加密,其他为可逆加密。 类似的功能有很多。不在本系统的解决范围内。 特性 基于注解的日志脱敏。 可以自定义策略实现,策略有效条件。...
  • JAVA微服务框架,Jeecg-P3-Biz-OA 1.0.0 插件开源发布 OA办公插件,采用JEECG-P3微服务框架技术,实现OA办公基本功能,H5页面素材:相册管理、联系人、联系人详细、报表、打印、订单报表、邮件内容、邮箱、留言墙...
  • 最近做毕业设计——oa系统,在邮箱这块用到了附件上传。在度娘找了好多jquery的控件,最终选择了uploadify。首先去官网下载uploadify ——http://www.uploadify.com/(选择falsh版本,html5是付费服务).解压后可以...
  • 下面我就教大家如何使用java邮箱发送验证码。 1、首先需要mailUtils工具类 该工具类主要用来封装发送邮箱信息参数 2、EmailService类 3、EmailServiceImpl实现类 生成五位随机数,网上的方法有很多大家可以自己...
  • 很显然,这个项目有点小题大做了,jaev 是一个用来验证电子邮箱地址是否有效的 Java 项目。不过它并不是这么简单,可以跟很多框架进行集成。 示例代码: ValidatorFactoryBuilder builder = Validation.basic();...
  • Aperture是一个Java框架,用于从各种信息系统(文件系统,网站,邮箱等)和这些系统中出现的文件格式(文档,图像等)中提取和查询全文内容和元数据。
  • Java SSH邮箱系统

    2010-05-06 22:37:18
    java SSH框架做的一人邮箱系统,代码完整!内有数据库文件。下次我免费上传上来
  • 规则文件的书写风格总得来说,XWork发布了两种类型的验证器,包括我们自定义的。 Plain Validators / Non-Field validators FieldValidators 平滑的... 属性验证器(比如邮箱验证器)是基于某个特定属性的,它们需要...
  • 最近做毕业设计——oa系统,在邮箱这块用到了附件上传。在度娘找了好多jquery的控件,最终选择了uploadify。 首先去官网下载uploadify ——http://www.uploadify.com/(选择falsh版本,html5是付费服务). 解压后...
  • Java三大主流框架概述

    2019-10-01 18:29:11
    Java三大主流框架概述 邮箱:1727292697@qq.com Struts、Hibernate和Spring是我们Java开发中的常用关键,他们分别针对不同的应用场景给出最合适的解决方案。但你是否知道,这些知名框架最初是怎样产生的?我们知道...
  • 开启邮箱终端授权码 添加依赖 <dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version>${mail.version}</version> </...
  • 学习是一个漫长而又反复的过程,经常会使人动摇放弃,java的学习更是如此。也正因为如此,才会使得java更加珍贵。...我们常用的web框架强调的是各种关注点分离,所以才有了MVC的结构思想。同样地...
  • 二,@AssertURL会验证连接的有效性,但不会验证是否是null.@Email验证邮箱地址有效性,但不会验证是否为null。以上需要配合@NotNull使用。 三,@CheckWith(value=CheckAge.class,message="age mus...
  • 注册,登陆,实现发送邮箱验证信息,保证安全,SSM框架整合

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 415
精华内容 166
关键字:

java邮箱框架

java 订阅