技术标签: 验证码 springboot
验证码这一块,也没啥难的,只是cas需要验证码,所以我就现在springboot上出一款验证码的操作,然后集成到cas上,在验证码操作上,需要理解如何导入静态文件到springboot中。实现的步骤:1、导入验证码生成工具。2、配置yml文件,设定端口号,项目,以及静态文件目录,等信息。3、配置验证码的控制器.4、配置前台设置。
https://gitee.com/yellowcong/springboot-demo/tree/master/springboot-server-code
验证码控制器,可以验证验证码正确性,以及生成验证码的服务,验证码生成工具可以查看Java工具包之验证码生成工具类-yellowcong
package com.yellowcong.cas.controller;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yellowcong.auth.code.CaptchaCodeUtils;
import com.yellowcong.auth.code.CaptchaCodeUtils.CaptchaCode;
import com.yellowcong.auth.constants.Constants;
@Controller
public class CaptchaController {
/**
* 创建日期:2018/02/07<br/>
* 创建时间:8:36:28<br/>
* 创建用户:yellowcong<br/>
* 机能概要: 写数据到客户端
* @param request
* @param response
* @throws Exception
*/
@GetMapping(value = Constants.REQUEST_MAPPING, produces = "image/png")
public void handleRequestInternal(HttpServletRequest req, HttpServletResponse resp) throws Exception {
OutputStream out = null;
try {
//设置response头信息
//禁止缓存
resp.setHeader("Cache-Control", "no-cache");
resp.setContentType("image/png");
//存储验证码到session
CaptchaCode code = CaptchaCodeUtils.getInstance().getCode();
//获取验证码code
String codeTxt = code.getText();
req.getSession().setAttribute(Constants.STORE_CODE, codeTxt);
System.out.println(req.getSession().getAttribute(Constants.STORE_CODE));
//写文件到客户端
out = resp.getOutputStream();
byte[] imgs = code.getData();
out.write(imgs, 0, imgs.length);
out.flush();
} finally {
if(out != null) {
out.close();
}
}
}
/**
* 创建日期:2018年2月7日<br/>
* 创建时间:下午10:09:29<br/>
* 创建用户:yellowcong<br/>
* 机能概要:验证码比对
* @param code
* @param req
* @param resp
*/
@RequestMapping(value="/chkCode",method=RequestMethod.POST)
public void checkJSON(String code,HttpServletRequest req,HttpServletResponse resp) {
//获取session中的验证码
String storeCode = (String)req.getSession().getAttribute(Constants.STORE_CODE);
code = code.trim();
//返回值
Map<String,Object> map = new HashMap<String, Object>();
//验证是否对,不管大小写
if(!StringUtils.isEmpty(storeCode) && code.equalsIgnoreCase(storeCode)) {
map.put("error", false);
map.put("msg", "验证成功");
}else if (StringUtils.isEmpty(code)){
map.put("error", true);
map.put("msg", "验证码不能为空");
}else {
map.put("error", true);
map.put("msg", "验证码错误");
}
this.writeJSON(resp, map);
}
/**
* 在SpringMvc中获取到Session
* @return
*/
public void writeJSON(HttpServletResponse response,Object object){
try {
//设定编码
response.setCharacterEncoding("UTF-8");
//表示是json类型的数据
response.setContentType("application/json");
//获取PrintWriter 往浏览器端写数据
PrintWriter writer = response.getWriter();
ObjectMapper mapper = new ObjectMapper(); //转换器
//获取到转化后的JSON 数据
String json = mapper.writeValueAsString(object);
//写数据到浏览器
writer.write(json);
//刷新,表示全部写完,把缓存数据都刷出去
writer.flush();
//关闭writer
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
<%@ page import="java.util.Map" %>
<%@ page import="java.util.Iterator" %>
<%@ page import="java.util.List" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>index</title>
<script type="text/javascript" src="<%=request.getContextPath()%>/static/js/jquery-1.7.1.js"></script>
<script type="text/javascript" src="<%=request.getContextPath()%>/static/js/code.js"></script>
</head>
<body>
<h1>首页</h1>
<a href="<%=request.getContextPath()%>/user/info">用户信息</a>
<br/>
<form action="">
用户名:<input type="text" /><br/>
密码:<input type="text" /><br/>
验证码:<img alt="" src="<%=request.getContextPath()%>/captcha" id="code_img" onclick="changeCode()"><input type="text" id="code"/><span id="code_str"></span><br/>
<input type="submit" value="提交"/>
</form>
</body>
</html>
$(function(){
//验证码验证
$("#code").blur(function(){
var codeStr = $("#code").val();
if(codeIsError()){
console.log("验证失败");
}else{
console.log("验证成功");
}
});
});
//---------------------------------------------------------------------
//检查验证码是否正确
//---------------------------------------------------------------------
function changeCode(){
//修改验证码
$("#code_img").attr('src','/captcha?id='+uuid());
}
//-------------------------------------------------------------------------------------------
//生成UUID
//-------------------------------------------------------------------------------------------
function uuid(){
//获取系统当前的时间
var d = new Date().getTime();
//替换uuid里面的x和y
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
//取余 16进制
var r = (d + Math.random()*16)%16 | 0;
//向下去整
d = Math.floor(d/16);
//toString 表示编程16进制的数据
return (c=='x' ? r : (r&0x3|0x8)).toString(16);
});
return uuid;
};
//---------------------------------------------------------------------
//检查验证码是否正确
//---------------------------------------------------------------------
function codeIsError(){
var error = true;
var codeStr = $("#code").val();
if(codeStr == ""){
setCodeInfo(error,"验证码不能为空");
return error;
}
$.ajax({
type : "post", //使用提交的方法 post、get
url : contextPath()+"chkCode", //提交的地址
data : { code:$("#code").val() }, //数据
async : false, //配置是否
dataType:"json",//返回数据类型的格式
success : function(data){
//回调操作
console.log(data);
error = data.error;
setCodeInfo(error,data.msg);
}
});
return error;
}
//设定验证码的错误提示消息
function setCodeInfo(error,msg){
if(error){
$("#code_str").html("<font color='red'>"+msg+"</font>");
}else{
$("#code_str").html("<font color='blue'>"+msg+"</font>");
}
}
// 获取到当前项目的名称
var contextPath = function() {
return "/" + location.pathname.split("/")[1];
}
在yml中,配置了静态文件的目录。然后设置端口好和项目信息。
logging:
#日志存储地址
file: "logs/config/demo-xx.log"
info:
name : "入门案例"
server:
#端口号
#http://yellowcong.com:8888/
port: 8888
#项目名,如果不设定,默认是 /
context-path: /
---
#spring.mvc.resources
spring:
mvc:
#配置静态文件地址
static-path-pattern: /static/**
view:
# 页面默认前缀目录
prefix: /WEB-INF/jsp/
# 响应页面默认后缀
suffix: .jsp
测试验证码,我登录到我的界面,设置登录验证。
PyTorch用预训练模型初始化网络的部分参数关于从预训练的模型加载参数时可能会遇到的一些阻碍,笔者对自己的绵薄经验在此进行分享,也便于自己之后的温习。加载初始化参数可参照论坛中 apaszke的做法,其删除了与当前model不匹配的key。代码为:pretrained_dict = ...model_dict = model.state_dict()# 1. filter out unnecessary keyspretrained_dict = {k: v for k, v in pret_1671465600
1、python的标准库是随着pyhon安装的时候默认自带的库。2、python的第三方库,需要下载后安装到python的安装目录下,不同的第三方库安装及使用方法不同。3、它们调用方式是一样的,都需要用import语句调用。简单的说,一个是默认自带不需要下载安装的库,一个是需要下载安装的库。它们的调用方式是一样的。20个必不可少的Python库也是基本的第三方库BeautifulSoup.我知道它...
# -*- coding: utf-8 -*-##参考https://www.cnblogs.com/mafeng/p/6292024.html 编码import base64import reimport urllibimport urllib2url = "http://192.168.81.13/prt_test.htm"data = {'hex_mode': 'on', 'Send': 'Print Test'}content = u"""1000使用以下这个命令来清空缓存:
#include using namespace std;int main(){ char ch; cout<<"输入一行字符:"<<endl; ch=cin.get(); while(ch!='\n') { cout.put(ch); ch=cin.get(); } cout<<endl; system("PAUSE"); return 0;}
幻影解析网(dns.52hyjs.com)专为新手站长提供的免费二级域名解析,域名均免费提供使用专门提供二级域名解析的平台,域名均免费提供使用,不收取任何费用,提供的域名当中有已备案域名和未备案域名,域名后缀多可自主选择解析全站提供免费阿里云企业备案域名 供大家使用https://dns.52hyjs.com/...
1、void 不能用来定义变量,因为void 大小不明确,但是 void *可以,因为是指针类型他的大小总是 4 个字节。win 32 下为0,Linux下为12、void * 不能被直接解引用。3、void * 可以接收任意类型,常用于指针场景。...
在做一个关于相机库SDK的二次开发demo,记录此过程工业相机都配有自己的相机软件,在软件中会集成这家相机的各种型号下的硬件配置,所以这部分不需要我们去关心,仅需要知道它干了些什么就可以,关于工业相机的编程模型和流程在:https://blog.csdn.net/wenzhou1219/article/details/45874779工业相机的编程原理及流程我们知道了,接下来就是找到这些工业...
如有错误,恳请指出。文章目录1. Introduction2. Related Work2.1 Analyzing importance of depth2.2 Scaling DNNs3. ParNet Method3.1 ParNet Block3.2 Downsampling and fusion block3.3 Network Architecture3.4 Scaling ParNet3.5 Practical Advantages or Parallel Architecures4. R._1671465600
https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html一般来说,如果不指定优化标识的话,gcc就会产生可调试代码,每条指令之间将是独立的:可以在指令之间设置断点,使用gdb中的 p命令查看变量的值,改变变量的值等。并且把获取最快的编译速度作为它的目标。当优化标识被启用之后,gcc编译器将会试图改变程序的结构(当然会在保证变换之后的程序与源程序语义等价的前提之下),以满足某些目标,如:代码大小最小或运行速度更快(只不过通常来说,..
EasyExcel导出自定义合并单元格文件
恭喜刘金鹏、陈众贤(铁熊)、裘炯涛三位老师联合编写的新书《来吧,一起创客:基于 Mixly 和 Mind+ 平台的创客作品 12 例》正式上市!# 内容摘要本书是基于 3 位作者多年的中小...
13.3.2 cocos2d项目如何支持ARCiOS 5中所支持的全新特性ARC(Automatic Reference Counting)首次在iOS系统中提供了自动内存管理,从而避免因为对retain、release、autorelease这些命令的错误调用而导致内存泄漏。实际上,Apple还成功地使得ARC可以向下兼容iOS 4的项目。现如今,越...