天梯计划2.0版本

天梯计划2.0版本

版本特色

(1)在1.x版本的基础上,2.0版本准备在登录页面加入一个人脸识别程序,以防都忘记密码造成损失。

(2)为了安全性着想 给密码进行加密MD5加密

两种功能,明显加密功能是更好实现的,可以选择先实现,不过这样需要修改大量源代码

加密

本程序采用MD5加密方法,MD5加密的好处是,

  • 加密是单向的,就算数据库被打破了,还是照样能使用的。
  • java自带有MD5加密方法,这就使得我们操作起来变得简单

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.dwx.until;

import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5Util {

public String getMD5(String password) {


byte[] digest = null;
try {
MessageDigest md5 = MessageDigest.getInstance("md5");
digest = md5.digest(password.getBytes());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
//16是表示转换为16进制数
String md5Str = new BigInteger(1, digest).toString(16);
return md5Str;
}

}


总结下来 修改代码并不多

  • 登录 需要将明码转化成MD5码
  • 修改 需要把获得的旧密码 新密码转化成MD5码

总之 加密已经完成

人脸识别系统

人脸识别系统需要两种技术

  • 调用摄像头 并且能够拍照
  • 人脸识别技术(对照技术)

对于人脸识别技术已经有了一些认识,参考之前的blog

人脸识别深入认识 | dwx-tx的小天地

但是对于调用摄像头技术,还没有掌握,下边计划先学习网页调用摄像头技术

假设,网页可以调用摄像头并且拍照,可以将拍好的照片暂时生成在服务器中,对比后,删除这个照片即可。

网页调用摄像头拍照技术

参考之前的blog

网页调用摄像头技术 | dwx-tx的小天地

这样后端就接收到了前端传递过来的二进制流,利用二进制流生成图片技术生成前端传递过来的图片

二进制流生成图片技术

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package com.dwx.until;

import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.nio.file.Paths;

//这是一个文件操作
public class FileUtil {

//一个文件读取操作
public String fileUpLoad(MultipartFile myfile,String filename, String fileUrl){
//此路径为 服务器要存储文件的文件夹的路径


//创建新文件
File file = new File(fileUrl+filename);
InputStream inputStream = null;
FileOutputStream fileOutputStream = null;
String result = null;
try {

//获得input流
inputStream = myfile.getInputStream();

fileOutputStream = new FileOutputStream(file);



//固定的文件写操作
int read;
byte[] bytes = new byte[1024];

while ((read = inputStream.read(bytes)) != -1) {
fileOutputStream.write(bytes, 0, read);
}
//如果一切成功
result = "success";


} catch (Exception e) {
System.out.println("程序出错了");
System.out.println(e);
//如果产生了异常 返回false
return "false";

}finally {

//关闭所有的流
try {
fileOutputStream.close();
inputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return result;
}


//一个文件删除操作
public boolean fileDelete(String fileName){
//直接删除
String fileUrl = "/img";

System.out.println(fileUrl + fileName);
File file = new File(fileUrl + fileName);
System.out.println(file.isFile());
boolean delete = file.delete();


return delete;
}



}

controller类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package com.dwx.controller;

import com.dwx.until.FileUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

@Controller
public class areFaceController {

@RequestMapping(value = "/areFace.do")
@ResponseBody
public String areFaceTest(HttpServletRequest request,HttpServletRequest response,HttpSession session) {
MultipartHttpServletRequest multipartRequest=(MultipartHttpServletRequest) request;
MultipartFile myfile = multipartRequest.getFile("file");


//获得正规的
String fileName = myfile.getOriginalFilename();
System.out.println(fileName);
int local = fileName.lastIndexOf(".");
System.out.println(local);
String fileType = fileName.substring(local);
System.out.println("文件类型为:"+fileType);

//获得路径
String contextPath = request.getContextPath();
FileUtil fileUtil = new FileUtil();
String fileUrl = "E:\\java\\union\\src\\main\\java\\com\\dwx\\img\\";


String filename = "test";
//文件上传操作
String s = fileUtil.fileUpLoad(myfile, filename+fileType,fileUrl);

System.out.println("图片生成成功");
//对数据库里的File进行一个增加

return s;


}

}

人脸识别技术

可以参考以前的blog

人脸识别深入认识 | dwx-tx的小天地

利用类似技术来实现人脸识别

具体思路

  • 创建数据库,这里不给管理员设置上传脸部信息的途径,只能通过我操作数据库来上传数据
  • 调用人脸识别工具类获得人的面部信息
  • 调用faceService获得数据库存储的人脸信息
  • 通过一对多的匹配得到可能性最高,且合适的对象
  • 完成登录操作

这里需要注意,SDK的依赖需要手动导入,引擎需要放的后台中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package com.dwx.controller;

import com.dwx.pojo.AreFace;
import com.dwx.pojo.User;
import com.dwx.service.FaceFeatureService;
import com.dwx.service.UserService;
import com.dwx.until.AreFaceUtil;
import com.dwx.until.FileUtil;
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 org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.List;

@Controller
public class AreFaceController {


@Autowired
private FaceFeatureService faceFeatureService;

public FaceFeatureService getFaceFeatureService() {
return faceFeatureService;
}

@Autowired
private UserService userService;

public UserService getUserService() {
return userService;
}

public void setUserService(UserService userService) {
this.userService = userService;
}

public void setFaceFeatureService(FaceFeatureService faceFeatureService) {
this.faceFeatureService = faceFeatureService;
}

//下载图片程序
@RequestMapping(value = "/areFace.do")
@ResponseBody
public String areFaceTest(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
MultipartHttpServletRequest multipartRequest=(MultipartHttpServletRequest) request;
MultipartFile myfile = multipartRequest.getFile("file");


AreFaceUtil areFaceUtil = new AreFaceUtil();
//调用程序 下载图片
fileDownload(myfile);

//调用service 获得数据库中的所有数据
List<AreFace> allAreFaceFeature = faceFeatureService.getAllAreFaceFeature();

//现在我们需要把String转化成byte
//用temp变量来存储最高分数的id
String temp = null;
//用mScore来存储最高分数
double mScore = 0;
for (AreFace areFace : allAreFaceFeature) {
double score = areFaceUtil.getAreFaceFeature(areFace.getAreFaceFeature());
System.out.print("管理员:"+areFace.getId()+"的人脸对比分数为:"+score);
System.out.println();
if (score > mScore){
mScore = score;
temp = areFace.getId();
}
}
//如果分数大于0.8 就可以说明找到了
if (mScore > 0.8){
System.out.println("找到了管理员:"+temp);
}

//调用userService通过id获得User

User userID = userService.getUserID(temp);

System.out.println(userID);
request.getSession().setAttribute("userSession",userID);
System.out.println("================");
//跳转到后端
try {
response.sendRedirect("/union/houtai/jsp/frame.jsp");
} catch (IOException e) {
throw new RuntimeException(e);
}
System.out.println("================");
return "ok";
}

public String fileDownload(MultipartFile myfile){
//获得正规的
String fileName = myfile.getOriginalFilename();
System.out.println(fileName);
int local = fileName.lastIndexOf(".");
System.out.println(local);
String fileType = fileName.substring(local);
System.out.println("文件类型为:"+fileType);

//获得路径
FileUtil fileUtil = new FileUtil();
String fileUrl = "E:\\java\\union\\src\\main\\java\\com\\dwx\\img\\";


String filename = "test";
//文件上传操作
String s = fileUtil.fileUpLoad(myfile, filename+fileType,fileUrl);

System.out.println("图片生成成功");
//对数据库里的File进行一个增加

return s;

}

}

遇到问题了

页面不跳转问题,请求都成功了,就是没跳转

参考解决办法

(183条消息) 解决java后台发起重定向响应成功,但前端不跳转页面问题_二十同学的博客-CSDN博客_java重定向跳转页面怎么不跳

分析是 后端的页面跳转与前端js相矛盾了 但是因为我不懂js 不会修改

网上的资料也不全

解决了 经过前端同学的帮助 解决的这个问题

修改后的HTML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>网页调取摄像头</title>
</head>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<style>
#capture{
position: absolute;
right: 190px;
bottom: -40px;

}
#video{
position: absolute;
right: 0;
top: 0;
}
#img{
position: absolute;
left: 0;
top: 0;
}
.auto{
position: absolute;
left: 50%;
top: 50%;
height: 320px;
margin-top: -160px;
}
#sure{
position: absolute;
left: 210px;
bottom: -40px;

}
button{
cursor: pointer;
margin: 0 auto;
border: 1px solid #f0f0f0;
background: #5CACEE;
color: #FFF;
width: 100px;
height: 36px;
line-height: 36px;
border-radius: 8px;
text-align: center;
/*禁止选择*/
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Chrome/Safari/Opera */
-khtml-user-select: none; /* Konqueror */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; /* Non-prefixed version, currently not supported by any browser */
}
body{
background-color: #61CAD0;
}

</style>
<body>

<div>
<a href="../login/login.jsp"><button id="back" style="height: 40px;" title="点击返回">返回登录页面</button></a>
</div>
<div class="auto">
<video id="video" width="480" height="320" autoplay></video>
<canvas id="canvas" width="480" height="320" style="display: none;"></canvas>
<img id="img" width="480" height="320" style="margin-left: 20px;background-color: #0a5eb6;">
<div>
<button id="capture" title="点击进行拍照">拍照</button>
</div>
<div>
<button id="sure" title="是否用这张图片进行验证">确认</button>
</div>
</div>


<script>
var file ,stream;
//访问用户媒体设备的兼容方法
function getUserMedia(constraints, success, error) {
if (navigator.mediaDevices.getUserMedia) {
//最新的标准API
navigator.mediaDevices.getUserMedia(constraints).then(success).catch(error);
} else if (navigator.webkitGetUserMedia) {
//webkit核心浏览器
navigator.webkitGetUserMedia(constraints,success, error)
} else if (navigator.mozGetUserMedia) {
//firfox浏览器
navigator.mozGetUserMedia(constraints, success, error);
} else if (navigator.getUserMedia) {
//旧版API
navigator.getUserMedia(constraints, success, error);
}
}

let video = document.getElementById('video');
let canvas = document.getElementById('canvas');
let context = canvas.getContext('2d');

function success(stream) {
//兼容webkit核心浏览器
let CompatibleURL = window.URL || window.webkitURL;
//将视频流设置为video元素的源
// console.log(stream);
stream = stream;
//video.src = CompatibleURL.createObjectURL(stream);
video.srcObject = stream;
video.play();
}

function error(error) {
console.log(`访问用户媒体设备失败${error.name}, ${error.message}`);
}

if (navigator.mediaDevices.getUserMedia || navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia) {
//调用用户媒体设备, 访问摄像头
getUserMedia({video : {width: 480, height: 320}}, success, error);
} else {
alert('不支持访问用户媒体');
}
// base64转文件

document.getElementById('capture').addEventListener('click', function () {
context.drawImage(video, 0, 0, 480, 320);
// 获取图片base64链接
var image = canvas.toDataURL('image/png');
// 定义一个img
var img = document.getElementById("img");
//设置属性和src
//img.id = "imgBoxxx";
img.src = image;
//将图片添加到页面中
//document.body.appendChild(img);
function dataURLtoFile(dataurl, filename) {
var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
file = new File([u8arr], filename, {type: mime});
// console.log(file)
return new File([u8arr], filename, {type: mime});
}
console.log(dataURLtoFile(image, "aa.png"));
})

document.getElementById("sure").addEventListener("click", function () {
console.log(file)
console.log('发送Ajax请求')
var formData = new FormData();
formData.append("file",file);
$.ajax({
type: "post",
//后端需要调用的地址
url:"http://localhost:8089/plotform/areFace.do",
data:formData, //发送数据
async: true, // 是否异步
processData: false, //processData 默认为false,当设置为true的时候,jquery ajax 提交的时候不会序列化 data,而是直接使用data
contentType: false,
success:function(data){
console.log(data)
if(data === '200'){
console.log('请求成功,即将跳转')
window.location.href="../houtai/jsp/frame.jsp"
// console.log(`${data.message}`);
}else{
// console.log(`${data.message}`);
}
},
error:function(e){
// self.$message.warning(`${e}`);
console.log("请求失败"+e);
}
});
// stream.getTracks()[0].stop();//结束关闭流
})
</script>
</body>
</html>



后端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
 package com.dwx.controller;

import com.dwx.pojo.AreFace;
import com.dwx.pojo.User;
import com.dwx.service.FaceFeatureService;
import com.dwx.service.UserService;
import com.dwx.until.AreFaceUtil;
import com.dwx.until.FileUtil;
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 org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.List;



@Controller
public class AreFaceController {


@Autowired
private FaceFeatureService faceFeatureService;

public FaceFeatureService getFaceFeatureService() {
return faceFeatureService;
}

@Autowired
private UserService userService;

public UserService getUserService() {
return userService;
}

public void setUserService(UserService userService) {
this.userService = userService;
}

public void setFaceFeatureService(FaceFeatureService faceFeatureService) {
this.faceFeatureService = faceFeatureService;
}

//下载图片程序
@RequestMapping(value = "/areFace.do")
@ResponseBody
public String areFaceTest(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
MultipartHttpServletRequest multipartRequest=(MultipartHttpServletRequest) request;
MultipartFile myfile = multipartRequest.getFile("file");


AreFaceUtil areFaceUtil = new AreFaceUtil();
//调用程序 下载图片
fileDownload(myfile);

//调用service 获得数据库中的所有数据
List<AreFace> allAreFaceFeature = faceFeatureService.getAllAreFaceFeature();

//现在我们需要把String转化成byte
//用temp变量来存储最高分数的id
String temp = null;
//用mScore来存储最高分数
double mScore = 0;
for (AreFace areFace : allAreFaceFeature) {
double score = areFaceUtil.getAreFaceFeature(areFace.getAreFaceFeature());
System.out.print("管理员:"+areFace.getId()+"的人脸对比分数为:"+score);
System.out.println();
if (score > mScore){
mScore = score;
temp = areFace.getId();
}
}
//如果分数大于0.8 就可以说明找到了
if (mScore > 0.8){
System.out.println("找到了管理员:"+temp);
}

//调用userService通过id获得User

User userID = userService.getUserID(temp);

System.out.println(userID);
request.getSession().setAttribute("userSession",userID);

//删除图片
boolean b = fileDelete();
if (b){
System.out.println("图片删除成功");
}else {
System.out.println("图片删除失败");
}
if (mScore > 0.8){
return "200";
}else {
return "300";
}
}

public String fileDownload(MultipartFile myfile){
//获得正规的
String fileName = myfile.getOriginalFilename();
System.out.println(fileName);
int local = fileName.lastIndexOf(".");
System.out.println(local);
String fileType = fileName.substring(local);
System.out.println("文件类型为:"+fileType);

//获得路径
FileUtil fileUtil = new FileUtil();
String fileUrl = "E:\\java\\union\\src\\main\\java\\com\\dwx\\img\\";


String filename = "test";
//文件上传操作
String s = fileUtil.fileUpLoad(myfile, filename+fileType,fileUrl);

System.out.println("图片生成成功");
//对数据库里的File进行一个增加

return s;
}

public boolean fileDelete(){
FileUtil fileUtil = new FileUtil();

String filename = "test";
boolean b = fileUtil.fileDelete( filename + ".png");
return b;
}
}

)

程序彻底写完了

Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2015-2023 dwx
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信