实现图片验证码与手机短信验证码

2023-11-12

实现图片验证码与手机短信验证码:

 

1、HTML 代码:


<!-- 和验证码一样大小的提示图片:"请输入手机号" -->
    <input type="hidden" value="${@cn.mycs.core.util.ToolUtil.url(@cn.mycs.core.constant.CommonConstant.DOMAINS_STATIC)}/2.0.0/images/safeCode.jpg" id="tipImageUrl">
<div class="form-group">
                            <label for="" class="control-label col-sm-3">联系人手机:</label>
                            <div class="col-sm-9">
                                <input maxlength="11" name="phone" placeholder="负责人手机" data="手机号码" warn="请输入11位数的手机号!" data-options="required:true" type="text" class="form-control easyui-validatebox" id="phone2">
                                <span class="reg_warn" style="color: red;"></span>
                            </div>
                        </div>
                        <div class="form-group">
                            <label for="" class="control-label col-sm-3">验证码:</label>
                            <div class="col-sm-9">
                                <div class="row">
                                    <div class="col-sm-4">
                                        <input name="safeCode" id="safeCode2"  maxlength="4"  data="验证码" warn="4位字符的验证码!" type="text" data-options="required:true,tipPosition:'left'" class="form-control easyui-validatebox">
                                    </div>
                                    <div class="col-sm-4">
                                        <img class="validate-img"  src="${@cn.mycs.core.util.ToolUtil.url(@cn.mycs.core.constant.CommonConstant.DOMAINS_STATIC)}/2.0.0/images/safeCode.jpg" id="validate-img2" />
                                    </div>
                                </div>
                            </div>
                        </div>
                        <div class="form-group">
                            <label for="" class="control-label col-sm-3">短信验证码:</label>
                            <div class="col-sm-9">
                                <div class="row">
                                    <div class="col-sm-4">
                                        <input name="smsCodeM" maxlength="6"  placeholder="6位验证码" data="手机验证码"   warn="请输入手机验证码!"  type="text" class="form-control  easyui-validatebox" />
                                        <span class="reg_warn" style="color: red;"></span>
                                    </div>
                                    <div class="col-sm-8">
                                        <button type="button" class="btn btn-primary" id="big_gray_btn2">发送验证码</button>
                                    </div>
                                </div>
                            </div>
                        </div>

2、js代码:

//手机号输入事件
    $("input[name='phone']").keyup(function () {
        var _this = $(this), v = _this.val(), obj_safeCode = _this.parent().parent().next("div").find(".validate-img");
        if (_this.data("v") != v) {
            _this.data("v", v);
            /^1\d{10}$/.test(v) ? obj_safeCode.trigger("click") : obj_safeCode.attr("src", $("#tipImageUrl").val());
        }
    });
    //验证码点击事件
    $("#validate-img1").click(function () {
        var error = $(".reg_error");
        for (var i = 0; i < error.length; i++) {
            if (error.eq(0 + "").html()=="该手机号已被绑定") {
                return;
            }
        }
        var v = $("#phone1").val();
        $(this).parent().prev("div").find("input[name='safeCode']").val("");
        /^1\d{10}$/.test(v) && $(this).attr("src", _ctx + "/validateCode?refresh=" + Math.random());
    });

//发送(手机|邮箱)验证码
    $("#big_gray_btn1").click(function () {
        var error = $(".reg_error");
        for (var i = 0; i < error.length; i++) {
            if (error.eq(0 + "").html()=="该手机号已被绑定") {
                alert("该手机号已被绑定","error");
                return;
            }
        }
        var _this = $(this), txt = _this.text(), div = _this.closest("div");
        if (txt == "发送验证码") {
            var tel_input = $("#phone1");
            var safeCode = $("#safeCode1").val();
            var tel_mess = tel_input.parent().nextAll("span").text();
            var tel = tel_input.val();
            if (tel_mess == "该号码已被绑定") {
                alert("请重新输入手机号码", "error");
            } else if (!/^[a-zA-Z0-9]{4}$/.test(safeCode)) {
                alert("请先输入正确的验证码!", "error");
            } else if (/^1\d{10}$/.test(tel)) {
                _this.text("请稍候……");
                _this.nextAll("span").hide();
                $.getJSON(_ctx + "/app/mobileSms?action=send&captchaCode=" + safeCode + "&phone=" + tel + "&" + Math.random(), function (json) {
                    _this.text(txt);
                    if (1 != json.code) {
                        alert(json.message, "error");
                        if (json.message == "图形验证码错误") {
                            $("#validate-img1").click();
                        }
                    } else {
                        setT(_this, 180, txt);
                        div.nextAll("span").text("此手机验证码30分钟内有效").attr({"class": "reg_warn"}).show();
                    }
                });
            } else {
                div.css("border-color", "#dedede").nextAll("span").text("请先输入正确的手机号!").attr({"class": "reg_warn"});
                tel_input.focus().parent().css("border-color", "#f77979").nextAll("span").attr("class", "reg_error");
            }
        }
    });

3、发送短信 控制器 Controller:

package cn.wpg.client.web.controller.persional;

import cn.wpg.core.base.restful.JsonResult;
import cn.wpg.core.constant.MobileProperties;
import cn.wpg.core.support.StrKit;
import cn.wpg.core.util.MobileSmsUtil;
import cn.wpg.server.persistence.redis.RedisService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.Random;


/**
 * <p>发送短信 控制器 Controller</p>
 * <pre>
 * @author Wupeiguo
 * @date 2019/06/14 11:42
 * </pre>
 */
@Controller
public class MobileSmsController {
    private final Logger log = LoggerFactory.getLogger(getClass());
    @Autowired
    private RedisService redisService;

    @RequestMapping("/app/mobileSms")
    @ResponseBody
    public JsonResult mobileSms(String action, String captchaCode, String phone, HttpServletRequest request) {
        if (StrKit.isEmpty(action) || StrKit.isEmpty(phone)) {
            log.debug("参数错误");

            return JsonResult.error("参数错误");
        }

        //获取redis 图形验证码做校验
        String code = redisService.get("cookiesReplyKey", 8, String.class);
        if (StrKit.isEmpty(code)) {
            log.debug("请重新获取图形验证码");
            return JsonResult.error("请重新获取图形验证码");
        } else if (!code.equalsIgnoreCase(captchaCode)) {
            log.debug("图形验证码错误");
            return JsonResult.error("图形验证码错误");
        } else if ("sendCode".equals(action)) {
            return sendCode(phone);
        }
        return JsonResult.success("发送成功");
    }

    private JsonResult sendCode(String phone) {
        log.debug("发送手机验证码");
        String key = "smsCode_" + phone;
        Object redisCode = redisService.get(key, Object.class);
        if (redisCode != null) {
            log.info("稍后再试");
            return JsonResult.error("稍后再试");
        }
        //生成随机号码
        final String smsCode = getRandomCode();
        //发送短信验证码
        JsonResult result = MobileSmsUtil.send(MobileProperties.SMS_APPID, phone, MobileProperties.SMS_TEMPLATEID, smsCode, "json");
        if (result.getCode() == 1) {
            redisService.set(key, smsCode, 120);
            log.info("发送短信验证码成功");
            return JsonResult.success("发送成功");
        } else {
            log.info("发送短信验证码失败");
            return JsonResult.error("发送失败");
        }
    }

    /***
     * 生成随机号码 6位
     * @return
     */
    private String getRandomCode() {
        Random random = new Random();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 6; i++) {
            sb.append(random.nextInt(10));
        }
        return sb.toString();

    }
}

4、发送短信相关的配置 Properties:

package cn.wpg.core.constant;

import cn.wpg.core.util.MD5Util;

import java.util.Base64;
import java.util.Date;


/**
 * <p>发送短信相关的配置 Properties</p>
 * <pre>
 * @author Wupeiguo
 * @date 2019/06/14 11:42
 * </pre>
 */
public class MobileProperties {

    /**
     * API请求地址
     */
    private static final String SMS_BASE_URL = "https://api.XXX.com/";
    /**
     * 云之讯REST API版本号。当前版本号为:2014-06-30
     */
    private static final String SMS_SOFTVERSION = "2014-06-30";
    /**
     * 开发者账号ID。由32个英文字母和阿拉伯数字组成的开发者账号唯一标识符。
     */
    private static final String SMS_ACCOUNT_SID = "96ea71afc8a76e978cbc13f67a4aa624";
    /**
     * 开发者账号TOKEN
     */
    private static final String SMS_TOKEN = "c59ff426f4c88a2dc0e612a6c860b144";
    private static String timestamp;

    public static final String SMS_APPID = "5edd47ba7fa84465a90c1d08ac8c9547";
    public static final String SMS_TEMPLATEID = "51730";

    /**
     * @return string
     * 验证参数,URL后必须带有sig参数,sig= MD5(账户Id + 账户授权令牌 + 时间戳,共32位)(注:转成大写)
     */
    private static String getSigParameter() {
        String sig = SMS_ACCOUNT_SID + SMS_TOKEN + timestamp;
        sig = MD5Util.encrypt(sig);
        return sig.toUpperCase();
    }

    private static String getTimestamp() {
        return format(new Date(), "yyyyMMddHHmmss");
    }

    public static String getSendSmsUrl() {
        timestamp=getTimestamp();
        return SMS_BASE_URL + SMS_SOFTVERSION + "/Accounts/" + SMS_ACCOUNT_SID + "/Messages/templateSMS?sig=" + getSigParameter();
    }

    public static String getAuthorization() {
        String data = SMS_ACCOUNT_SID + ":" + timestamp;
        return Base64.getEncoder().encodeToString(data.getBytes());
    }

    /**
     * 根据特定格式格式化日期
     *
     * @param date   被格式化的日期
     * @param format 格式
     * @return 格式化后的字符串
     */
    public static String format(Date date, String format) {
        return new SimpleDateFormat(format).format(date);
    }

}
 

5、手机发送短信工具 Util:

package cn.wpg.core.util;

import cn.wpg.core.base.restful.JsonResult;
import cn.wpg.core.constant.MobileProperties;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;


/**
 * <p>手机发送短信工具 Util</p>
 * <pre>
 * @author Wupeiguo
 * @date 2019/06/14 11:42
 * </pre>
 */
public class MobileSmsUtil {
    public static JsonResult send(String appId, String phone, String templateId, String smsCode, String type) {
        String sendSmsUrl = MobileProperties.getSendSmsUrl();
        String body;
        if ("json".equals(type)) {
            JSONObject json = new JSONObject();
            Map<String, String> bodyMap = new HashMap<>(4);
            bodyMap.put("appId", appId);
            bodyMap.put("templateId", templateId);
            bodyMap.put("appId", appId);
            bodyMap.put("to", phone);
            bodyMap.put("param", smsCode);

            json.put("templateSMS", bodyMap);
            body = json.toJSONString();
        } else if ("xml".equals(type)) {
            String bodyXml = "<?xml version='1.0' encoding='UTF-8' standalone='yes'?>" +
                    "<templateSMS>" +
                    "<templateId>" + templateId + "</templateId>" +
                    "<to>" + phone + "</to>" +
                    "<param>" + smsCode + "</param>" +
                    "<appId>" + appId + "</appId>" +
                    "</templateSMS>";
            body = bodyXml;
        } else {
            throw new RuntimeException("只能json或xml,默认为json");
        }
        String result = doSend(sendSmsUrl, body, type);
        return result == null ?JsonResult.error("发送失败"):JsonResult.success(result);
    }

    private static String doSend(String url, String body, String type) {
        String mine;
        if ("json".equals(type)) {
            mine = "application/json";
        } else {
            mine = "application/xml";
        }
        Map<String, String> header = new HashMap<>(3);
        header.put("Accept", mine);
        header.put("Content-Type", mine + ";charset=utf-8");
        header.put("Authorization", MobileProperties.getAuthorization());
        return HdoPost(url, body, header);
    }


    private static String HdoPost(String url, String body, Map<String, String> header) {
        HttpClient httpClient;
        HttpPost postMethod;
        HttpResponse response;
        try {
            httpClient = HttpClients.createDefault();
            //传入URL地址
            postMethod = new HttpPost(url);
            //设置请求头
            if (header != null) {
                for (Map.Entry<String, String> entry : header.entrySet()) {
                    //设置请求头
                    postMethod.addHeader(entry.getKey(), entry.getValue());

                }
            }
            // 传入请求参数
            postMethod.setEntity(new StringEntity(body, Charset.forName("UTF-8")));
            // 获取响应
            response = httpClient.execute(postMethod);
            int statusCode = response.getStatusLine().getStatusCode();
            System.out.println("HTTP Status Code:" + statusCode);
            if (statusCode != HttpStatus.SC_OK) {
                System.out.println("HTTP请求未成功!HTTP Status Code:" + response.getStatusLine());
                return null;
            }
            HttpEntity httpEntity = response.getEntity();
            String reponseContent = EntityUtils.toString(httpEntity);
            // 释放资源
            EntityUtils.consume(httpEntity);
            System.out.println("响应内容:" + reponseContent);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }
}

 

6、MD5加密类(封装jdk自带的md5加密方法):

package cn.wpg.core.util;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * MD5加密类(封装jdk自带的md5加密方法)
 * @author zhangzhc 
 * @date 2018-06-07 10:57:38
 */
public class MD5Util {

    /**
     * 安全码
     */
    public static final String SECURITY_CODE = "wha3202343222dxssssssswwd";
    
    /**
     * md5加密密码
     *
     * @param source 源数据
     * @param salt   盐
     * @return String
     */
    public static String encryptAndSalt(String source, String salt) {
        salt = (salt != null ? salt : "") + SECURITY_CODE;
        source = MD5Util.encrypt(source) + salt;
        return MD5Util.encrypt(source);
    }

    /**
     * md5加密
     *
     * @param source 源数据
     * @return String
     */
    public static String encrypt(String source) {
        return encodeMd5(source.getBytes());
    }

    private static String encodeMd5(byte[] source) {
        try {
            return encodeHex(MessageDigest.getInstance("MD5").digest(source));
        } catch (NoSuchAlgorithmException e) {
            throw new IllegalStateException(e.getMessage(), e);
        }
    }

    private static String encodeHex(byte[] bytes) {
        StringBuffer buffer = new StringBuffer(bytes.length * 2);
        for (int i = 0; i < bytes.length; i++) {
            if (((int) bytes[i] & 0xff) < 0x10) {
                buffer.append("0");
            }
            buffer.append(Long.toString((int) bytes[i] & 0xff, 16));
        }
        return buffer.toString();
    }

    public static void main(String[] args) {
        System.out.println(encrypt("123456"));
    }
}

7、备注:

jar包:

com.alibaba.fastjson:
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>${fastjson.version}</version>
</dependency>

org.apache.http:
<dependency>
    <groupId>org.apache.activemq</groupId>
    <artifactId>activemq-http</artifactId>
</dependency>

结果类 JsonResult:

该操作结果类为自定义类,可以用  Object 类型替代

获取图形验证码:

在《图形验证码》篇

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

实现图片验证码与手机短信验证码 的相关文章

  • GO终端读取

    GO终端读取 Go语言获取标准输入 Go语言 fmt 包下有 fmt Scan fmt Scanf fmt Scanln 三个函数 可以在程序运行过程中获取用户输入 func Scan a interface n int err error
  • Spring核心之一:IOC

    IOC Inversion of Control 其实是一种思想 这种思想并不是Spring独有的 而是在软件开发中 大家提出的一种开发原则 类似面向接口编程原则 开闭原则等 网上有很多类似的文章尝试去通俗易懂地解释IOC思想 这里我根据自
  • BugkuCTF-Crypto题小山丘的秘密

    本题考查希尔密码 解题流程 题目信息 1 根据提示知道是希尔 hill 密码 解密网站 www atoolbox net Tool php Id 914 ac csdn flag txt 里给出A 1 一般的希尔密码是A 0 B 1 C 2
  • Vue.js 学习笔记 第5章 内置指令

    本篇目录 5 1 基本指令 5 2 条件渲染指令 5 3 列表渲染指令 v for 5 4 方法与事件 5 5 实战 利用计算属性 指令等知识开发购物车 回顾一下第2 2节 我们己经介绍过指令 Directive 的概念了 Vue js的指
  • JAVA 【基础】 log4j 输出样式

    先了解一下log4j 的打印参数如下 参数 说明 L 输出代码中的行号 l 输出日志事件的发生位置 包括类目名 发生的线程 以及在代码中的行数 如 Testlog main TestLog java 10 m 输出代码中指定的消息 p 输出
  • 使用vs2013编译qt4库

    一 废话 由于项目需要搭建qt msvc2013的环境 而官方提供的qt4库最高只支持和vs2010关联 如果需要配置qt msvc2010只需要安装官方给的qt4库的安装包 然后下载addin就可以了 本人也是第一次搭建该环境 在网上找了
  • GDB 程序调试常用命令

    调试之前 若要在GDB中调试程序在编译时需要加上调试信息 在GCC中添加的方法 GCC g a c o a exe 或下面提供更符合GDB的调试信息 GCC ggdb a c o a exe 运行流程 命令 作用 start 开始执行程序
  • elasticsearch评分进阶

    elasticsearch 评分进阶 原文引用自 Advanced Scoring in elasticsearch 作者还有一篇Elasticsearch评分的经验说明 建议爬墙参考slideshare上的资源对照查看 如有侵权请联系 s
  • 几张架构图阐述微服务架构治理相关知识点

    微服务架构的技术点 超时时间设置 接口重试机制 流量QPS限流 请求熔断处理 请求降级处理 今天给大家分享一下以上相关的知识点 通过微服务系统之间RPC通信的方式 以架构图的形式给大家展开介绍 1 超时时间设置 应用访问业务系统A 业务系统
  • 程序员都要学学任正非的坚强!这个老头,在逆境中崛起!

    点赞再看 养成习惯 微信搜一搜 findyi 关注这个喜欢写情怀的程序员 回复 1 获得程序员职场晋升PPT一份 2019年的最后一天 罗胖在跨年演讲中引用了何帆老师的一句话 用一个人的长期主义 对冲世界的不确定性 那时候 谁也无法想到 世
  • 【STM32】为什么STM32的Flash地址要设置到0x08000000

    参考 不是问题的问题 为什么STM32的Flash地址要设置到0x08000000 这边涉及到分散加载文件 启动文件等等 先挖坑 搞定IAP升级以后再填 为什么STM32的Flash地址要设置到0x08000000 主flash启动时 是从
  • tomcat多系统部署方案

    多系统部署到一个 Tomcat 中 如果某一个系统崩溃可能会同时使其他系统不能正常工作 因为它们运行在同一个 JVM 上 就需要在同一个服务器中安装多个 Tomcat 来运行不同的 WEB 系统 一 Tomcat 版本选择 安装 JDK 版
  • 事件循环(Event Loop)

    目录 一 浏览器的进程模型 1 1 进程 1 2 线程 1 3 浏览器的进程和线程 二 渲染主线程 2 1 渲染主线程中为什么使用异步 2 2 js的异步 2 3 队列的优先级 添加任务到微队列的主要 式主要是使 Promise NextT
  • 板材眼镜大小调整方法

    http v youku com v show id XNTY0NjUwOTU2 html
  • ROS 2正式版来了,到底有哪些新变化?

    锋影 email 174176320 qq com 如果你认为本系列文章对你有所帮助 请大家有钱的捧个钱场 点击此处赞助 赞助额0 1元起步 多少随意 2017 12 09 机器人开源操作系统软件ROS 2终于推出首个正式版 新版本命名为
  • openGL之API学习(一零三)glGetActiveUniform

    获取活跃一致变量的信息 变量可以在程序执行期间被访问 则该变量被认为是活动的 void glGetActiveUniform GLuint program GLuint index GLsizei bufSize GLsizei lengt
  • 微信小程序唤起键盘页面溢出的解决方案

    文章目录 背景 解决方案 效果 背景 微信小程序的 input 组件 如果使用自带的adjust position会引起除了 input 元素的其他元素一并上移 解决方案 首先获取到屏幕的高度screenHeight 确定好每个元素所占的大
  • 静态代码分析工具清单:开源篇(多语言)

    http hao jobbole com static code analysis tool list opensource utm source hao jobbole com utm medium relatedResources 静态

随机推荐

  • 百度地图入门

    百度地图官网百度api 进入官网选择javascript API 里面有详细的教程 跟着教程先登录注册一个个人开发账号 并创建一个应用获取ak 创建时js需要填白名单 如果是在本地运行填写localhost就好了 当你在控制台看到这个界面是
  • eclipse双击变量高亮显示开关

    eclipse双击变量高亮显示开关 在eclipse myeclipse中如果不小心把变量的高亮显示弄丢了 可真是件愁人的事 不过看到这你就不用愁了 windows gt preferences gt java gt Editor gt M
  • Springboot读取jar下的文件(在springboot打包成jar后)

    关于取web jar中的配置数据 以及存储下载的数据临时目录 按如下方法处理 均已测试验证过 1 更新了文件路径问题 所有的初始化数据Jason直接从reasource目录的mockdata里读 2 所有下载的数据 放到web jar同一级
  • C语言学习———函数

    目录 编辑 1 函数的概念 2 函数的分类 3 库函数是什么 3 1库函数的查找学习方法 3 2库函数的分类 4 自定义函数 4 1形参与实参 4 2传值与传址调用 4 3总结一句 5 函数的嵌套定义与链式访问 5 1嵌套定义 5 2链式访
  • 什么是智能合约? 智能合约到底做什么的?

    Solidity Solidity是一种用于编写智能合约的高级语言 语法类似于JavaScript 在以太坊平台上 Solidity编写的智能合约可以被编译成字节码在以太坊虚拟机上运行 使用Solidity语言编写智能合约避免了直接编写底层
  • thinkphp5学习路程 二 URL访问路径

    URL访问路径 localhost studytp1 public index php 模块 控制器 操作名 参数名 参数值 默认情况下URL是不区分大小写的 自动转换成小写 如果要区分 就要打开配置文件中的 关闭URL中控制器和操作名的自
  • 计算机网络一到六章知识点

    一 概述 1 1互联网的基本特性 连通性 互联网上用户不管距离多远 都能通信 就像这些用户终端都彼此连通 共享性 所谓共享就是指资源共享 资源共享 包含信息 软件 硬件等共享 就像资源在用户身边 1 2 因特网 互联网 概述 1 网络的网络
  • 在小程序开发中使用 npm

    微信小程序在 2 2 1 版本后增加了对 npm 包加载的支持 使得小程序支持使用 npm 安装第三方包 1 在小程序中加载 npm 包 npm install miniprogram datepicker production node
  • 数组查找操作:寻找第二大

    一 找出数组中第二大的数字 public class Main public static void main String args int max 0 int smax 0 int arr 1 2 3 4 6 8 7 if arr 0
  • 解决bash: mysql: command not found 的方法【linux mysql命令 】

    linux下 在mysql正常运行的情况下 输入mysql提示 mysql command not found 遇上 bash mysql command not found的情况别着急 这个是因为 usr local bin目录下缺失my
  • C#使用欧姆龙PLC的Fins协议读写PLC地址(基本封装)

    FINS通讯概述 FINS factory interface network service 通信协议是欧姆龙公司开发的用于工业自动化控制网络的指令 响应系统 运用 FINS指令可实现各种网络间的无缝通信 通过编程发送FINS指令 上位机
  • Unity中用到的数学知识 整理 (为自己)

    缓动数学知识 转自 http easings net en CSS CSS properties transition and animation allow you to pick the easing function Unfortun
  • Spring两大特性:IOC和AOP

    Spring拥有两大特性 IOC 控制反转 AOP 面向切面编程 Spring注解 Spring为我们提供了多个方便的注解 例如 Controller 标明为控制层组件 Service 服务层组件 Repository DAO层 Compo
  • openssl hmac源码分析

    hmac 原理 HMAC 用于保护消息的完整性 它采用摘要算法对消息 填充以及秘密密钥进行混合 运算 在消息传输时 用户不仅传送消息本身 还传送 HMAC 值 接收方接收数据后也进 行 HMAC 运算 再比对 MAC 值是否一致 由于秘密密
  • 【ORACLE】ora-12519错误分析解决

    首先检查process和session的使用情况 在sqlplus里面查看 SQL gt show parameter processes NAME TYPE VALUE aq tm processes integer 0 db write
  • gdb常用的调试方法

    1 安装gdb yum install gdb 2 打印线程的堆栈 1 ps afx 查看进程id 2 attach 正在运行的进程 gdb debugme pid 3 set logging file tmp test txt 设置操作g
  • hadoop :java.io.FileNotFoundException: File does not exist:

    点击打开链接转自 http blog 163 com silver9886 126 blog static 35971862201441134010403 1 用hadoop的eclipse插件下M R程序的时候 有时候会报 Excepti
  • JSP pagecontext对象的简介说明

    转自 JSP pagecontext对象的简介说明 下文笔者将讲述pagecontext对象的简介说明 如下所示 pageContext对象的简介 pageContext对象是javax servlet jsp PageContext类的实
  • 解决问题记录16:jar包冲突解决

    当项目中jar遇到冲突问题时 一般我的处理方式就是 比较冲突jar 找出冲突的地方 自己取舍排除即可
  • 实现图片验证码与手机短信验证码

    实现图片验证码与手机短信验证码 1 HTML 代码