『博客开发日记』之生成评论头像接口的实现

本文最后更新于 2026年2月10日 晚上

生成评论头像接口


生成评论头像接口需求

在评论框内输入邮箱时会显示头像

未输入邮箱时显示神秘人头像

邮箱格式错误时使用彩色几何图案

邮箱格式正确时返回邮箱对应的头像

代码实现

在CommentController类中新加generateAvatar接口方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

/**
* 生成评论头像(用于评论框预览)
* 规则:
* - 空邮箱:返回 d=mp(神秘人物轮廓)
* - 邮箱格式错误:返回 d=identicon(彩色几何图案)
* - 邮箱格式正确:返回对应邮箱的头像,默认使用 d=identicon
*
* @param params 包含email参数的Map
* @return 头像URL
*/
@PostMapping("/generateAvatar")
@SystemLog(businessName = "生成评论头像")
@ApiOperation(value = "生成评论头像", notes = "根据邮箱生成评论框预览头像")
public ResponseResult generateAvatar(@RequestBody Map<String, String> params)
{
String email = params.get("email");
return commentService.generateAvatar(email);
}

在CommentServiceImpl类中添加方法

1
2
3
4
5
6
7
8
9
10
11
12
13
//生成评论头像
@Override
public ResponseResult generateAvatar(String email)
{
// 使用工具类生成头像URL
String avatarUrl = GravatarUtils.getCommentPreviewAvatarUrl(email);

// 封装返回结果
java.util.Map<String, String> result = new java.util.HashMap<>();
result.put("avatar", avatarUrl);

return ResponseResult.okResult(result);
}

更新GravatarUtils类

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
/**
* 头像工具类
* 使用 Gravatar 生成头像
*/
public class GravatarUtils
{

// 使用国内可访问的 Gravatar 镜像
private static final String GRAVATAR_URL = "https://cravatar.cn/avatar/";
// 默认头像类型(mp: 神秘人, identicon: 几何图案, monsterid: 怪物, wavatar: 卡通脸, retro: 8位像素, robohash: 机器人)
private static final String DEFAULT_AVATAR = "mp";
// 评论区默认头像类型(彩色几何图案)
private static final String COMMENT_DEFAULT_AVATAR = "identicon";
// 默认头像大小
private static final int DEFAULT_SIZE = 80;

/**
* 根据邮箱生成头像 URL
* @param email 邮箱地址
* @return 头像 URL
*/
public static String getGravatarUrl(String email) {
return getGravatarUrl(email, DEFAULT_SIZE);
}

/**
* 根据邮箱生成指定大小的头像 URL
* @param email 邮箱地址
* @param size 头像大小
* @return 头像 URL
*/
public static String getGravatarUrl(String email, int size)
{
if (email == null || email.trim().isEmpty()) {
return GRAVATAR_URL + "00000000000000000000000000000000?d=" + DEFAULT_AVATAR + "&s=" + size;
}

String trimmedEmail = email.trim().toLowerCase();

// 统一使用 Gravatar(更稳定可靠)
String hash = md5Hex(trimmedEmail);
return GRAVATAR_URL + hash + "?d=" + DEFAULT_AVATAR + "&s=" + size;
}

/**
* 根据邮箱生成评论框预览头像 URL
* 规则:
* - 空邮箱:使用 mp(神秘人物轮廓)
* - 邮箱格式错误:使用 identicon(彩色几何图案)
* - 邮箱格式正确:使用 identicon 作为默认头像
*
* @param email 邮箱地址
* @return 头像 URL
*/
public static String getCommentPreviewAvatarUrl(String email)
{
return getCommentPreviewAvatarUrl(email, DEFAULT_SIZE);
}

/**
* 根据邮箱生成评论框预览头像 URL
* @param email 邮箱地址
* @param size 头像大小
* @return 头像 URL
*/
public static String getCommentPreviewAvatarUrl(String email, int size)
{
// 空邮箱:使用 mp(神秘人物轮廓)
if (email == null || email.trim().isEmpty()) {
return GRAVATAR_URL + "00000000000000000000000000000000?d=" + DEFAULT_AVATAR + "&s=" + size;
}

String trimmedEmail = email.trim().toLowerCase();

// 验证邮箱格式
if (!isValidEmail(trimmedEmail)) {
// 邮箱格式错误:使用 identicon(彩色几何图案)
return GRAVATAR_URL + "00000000000000000000000000000000?d=" + COMMENT_DEFAULT_AVATAR + "&s=" + size;
}

// 邮箱格式正确:使用 identicon 作为默认头像
String hash = md5Hex(trimmedEmail);
return GRAVATAR_URL + hash + "?d=" + COMMENT_DEFAULT_AVATAR + "&s=" + size;
}

/**
* 验证邮箱格式
* @param email 邮箱地址
* @return 是否为有效邮箱
*/
private static boolean isValidEmail(String email) {
if (email == null || email.isEmpty()) {
return false;
}
// 简单的邮箱格式验证
String emailRegex = "^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$";
return email.matches(emailRegex);
}

/**
* 计算字符串的 MD5 哈希值
* @param input 输入字符串
* @return MD5 哈希值(小写十六进制)
*/
private static String md5Hex(String input) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(input.getBytes());
StringBuilder sb = new StringBuilder();
for (byte b : digest) {
sb.append(String.format("%02x", b));
}
return sb.toString();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("MD5 algorithm not found", e);
}
}
}




『博客开发日记』之生成评论头像接口的实现
http://example.com/2026/02/10/『博客开发日记』之生成评论头像接口的实现/
作者
云梦泽
发布于
2026年2月10日
更新于
2026年2月10日
许可协议