1.统一消息处理 前后端分离

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
public class Result<T> {
private int code;
private String msg;
private T data;

//失败的时候调用
private Result(CodeMsg cm)
{
if(cm=null)
{
return;
}
this.code=cm.getCode();
this.msg=cm.getMsg();
}
//成功的时候调用
private Result(T data){
this.code=0;
this.msg="SUCCESS";
this.data=data;
}
//失败的时候调用
public static <T> Result<T> Error(CodeMsg cm){
return new Result<T>(cm);
}
//成功的时候调用
public static <T> Result<T> Success(T data){
return new Result<T>(data);
}


//生成构造方法
public Result(int code){
this.code=code;
}
public Result(String msg){
this.msg=msg;
}

//生成set/get方法
public int getCode(){
return code;
}
public void setCode(int code){
this.code=code;
}
public int getMsg(){
return msg;
}
public void setMsg(String msg){
this.msg=msg;
}

public T getData(){
return data;
}
public void setData(T data){
this.data=data;
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class CodeMsg{
private int code;
private String msg;

//通用异常

public static CodeMsg SUCCESS=new CodeMsg(0, "success");
public static CodeMsg ERROR =new CodeMsg(-1, "error");


private CodeMsg(int code,String msg){
this.code=code;
this.msg=msg;
}

public int getCode(){
return code;
}

public String getMsg(){
return msg;
}

}

2 在Controller中使用@ResponseBody注解 返回JSON数据 return


1
2
3
4
5
6
7
8
9
10
@Controller
@RequestMapping
public class DemoTestController {

@RequestMapping("/")
@ResponseBody
//通常用来返回JSON数据或者是XML/
String home() {
return "hello world";
}

image-20190203092808595


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
@RequestMapping("/resultsuccess")
@ResponseBody
public Result<String> resultsuccess() {
//⭐️⭐️⭐️⭐️⭐️
/**1.返回成功的时候调用
* public static <T> Result<T> success(T data) {
* return new Result<T>(data);
* }
*
* private Result(T data) {
* this.code = 0;
* this.msg = "success";
* this.data = data;
* }
* 1.Result.success(data);
* 结果:
* {
* "code": 0,
* "msg": "success",
* "data": "hello immooc"
* }
*/

return Result.success("hello immooc");

}

image-20190203093050758


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
@RequestMapping("/resulterror")
@ResponseBody
public Result<String> resultError() {
/**
* 2。失败的时候调用
* public static <T> Result<T> error(CodeMsg cm) {
* return new Result<T>(cm);
* }
*
* private Result(CodeMsg cm) {
* if (cm == null) {
* return;
* }
* this.code = cm.getCode();
* this.msg = cm.getMsg();
* }
* 2 Result.error(CodeMsg.SERVER_NAME)
* public static CodeMsg SERVER_NAME = new CodeMsg(50001, "服务端异常");
*
* 结果 {
* "code": 50001,
* "msg": "服务端异常",
* "data": null
* }
* 分析:
* 因为CodeMsg SUCCESS 用static修饰了
* public static CodeMsg SUCCESS = new CodeMsg(0, "success");
* 所以可以使用类.属性.属性的方式获得
* CodeMsg.SUCCESS.code=50001
* CodeMsg.SUCCESS.msg="服务端异常"
*/
return Result.error(CodeMsg.SERVER_NAME);

}

image-20190203093139520


3 前后的分离的分析

image-20190203093624571


image-20190203093752553


4 Controller 层的代码编写 snip

LoginController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Controller
@RequestMapping("/login")
public class LoginController {
//self4日志处理
private static Logger logger = LoggerFactory.getLogger(LoginController.class);
@Autowired
private MiaoShaoUserServiceImpl miaoShaoUserService;
@RequestMapping("/to_login")
public String toLogin() {
return "login";//跳转到登陆页面login.html
}

@RequestMapping("/do_login")
@ResponseBody
//loginVo用户登陆的POJO
public Result doLogin(@Valid LoginVo loginVo) {
logger.info(loginVo.toString());

//核心代码 ⭐️⭐️
miaoShaoUserService.login(loginVo);

return Result.success(true);
}
}

POJO loginVo

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
package com.imooc.miaosha.domain;
import com.imooc.miaosha.validate.IsMobile;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotNull;
public class LoginVo {

@NotNull
//自定义validator
@IsMobile
private String mobile;
@NotNull
@Length(min = 32)
private String password;

public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "LoginVo{" +
"mobile='" + mobile + '\'' +
", password='" + password + '\'' +
'}';
}
}

MiaoShaoUserService.

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
@Service
public class MiaoShaoUserServiceImpl implements MiaoShaoUserService {
@Autowired
private MiaoshaUserMapper miaoshaUserMapper;
@Override
//得到数据库里面的User用户的所有字段 getById(long id)
public MiaoshaUser getById(long id) {
return miaoshaUserMapper.selectByPrimaryKey(id);
}
//检测是否登陆 loginVo和前端ajax data绑定了
public boolean login(LoginVo loginVo) {
if (loginVo == null) {
throw new GlobalException(CodeMsg.SERVER_ERROR);
}
// 拿到页面中的手机号码
String form_mobile = loginVo.getMobile();
// 拿到页面中的密码
String form_Password = loginVo.getPassword();
//判断手机号是否存在getById==selectByPrimaryKey(id) 看看数据库中存不存在这个数据
//将查询出来的数据变成miaoshaUser
MiaoshaUser miaoshaUser = getById(Long.parseLong(form_mobile));

if (miaoshaUser == null) {
throw new GlobalException(CodeMsg.MOBILE_NOT_EXIST);
}
//如果用户存在
//1 验证密码
//数据库里面的密码 dbPassword b7797cce01b4b131b433b6acf4add 449
String dbPassword = miaoshaUser.getPassword();//Md5Utils.inputPassToDbPass()=dbPass
//数据库里面的盐值
String dbSalt = miaoshaUser.getSalt();
//经过计算得到的密码 原密码 123456 calcpass= d3b1294a61a07da9b49b6e22b2cbd7 f9
String calcPass = MD5Util.fromPassToDBPass(form_Password, dbSalt);
//==inputPassToDbPass=calcPass
if (!calcPass.equals(dbPassword)) {
throw new GlobalException(CodeMsg.PASSWORED_ERROR);
}
return true;
}
}

MiaoshaUserMapper–selectByPrimaryKey

1
2
3
4
5
@Mapper
public interface MiaoshaUserMapper {
//id=手机号码 返回一个MiaoshaUser对象
MiaoshaUser selectByPrimaryKey(Long id);
}
1
2
3
4
5
6
<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
select
id, nickname, `password`, salt, head, registerr_date, login_count
from miaosha_user
where id = #{id,jdbcType=BIGINT}
</select>

MD5Utils 密码加密

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
package com.imooc.miaosha.utils;

import org.apache.commons.codec.digest.DigestUtils;

public class MD5Util {
public static void main(String args[]) {
System.out.println(inputPassToFormPass("123456")); //d3b1294a61a07da9b49b6e22b2cbd7 f9
System.out.println(fromPassToDBPass("123456", "1a2b3c4d")); //d3b1294a61a07da9b49b6e22b2cbd7 f9
System.out.println(inputPassToDbPass("123456","1a2b3c4d"));
//b7797cce01b4b131b433b6acf4add 449
}

/*固定盐值*/
private static final String salt = "1a2b3c4d";

//注意导包为codec中的DigestUtils类.codec.digest.DigestUtils;
public static String md5(String src) {
//计算MD5摘要并以32个字符十六进制字符串的形式返回值。
return DigestUtils.md5Hex(src);
}

/**
* 第一次md5 :
* 用于 通过输入的密码生成
* 传输的密码 : 方法 通过固定盐值和明文密码之间的拼接在生成md5
*/
public static String inputPassToFormPass(String inputPass) {
String str = "" + salt.charAt(0) + salt.charAt(2) + inputPass + salt.charAt(5) + salt.charAt(4);
return md5(str);
}

/**
* 第二次md5 :
*/
public static String fromPassToDBPass(String formpasss, String salt) {
String str = "" + salt.charAt(0) + salt.charAt(2) + formpasss + salt.charAt(5) + salt.charAt(4);
return md5(str);
}

//将密码封装到数据库中
public static String inputPassToDbPass(String input, String saltDB) {
String s = inputPassToFormPass(input);
String formPass = fromPassToDBPass(s, saltDB);
return formPass;
}
}

Ajax

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
function doLogin() {

..密码处理
var inputpass = $("#password").val();
var salt = "1a2b3c4d";
var str = "" + salt.charAt(0) + salt.charAt(2) + inputpass + salt.charAt(5) + salt.charAt(4);
var password = md5(str);


$.ajax({
url: "/login/do_login",
type: "POST",
data: {
mobile: $("#mobile").val(),
password: password
},
success: function (data) {
layer.closeAll();
if (data.code == 0) {
layer.msg("成功");
} else {
layer.msg(data.msg);
}
console.log(data);
},
error: function () {
layer.closeAll();
}
});

}

MD5.min.js

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
/**
* [js-md5]{@link https://github.com/emn178/js-md5}
*
* @namespace md5
* @version 0.7.2
* @author Chen, Yi-Cyuan [emn178@gmail.com]
* @copyright Chen, Yi-Cyuan 2014-2017
* @license MIT
*/
!function () {
"use strict";

function Md5(t) {
if (t) blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0, this.blocks = blocks, this.buffer8 = buffer8; else if (ARRAY_BUFFER) {
var r = new ArrayBuffer(68);
this.buffer8 = new Uint8Array(r), this.blocks = new Uint32Array(r)
} else this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
this.h0 = this.h1 = this.h2 = this.h3 = this.start = this.bytes = this.hBytes = 0, this.finalized = this.hashed = !1, this.first = !0
}

var ERROR = "input is invalid type", WINDOW = "object" == typeof window, root = WINDOW ? window : {};
root.JS_MD5_NO_WINDOW && (WINDOW = !1);
var WEB_WORKER = !WINDOW && "object" == typeof self,
NODE_JS = !root.JS_MD5_NO_NODE_JS && "object" == typeof process && process.versions && process.versions.node;
NODE_JS ? root = global : WEB_WORKER && (root = self);
var COMMON_JS = !root.JS_MD5_NO_COMMON_JS && "object" == typeof module && module.exports,
AMD = "function" == typeof define && define.amd,
ARRAY_BUFFER = !root.JS_MD5_NO_ARRAY_BUFFER && "undefined" != typeof ArrayBuffer,
HEX_CHARS = "0123456789abcdef".split(""), EXTRA = [128, 32768, 8388608, -2147483648], SHIFT = [0, 8, 16, 24],
OUTPUT_TYPES = ["hex", "array", "digest", "buffer", "arrayBuffer", "base64"],
BASE64_ENCODE_CHAR = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split(""), blocks = [],
buffer8;
if (ARRAY_BUFFER) {
var buffer = new ArrayBuffer(68);
buffer8 = new Uint8Array(buffer), blocks = new Uint32Array(buffer)
}
(root.JS_MD5_NO_NODE_JS || !Array.isArray) && (Array.isArray = function (t) {
return "[object Array]" === Object.prototype.toString.call(t)
}), !ARRAY_BUFFER || !root.JS_MD5_NO_ARRAY_BUFFER_IS_VIEW && ArrayBuffer.isView || (ArrayBuffer.isView = function (t) {
return "object" == typeof t && t.buffer && t.buffer.constructor === ArrayBuffer
});
var createOutputMethod = function (t) {
return function (r) {
return new Md5(!0).update(r)[t]()
}
}, createMethod = function () {
var t = createOutputMethod("hex");
NODE_JS && (t = nodeWrap(t)), t.create = function () {
return new Md5
}, t.update = function (r) {
return t.create().update(r)
};
for (var r = 0; r < OUTPUT_TYPES.length; ++r) {
var e = OUTPUT_TYPES[r];
t[e] = createOutputMethod(e)
}
return t
}, nodeWrap = function (method) {
var crypto = eval("require('crypto')"), Buffer = eval("require('buffer').Buffer"), nodeMethod = function (t) {
if ("string" == typeof t) return crypto.createHash("md5").update(t, "utf8").digest("hex");
if (null === t || void 0 === t) throw ERROR;
return t.constructor === ArrayBuffer && (t = new Uint8Array(t)), Array.isArray(t) || ArrayBuffer.isView(t) || t.constructor === Buffer ? crypto.createHash("md5").update(new Buffer(t)).digest("hex") : method(t)
};
return nodeMethod
};
Md5.prototype.update = function (t) {
if (!this.finalized) {
var r, e = typeof t;
if ("string" !== e) {
if ("object" !== e) throw ERROR;
if (null === t) throw ERROR;
if (ARRAY_BUFFER && t.constructor === ArrayBuffer) t = new Uint8Array(t); else if (!(Array.isArray(t) || ARRAY_BUFFER && ArrayBuffer.isView(t))) throw ERROR;
r = !0
}
for (var s, i, o = 0, h = t.length, f = this.blocks, a = this.buffer8; h > o;) {
if (this.hashed && (this.hashed = !1, f[0] = f[16], f[16] = f[1] = f[2] = f[3] = f[4] = f[5] = f[6] = f[7] = f[8] = f[9] = f[10] = f[11] = f[12] = f[13] = f[14] = f[15] = 0), r) if (ARRAY_BUFFER) for (i = this.start; h > o && 64 > i; ++o) a[i++] = t[o]; else for (i = this.start; h > o && 64 > i; ++o) f[i >> 2] |= t[o] << SHIFT[3 & i++]; else if (ARRAY_BUFFER) for (i = this.start; h > o && 64 > i; ++o) s = t.charCodeAt(o), 128 > s ? a[i++] = s : 2048 > s ? (a[i++] = 192 | s >> 6, a[i++] = 128 | 63 & s) : 55296 > s || s >= 57344 ? (a[i++] = 224 | s >> 12, a[i++] = 128 | s >> 6 & 63, a[i++] = 128 | 63 & s) : (s = 65536 + ((1023 & s) << 10 | 1023 & t.charCodeAt(++o)), a[i++] = 240 | s >> 18, a[i++] = 128 | s >> 12 & 63, a[i++] = 128 | s >> 6 & 63, a[i++] = 128 | 63 & s); else for (i = this.start; h > o && 64 > i; ++o) s = t.charCodeAt(o), 128 > s ? f[i >> 2] |= s << SHIFT[3 & i++] : 2048 > s ? (f[i >> 2] |= (192 | s >> 6) << SHIFT[3 & i++], f[i >> 2] |= (128 | 63 & s) << SHIFT[3 & i++]) : 55296 > s || s >= 57344 ? (f[i >> 2] |= (224 | s >> 12) << SHIFT[3 & i++], f[i >> 2] |= (128 | s >> 6 & 63) << SHIFT[3 & i++], f[i >> 2] |= (128 | 63 & s) << SHIFT[3 & i++]) : (s = 65536 + ((1023 & s) << 10 | 1023 & t.charCodeAt(++o)), f[i >> 2] |= (240 | s >> 18) << SHIFT[3 & i++], f[i >> 2] |= (128 | s >> 12 & 63) << SHIFT[3 & i++], f[i >> 2] |= (128 | s >> 6 & 63) << SHIFT[3 & i++], f[i >> 2] |= (128 | 63 & s) << SHIFT[3 & i++]);
this.lastByteIndex = i, this.bytes += i - this.start, i >= 64 ? (this.start = i - 64, this.hash(), this.hashed = !0) : this.start = i
}
return this.bytes > 4294967295 && (this.hBytes += this.bytes / 4294967296 << 0, this.bytes = this.bytes % 4294967296), this
}
}, Md5.prototype.finalize = function () {
if (!this.finalized) {
this.finalized = !0;
var t = this.blocks, r = this.lastByteIndex;
t[r >> 2] |= EXTRA[3 & r], r >= 56 && (this.hashed || this.hash(), t[0] = t[16], t[16] = t[1] = t[2] = t[3] = t[4] = t[5] = t[6] = t[7] = t[8] = t[9] = t[10] = t[11] = t[12] = t[13] = t[14] = t[15] = 0), t[14] = this.bytes << 3, t[15] = this.hBytes << 3 | this.bytes >> 29, this.hash()
}
}, Md5.prototype.hash = function () {
var t, r, e, s, i, o, h = this.blocks;
this.first ? (t = h[0] - 680876937, t = (t << 7 | t >>> 25) - 271733879 << 0, s = (-1732584194 ^ 2004318071 & t) + h[1] - 117830708, s = (s << 12 | s >>> 20) + t << 0, e = (-271733879 ^ s & (-271733879 ^ t)) + h[2] - 1126478375, e = (e << 17 | e >>> 15) + s << 0, r = (t ^ e & (s ^ t)) + h[3] - 1316259209, r = (r << 22 | r >>> 10) + e << 0) : (t = this.h0, r = this.h1, e = this.h2, s = this.h3, t += (s ^ r & (e ^ s)) + h[0] - 680876936, t = (t << 7 | t >>> 25) + r << 0, s += (e ^ t & (r ^ e)) + h[1] - 389564586, s = (s << 12 | s >>> 20) + t << 0, e += (r ^ s & (t ^ r)) + h[2] + 606105819, e = (e << 17 | e >>> 15) + s << 0, r += (t ^ e & (s ^ t)) + h[3] - 1044525330, r = (r << 22 | r >>> 10) + e << 0), t += (s ^ r & (e ^ s)) + h[4] - 176418897, t = (t << 7 | t >>> 25) + r << 0, s += (e ^ t & (r ^ e)) + h[5] + 1200080426, s = (s << 12 | s >>> 20) + t << 0, e += (r ^ s & (t ^ r)) + h[6] - 1473231341, e = (e << 17 | e >>> 15) + s << 0, r += (t ^ e & (s ^ t)) + h[7] - 45705983, r = (r << 22 | r >>> 10) + e << 0, t += (s ^ r & (e ^ s)) + h[8] + 1770035416, t = (t << 7 | t >>> 25) + r << 0, s += (e ^ t & (r ^ e)) + h[9] - 1958414417, s = (s << 12 | s >>> 20) + t << 0, e += (r ^ s & (t ^ r)) + h[10] - 42063, e = (e << 17 | e >>> 15) + s << 0, r += (t ^ e & (s ^ t)) + h[11] - 1990404162, r = (r << 22 | r >>> 10) + e << 0, t += (s ^ r & (e ^ s)) + h[12] + 1804603682, t = (t << 7 | t >>> 25) + r << 0, s += (e ^ t & (r ^ e)) + h[13] - 40341101, s = (s << 12 | s >>> 20) + t << 0, e += (r ^ s & (t ^ r)) + h[14] - 1502002290, e = (e << 17 | e >>> 15) + s << 0, r += (t ^ e & (s ^ t)) + h[15] + 1236535329, r = (r << 22 | r >>> 10) + e << 0, t += (e ^ s & (r ^ e)) + h[1] - 165796510, t = (t << 5 | t >>> 27) + r << 0, s += (r ^ e & (t ^ r)) + h[6] - 1069501632, s = (s << 9 | s >>> 23) + t << 0, e += (t ^ r & (s ^ t)) + h[11] + 643717713, e = (e << 14 | e >>> 18) + s << 0, r += (s ^ t & (e ^ s)) + h[0] - 373897302, r = (r << 20 | r >>> 12) + e << 0, t += (e ^ s & (r ^ e)) + h[5] - 701558691, t = (t << 5 | t >>> 27) + r << 0, s += (r ^ e & (t ^ r)) + h[10] + 38016083, s = (s << 9 | s >>> 23) + t << 0, e += (t ^ r & (s ^ t)) + h[15] - 660478335, e = (e << 14 | e >>> 18) + s << 0, r += (s ^ t & (e ^ s)) + h[4] - 405537848, r = (r << 20 | r >>> 12) + e << 0, t += (e ^ s & (r ^ e)) + h[9] + 568446438, t = (t << 5 | t >>> 27) + r << 0, s += (r ^ e & (t ^ r)) + h[14] - 1019803690, s = (s << 9 | s >>> 23) + t << 0, e += (t ^ r & (s ^ t)) + h[3] - 187363961, e = (e << 14 | e >>> 18) + s << 0, r += (s ^ t & (e ^ s)) + h[8] + 1163531501, r = (r << 20 | r >>> 12) + e << 0, t += (e ^ s & (r ^ e)) + h[13] - 1444681467, t = (t << 5 | t >>> 27) + r << 0, s += (r ^ e & (t ^ r)) + h[2] - 51403784, s = (s << 9 | s >>> 23) + t << 0, e += (t ^ r & (s ^ t)) + h[7] + 1735328473, e = (e << 14 | e >>> 18) + s << 0, r += (s ^ t & (e ^ s)) + h[12] - 1926607734, r = (r << 20 | r >>> 12) + e << 0, i = r ^ e, t += (i ^ s) + h[5] - 378558, t = (t << 4 | t >>> 28) + r << 0, s += (i ^ t) + h[8] - 2022574463, s = (s << 11 | s >>> 21) + t << 0, o = s ^ t, e += (o ^ r) + h[11] + 1839030562, e = (e << 16 | e >>> 16) + s << 0, r += (o ^ e) + h[14] - 35309556, r = (r << 23 | r >>> 9) + e << 0, i = r ^ e, t += (i ^ s) + h[1] - 1530992060, t = (t << 4 | t >>> 28) + r << 0, s += (i ^ t) + h[4] + 1272893353, s = (s << 11 | s >>> 21) + t << 0, o = s ^ t, e += (o ^ r) + h[7] - 155497632, e = (e << 16 | e >>> 16) + s << 0, r += (o ^ e) + h[10] - 1094730640, r = (r << 23 | r >>> 9) + e << 0, i = r ^ e, t += (i ^ s) + h[13] + 681279174, t = (t << 4 | t >>> 28) + r << 0, s += (i ^ t) + h[0] - 358537222, s = (s << 11 | s >>> 21) + t << 0, o = s ^ t, e += (o ^ r) + h[3] - 722521979, e = (e << 16 | e >>> 16) + s << 0, r += (o ^ e) + h[6] + 76029189, r = (r << 23 | r >>> 9) + e << 0, i = r ^ e, t += (i ^ s) + h[9] - 640364487, t = (t << 4 | t >>> 28) + r << 0, s += (i ^ t) + h[12] - 421815835, s = (s << 11 | s >>> 21) + t << 0, o = s ^ t, e += (o ^ r) + h[15] + 530742520, e = (e << 16 | e >>> 16) + s << 0, r += (o ^ e) + h[2] - 995338651, r = (r << 23 | r >>> 9) + e << 0, t += (e ^ (r | ~s)) + h[0] - 198630844, t = (t << 6 | t >>> 26) + r << 0, s += (r ^ (t | ~e)) + h[7] + 1126891415, s = (s << 10 | s >>> 22) + t << 0,e += (t ^ (s | ~r)) + h[14] - 1416354905,e = (e << 15 | e >>> 17) + s << 0,r += (s ^ (e | ~t)) + h[5] - 57434055,r = (r << 21 | r >>> 11) + e << 0,t += (e ^ (r | ~s)) + h[12] + 1700485571,t = (t << 6 | t >>> 26) + r << 0,s += (r ^ (t | ~e)) + h[3] - 1894986606,s = (s << 10 | s >>> 22) + t << 0,e += (t ^ (s | ~r)) + h[10] - 1051523,e = (e << 15 | e >>> 17) + s << 0,r += (s ^ (e | ~t)) + h[1] - 2054922799,r = (r << 21 | r >>> 11) + e << 0,t += (e ^ (r | ~s)) + h[8] + 1873313359,t = (t << 6 | t >>> 26) + r << 0,s += (r ^ (t | ~e)) + h[15] - 30611744,s = (s << 10 | s >>> 22) + t << 0,e += (t ^ (s | ~r)) + h[6] - 1560198380,e = (e << 15 | e >>> 17) + s << 0,r += (s ^ (e | ~t)) + h[13] + 1309151649,r = (r << 21 | r >>> 11) + e << 0,t += (e ^ (r | ~s)) + h[4] - 145523070,t = (t << 6 | t >>> 26) + r << 0,s += (r ^ (t | ~e)) + h[11] - 1120210379,s = (s << 10 | s >>> 22) + t << 0,e += (t ^ (s | ~r)) + h[2] + 718787259,e = (e << 15 | e >>> 17) + s << 0,r += (s ^ (e | ~t)) + h[9] - 343485551,r = (r << 21 | r >>> 11) + e << 0,this.first ? (this.h0 = t + 1732584193 << 0, this.h1 = r - 271733879 << 0, this.h2 = e - 1732584194 << 0, this.h3 = s + 271733878 << 0, this.first = !1) : (this.h0 = this.h0 + t << 0, this.h1 = this.h1 + r << 0, this.h2 = this.h2 + e << 0, this.h3 = this.h3 + s << 0)
}, Md5.prototype.hex = function () {
this.finalize();
var t = this.h0, r = this.h1, e = this.h2, s = this.h3;
return HEX_CHARS[t >> 4 & 15] + HEX_CHARS[15 & t] + HEX_CHARS[t >> 12 & 15] + HEX_CHARS[t >> 8 & 15] + HEX_CHARS[t >> 20 & 15] + HEX_CHARS[t >> 16 & 15] + HEX_CHARS[t >> 28 & 15] + HEX_CHARS[t >> 24 & 15] + HEX_CHARS[r >> 4 & 15] + HEX_CHARS[15 & r] + HEX_CHARS[r >> 12 & 15] + HEX_CHARS[r >> 8 & 15] + HEX_CHARS[r >> 20 & 15] + HEX_CHARS[r >> 16 & 15] + HEX_CHARS[r >> 28 & 15] + HEX_CHARS[r >> 24 & 15] + HEX_CHARS[e >> 4 & 15] + HEX_CHARS[15 & e] + HEX_CHARS[e >> 12 & 15] + HEX_CHARS[e >> 8 & 15] + HEX_CHARS[e >> 20 & 15] + HEX_CHARS[e >> 16 & 15] + HEX_CHARS[e >> 28 & 15] + HEX_CHARS[e >> 24 & 15] + HEX_CHARS[s >> 4 & 15] + HEX_CHARS[15 & s] + HEX_CHARS[s >> 12 & 15] + HEX_CHARS[s >> 8 & 15] + HEX_CHARS[s >> 20 & 15] + HEX_CHARS[s >> 16 & 15] + HEX_CHARS[s >> 28 & 15] + HEX_CHARS[s >> 24 & 15]
}, Md5.prototype.toString = Md5.prototype.hex, Md5.prototype.digest = function () {
this.finalize();
var t = this.h0, r = this.h1, e = this.h2, s = this.h3;
return [255 & t, t >> 8 & 255, t >> 16 & 255, t >> 24 & 255, 255 & r, r >> 8 & 255, r >> 16 & 255, r >> 24 & 255, 255 & e, e >> 8 & 255, e >> 16 & 255, e >> 24 & 255, 255 & s, s >> 8 & 255, s >> 16 & 255, s >> 24 & 255]
}, Md5.prototype.array = Md5.prototype.digest, Md5.prototype.arrayBuffer = function () {
this.finalize();
var t = new ArrayBuffer(16), r = new Uint32Array(t);
return r[0] = this.h0, r[1] = this.h1, r[2] = this.h2, r[3] = this.h3, t
}, Md5.prototype.buffer = Md5.prototype.arrayBuffer, Md5.prototype.base64 = function () {
for (var t, r, e, s = "", i = this.array(), o = 0; 15 > o;) t = i[o++], r = i[o++], e = i[o++], s += BASE64_ENCODE_CHAR[t >>> 2] + BASE64_ENCODE_CHAR[63 & (t << 4 | r >>> 4)] + BASE64_ENCODE_CHAR[63 & (r << 2 | e >>> 6)] + BASE64_ENCODE_CHAR[63 & e];
return t = i[o], s += BASE64_ENCODE_CHAR[t >>> 2] + BASE64_ENCODE_CHAR[t << 4 & 63] + "=="
};
var exports = createMethod();
COMMON_JS ? module.exports = exports : (root.md5 = exports, AMD && define(function () {
return exports
}))
}();

5 MD5 Utils加密

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//将查询出来的数据变成miaoshaUser
MiaoshaUser miaoshaUser = getById(Long.parseLong(form_mobile));

if (miaoshaUser == null) {
throw new GlobalException(CodeMsg.MOBILE_NOT_EXIST);
}
//如果用户存在
//1 验证密码
//数据库里面的密码 dbPassword b7797cce01b4b131b433b6acf4add 449
String dbPassword = miaoshaUser.getPassword();//Md5Utils.inputPassToDbPass()=dbPass
//数据库里面的盐值
String dbSalt = miaoshaUser.getSalt();
//经过计算得到的密码 原密码 123456 calcpass= d3b1294a61a07da9b49b6e22b2cbd7 f9
String calcPass = MD5Util.fromPassToDBPass(form_Password, dbSalt);
//==inputPassToDbPass=calcPass
if (!calcPass.equals(dbPassword)) {
throw new GlobalException(CodeMsg.PASSWORED_ERROR);
}
return true;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//验证密码
//数据库里面的密码 bPassword
String dbPassword = miaoshaUser.getPassword();
//数据库里面的盐值
String dbSalt = miaoshaUser.getSalt();
String calcPass = MD5Util.fromPassToDBPass(form_Password, dbSalt);
//d3b1294a61a07da9b49b6e22b2cbd7f9
System.err.println("============");
System.err.println(form_mobile + "form_mobile ajax md5加密的密码");
System.err.println(dbPassword + "dbPassword数据库里面的密码");
System.err.println(calcPass + "calcPass经过计算的密码 fromPassToDBPass(form_Password, dbSalt)");
System.err.println("inputPassToFormPass=" + "d3b1294a61a07da9b49b6e22b2cbd7f9");
System.err.println("fromPassToDBPass=" + "d3b1294a61a07da9b49b6e22b2cbd7f9");
System.err.println("inputPassToDbPass=" + "b7797cce01b4b131b433b6acf4add449");
System.err.println("============");

image-20190203101433598

image-20190203102816120

  • inputPassToFormPass(String input). Md5Utils===md5(str). Ajax
  • inputPassToDbPass(String input ,String saltDb) =====Md5Utils.fomPassDBPass(form_password),dbSalt);
  • 两次MD5封装 其本质是一样的。

6 JSR 303 校验

1dependency

1
2
3
4
5
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>2.0.6.RELEASE</version>
</dependency>

2 .@Valid

1
2
3
4
5
6
7
@RequestMapping("/do_login")
@ResponseBody
public Result doLogin(@Valid LoginVo loginVo) {
logger.info(loginVo.toString());
miaoShaoUserService.login(loginVo);
return Result.success(true);
}

3 POJO

1
2
3
4
5
6
7
8
public class LoginVo {

@NotNull
//自定义validator
@IsMobile
private String mobile;
@NotNull
@Length(min = 32)

4 自定义的 @IsMobile

image-20190203103632449


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.imooc.miaosha.validate;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.ElementType.TYPE_USE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {IsMobileValidator.class})
public @interface IsMobile {
boolean required() default true;
String message() default "手机号不正确~~ -,- ~~~~";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};

}
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.imooc.miaosha.validate;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.regex.Pattern;
//手机号码的validator校验
public class IsMobileValidator implements ConstraintValidator<IsMobile, String> {
private boolean required;
// 重写initialize方法获取注解实例
@Override
public void initialize(IsMobile ca) {
// 重注解实例中获信息
required = ca.required();
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
// value就是要校验的数据了
if (value != null && required) {
// 手机号校验规则
System.out.println(value);
String regexp = "^(((\\+\\d{2}-)?0\\d{2,3}-\\d{7,8})|((\\+\\d{2}-)?(\\d{2,3}-)?([1][3,4,5,7,8][0-9]\\d{8})))$";
boolean matches = Pattern.matches(regexp, value);
System.out.println(matches);
return matches;
}
return false;
}
}

image-20190203103753898

image-20190203103810510


7统一异常处理

image-20190203104404035

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
package com.imooc.miaosha.Exception;

import com.imooc.miaosha.result.CodeMsg;
import com.imooc.miaosha.result.Result;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

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

//定义全局异常处理器 Advice

@ControllerAdvice
@ResponseBody//返回JSON数据
public class GlobleExceptionHandler {
@ExceptionHandler(value = Exception.class)
public Result<String> exceptionHandler(HttpServletRequest httpServletRequest, Exception e) {
if (e instanceof BindException) {
BindException ex = (BindException) e;

List<ObjectError> allErrors = ex.getAllErrors();

ObjectError objectError = allErrors.get(0);

String defaultMessage = objectError.getDefaultMessage();

return Result.error(CodeMsg.BINDD_ERROR.fillArgs(defaultMessage));
} else {
return Result.error(CodeMsg.SERVER_ERROR);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
public class CodeMsg {
private int code;
private String msg;
//通用异常
public static CodeMsg BINDD_ERROR = new CodeMsg(50008, "参数绑定异常 :%s");
//⭐️ 不懂 不理解 查文档
public CodeMsg fillArgs(Object... args) {
int code = this.code;
String message = String.format(this.msg, args);
return new CodeMsg(code, message);
}

image-20190203111119493

思考🤔 参数绑定异常:手机号码不正确– –,— 哪来的

image-20190203111341776

image-20190203111444363

image-20190203111547120

image-20190203113041569

Ajax data的理解。 五角星⭐️

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$.ajax({
url: "/login/do_login",
type: "POST",
data: {
mobile: $("#mobile").val(),
password: password
},
success: function (data) {
layer.closeAll();
if (data.code === 0) {
layer.msg("成功 加油Boy");
} else {
layer.msg(data.msg);
layer.msg(data.data);
}
console.log(data);
},
error: function () {
layer.closeAll();
}
});

image-20190203115740299

这里面传入的 data.code data.msg data.data 应该就是注解@ResponseBody返回的JSON数

就是Conlse下Object的值 或者是全局异常 和统一异常返回响应的结果。 Return 语句返回的值

data.data的值不存在。 会报错。 layer.js:2 Uncaught TypeError: Cannot read property ‘parents’ of null

image-20190203132304123

image-20190203120017487

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24


ControllerAdvice用法解析
简介
  通过@ControllerAdvice注解可以将对于控制器的全局配置放在同一个位置。
  注解了@Controller的类的方法可以使用@ExceptionHandler@InitBinder@ModelAttribute注解到方法上。
  @ControllerAdvice注解将作用在所有注解了@RequestMapping的控制器的方法上
  @ExceptionHandler:用于全局处理控制器里的异常。

用法
@ControllerAdvice
@ResponseBody
public class BusinessExceptionHandler {
@ExceptionHandler(value = Exception.class)
public JsonBackData exceptionHandler(HttpServletRequest request, Exception e) {
e.printStackTrace();
JsonBackData back = new JsonBackData();
if (e instanceof BusinessException) {
BusinessException ex = (BusinessException) e;
back.setSuccess(false);
back.setBackMsg(ex.getMessage());
}
return back;
}

8.全局异常处理

1
2
3
4
public boolean login(LoginVo loginVo) {
if (loginVo == null) {
throw new GlobalException(CodeMsg.SERVER_ERROR);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.imooc.miaosha.Exception;
import com.imooc.miaosha.result.CodeMsg;
public class GlobalException extends RuntimeException {
private CodeMsg cm;
public GlobalException(CodeMsg cm) {
super(cm.toString());
this.cm = cm;
}
public CodeMsg getCm() {
return cm;
}
public void setCm(CodeMsg cm) {
this.cm = cm;
}
}
1
2
3
4
5
6
7
8
9
10
11
@ControllerAdvice
@ResponseBody
public class GlobleExceptionHandler {
@ExceptionHandler(value = Exception.class)
public Result<String> exceptionHandler(HttpServletRequest httpServletRequest, Exception e) {
if (e instanceof GlobalException) {
GlobalException ex = (GlobalException) e;
return Result.error(ex.getCm());
}
}
}

image-20190203114836279

image-20190203114852239

image-20190203114913217