{"id":960,"date":"2025-04-21T21:30:19","date_gmt":"2025-04-21T13:30:19","guid":{"rendered":"https:\/\/eve2333.top\/?p=960"},"modified":"2025-04-21T21:30:19","modified_gmt":"2025-04-21T13:30:19","slug":"%e9%bb%91%e9%a9%ac%e7%82%b9%e8%af%84redis%e6%94%b9-part-1","status":"publish","type":"post","link":"https:\/\/eve2333.top\/?p=960","title":{"rendered":"\u9ed1\u9a6c\u70b9\u8bc4redis\u6539 part 1"},"content":{"rendered":"\n<p>\u00a0<img loading=\"lazy\" decoding=\"async\" height=\"387\" width=\"682\" src=\"https:\/\/i-blog.csdnimg.cn\/direct\/c0a3cf82996743a5884684c608ba1f6c.png\" alt=\"\"><\/p>\n\n\n\n<p>&nbsp;\u672c\u7bc7\u5c06\u4e3b\u8981\u9610\u8ff0\u77ed\u4fe1\u767b\u5f55\u7684\u76f8\u5173\u77e5\u8bc6\uff0c\u611f\u8c22\u9ed1\u9a6c\u7a0b\u5e8f\u5458\u5f00\u6e90\uff0c\u611f\u8c22\u63d0\u4f9b\u521d\u59cb\u6e90\u6587\u4ef6\uff08\u7ed9\u5230\u7684\u662f\u5b9e\u6218\u7b2c7\u96c6\u5f00\u59cb\u7684\u4ee3\u7801\uff09<a href=\"https:\/\/blog.csdn.net\/weixin_52152676\/article\/details\/144680041\" target=\"_blank\"  rel=\"nofollow\" >\u3010Redis\u5b9e\u6218\u7bc7\u3011\u9ed1\u9a6c\u70b9\u8bc4\u5b66\u4e60\u7b14\u8bb0\uff0816\u4e07\u5b57\u8d85\u8be6\u7ec6\u3001Redis\u5b9e\u6218\u9879\u76ee\u5b66\u4e60\u5fc5\u770b\u3001\u6b22\u8fce\u70b9\u8d5e\u2b50\u6536\u85cf\uff09-CSDN\u535a\u5ba2<\/a><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1.\u6253\u5f00localhost_3306,\u9009\u4e2d\u53f3\u51fb\u201c\u65b0\u5efa\u6570\u636e\u5e93\u201d<\/h3>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"353\" width=\"478\" src=\"https:\/\/i-blog.csdnimg.cn\/blog_migrate\/60e33a2ab08af161fb59d24ddbc7214e.png\" alt=\"\u5728\u8fd9\u91cc\u63d2\u5165\u56fe\u7247\u63cf\u8ff0\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><a><\/a>2.\u6307\u5b9a\u6570\u636e\u5e93\u540d\u548c\u5b57\u7b26\u96c6\uff08\u53ef\u6839\u636esql\u6587\u4ef6\u7684\u5b57\u7b26\u96c6\u7c7b\u578b\u81ea\u884c\u9009\u62e9\uff09<\/h3>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"331\" width=\"375\" src=\"https:\/\/i-blog.csdnimg.cn\/blog_migrate\/c7a02465ee9282c444c6e80df2620f61.png\" alt=\"\u5728\u8fd9\u91cc\u63d2\u5165\u56fe\u7247\u63cf\u8ff0\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><a><\/a>3.\u9009\u4e2d\u6570\u636e\u5e93\u4e0b\u7684\u8868\u8fd0\u884cSQL\u6587\u4ef6<\/h3>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"201\" width=\"235\" src=\"https:\/\/i-blog.csdnimg.cn\/blog_migrate\/cb961f8a0e41edc797b3e704224bfe0c.png\" alt=\"\u5728\u8fd9\u91cc\u63d2\u5165\u56fe\u7247\u63cf\u8ff0\">\u5176\u5b9e\u6211\u60f3\u53d1\u5728\u8fd9\u91cc\u7684\uff0c\u4f46\u662f1285\u884c\u4ee3\u7801\u592a\u591a\u4e86<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><a><\/a>4.\u9009\u4e2d\u8def\u5f84\u5bfc\u5165<\/h3>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"285\" width=\"327\" src=\"https:\/\/i-blog.csdnimg.cn\/blog_migrate\/f5ba725102e723df474bab00ab4bf80f.png\" alt=\"\u5728\u8fd9\u91cc\u63d2\u5165\u56fe\u7247\u63cf\u8ff0\"><\/p>\n\n\n\n<p>&nbsp;\u5c06hmdp.sql\u5bfc\u5165\uff08\u672c\u4eba\u662fmysql8.0.32\u7248\u672c\uff09\uff0c\u5373\u53ef\u770b\u5230\u5305\u62ectb_user:\u7528\u6237\u8868\uff0ctb_user_info\uff1a\u7528\u6237\u8be6\u60c5\u8868\uff0ctb_shop\uff1a\u5546\u6237\u4fe1\u606f\u8868\uff0ctb_shop_type:\u5546\u6237\u7c7b\u578b\u8868\uff0ctb_blog\uff1a\u7528\u6237\u65e5\u8bb0\u8868\uff08\u8fbe\u4eba\u63a2\u5e97\u65e5\u8bb0\uff09\uff0ctb_follow\uff1a\u7528\u6237\u5173\u6ce8\u8868\uff0ctb_voucher:\u4f18\u60e0\u5238\u8868\uff0ctb_voucher_order:\u4f18\u60e0\u5238\u7684\u8ba2\u5355\u8868 \u7684\u4e00\u517111\u4e2a\u8868&nbsp;<\/p>\n\n\n\n<p>\u5728\u8d44\u6599\u4e2d\u63d0\u4f9b\u4e86\u4e00\u4e2a\u9879\u76ee\u6e90\u7801\uff0chm-dianping\uff0c\u5927\u6982\u770b\u4e00\u4e0b\uff0c\u7ecf\u5178\u7684ssm\uff0c\u4e00\u773cspringboot\u3002\u4fee\u6539application.yaml\u90e8\u5206\uff0c\u5bf9\u7167\u81ea\u5df1 \u7684\u5373\u53ef<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>server:\n  port: 8081\nspring:\n  application:\n    name: hmdp\n  datasource:\n    driver-class-name: com.mysql.jdbc.Driver\n    url: jdbc:mysql:\/\/localhost:3306\/hmdp?useSSL=false&amp;serverTimezone=UTC\n    username: root\n    password: root\n  redis:\n    host: 192.168.169.133\n    port: 6379\n    password: 123321\n    lettuce:\n      pool:\n        max-active: 10\n        max-idle: 10\n        min-idle: 1\n        time-between-eviction-runs: 10s\n  jackson:\n    default-property-inclusion: non_null # JSON\u5904\u7406\u65f6\u5ffd\u7565\u975e\u7a7a\u5b57\u6bb5\nmybatis-plus:\n  type-aliases-package: com.hmdp.entity # \u522b\u540d\u626b\u63cf\u5305\nlogging:\n  level:\n    com.hmdp: debug\n<\/code><\/pre>\n\n\n\n<p><s>&nbsp;RedissonConfig\u4e2d\u4e5f\u6709redis\u7684\u5730\u5740\u9700\u8981\u4fee\u6539\uff08\u9519\u8bef\u7684\uff0c\u6211\u8bef\u6253\u5f00\u7684\u5b8c\u6574\u7248\u4ee3\u7801\uff09<\/s><\/p>\n\n\n\n<p>\u4fee\u6539pom\u4e2d\u4f60\u7684java\u7248\u672c\u548cmysql\u7248\u672c\uff08java\u7248\u672c\u4e0d\u5efa\u8bae\u592a\u65b0\u672c\u4eba\u7528\u7684jdk13\uff0c\u8001\u5e08\u7528\u7956\u4f201.8\uff0c\u56e0\u4e3a\u68c0\u67e5 <code>JCImport<\/code> \u7684\u6e90\u7801\uff08\u6216\u53cd\u7f16\u8bd1\uff09\u786e\u8ba4\u5b57\u6bb5\u540d\uff1aJDK 8\uff1a\u5b57\u6bb5\u4e3a <code>qualid<\/code>\u3002JDK 13+\uff1a\u5b57\u6bb5\u53ef\u80fd\u6539\u4e3a <code>pid<\/code>\u3002\u5417\u4e0d\u8fc7java\u4ece11\u5f00\u59cb\u5230\u5927\u698217\u57fa\u672c\u4e0a\u6ca1\u6709\u4ec0\u4e48\u5927\u53d8\u5316\uff0c\u6211\u731c\u5e94\u8be5\u90fd\u53ef\u4ee5\u5427\uff0c\u4e0d\u8fc7jdk23\u80af\u5b9a\u4e0d\u884c\uff09&nbsp;<\/p>\n\n\n\n<p>alt+8\u6253\u5f00service\uff0c\u6dfb\u52a0 \u201c\u8fd0\u884c\u914d\u7f6e\u7c7b\u578b\u201d springboot\u3002\u6210\u529f\u8fd0\u884c\uff01<img loading=\"lazy\" decoding=\"async\" height=\"163\" width=\"682\" src=\"https:\/\/i-blog.csdnimg.cn\/direct\/74743d0e947042d6a263d709b8685c7e.png\" alt=\"\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u8fd0\u884c\u524d\u7aef\u9879\u76ee<\/h3>\n\n\n\n<p>\u5728nginx\u6240\u5728\u76ee\u5f55\u4e0b\u6253\u5f00\u4e00\u4e2acmd\u7a97\u53e3<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>start nginx.exe<\/code><\/pre>\n\n\n\n<p>\u6253\u5f00\u6d4f\u89c8\u5668\u7684\u624b\u673a\u6a21\u5f0f\u548c\u672c\u5730\u76848080\u7aef\u53e3\u5373\u53ef<\/p>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"768\" width=\"679\" src=\"https:\/\/i-blog.csdnimg.cn\/direct\/c0dce912312c463aa909f6ae4eca17d5.png\" alt=\"\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u57fa\u4e8esession\u5b9e\u73b0\u767b\u5f55<\/h3>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"306\" width=\"677\" src=\"https:\/\/i-blog.csdnimg.cn\/direct\/613be9b3c3af4e1b92adfa6c22d911c5.png\" alt=\"\"><\/p>\n\n\n\n<p>\u00a0\u6211\u4eec\u5728<a href=\"http:\/\/localhost:8080\/login.html\" target=\"_blank\"  rel=\"nofollow\" >http:\/\/localhost:8080\/login.html<\/a>\u8f93\u5165\u4e00\u4e2a\u5408\u6cd5\u7684\u624b\u673a\u53f7\u7801\u53ef\u4ee5\u770b\u5230\u4e00\u4e2a<br>\u5df2\u5b8c\u6210\u52a0\u8f7d:POST \"http:\/\/localhost:8080\/api\/user\/code?phone=16883577632\"\u3002\u00a0\u8bf7\u6c42\u53d1\u5230api\u7684user<img loading=\"lazy\" decoding=\"async\" height=\"72\" width=\"1214\" src=\"https:\/\/i-blog.csdnimg.cn\/direct\/9036a423f64d48918d4b58b3d7725c01.png\" alt=\"\"><\/p>\n\n\n\n<p>\u8bf7\u6c42\u65b9\u5f0fPOST\uff0c\u8bf7\u6c42\u8def\u5f84\/user\/code\uff0c\u8bf7\u6c42\u53c2\u6570phone\u3001\u7535\u8bdd\u53f7\u7801\uff0c\u8fd4\u56de\u503c\u65e0&nbsp;<\/p>\n\n\n\n<p>\u6211\u4eec\u8981\u6253\u5f00UserController\uff0c\u5b9e\u73b0\u53d1\u9001\u624b\u673a\u9a8c\u8bc1\u7801\u7684\u529f\u80fd\uff0c\u7531\u4e8e\u4e2d\u56fd\u5927\u9646\u7684\u624b\u673a\u53f7\u653f\u7b56\uff0c\u5b9e\u9645\u4e0a\u4f60\u53ef\u4ee5\u6539\u4e3a\u90ae\u7bb1\u9a8c\u8bc1\uff0c\u6bd5\u7adf\u53ea\u662f\u4e00\u4e2a\u7b80\u5355demo\u800c\u5df2\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@PostMapping(\"code\")\npublic Result sendCode(@RequestParam(\"phone\") String phone, HttpSession session) {\n    \/\/ \u53d1\u9001\u77ed\u4fe1\u9a8c\u8bc1\u7801\u5e76\u4fdd\u5b58\u9a8c\u8bc1\u7801\n    return userService.sendCode(phone, session);\n}<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.hmdp.service.impl;\n\nimport cn.hutool.core.util.RandomUtil;\nimport com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;\nimport com.hmdp.dto.Result;\nimport com.hmdp.entity.User;\nimport com.hmdp.mapper.UserMapper;\nimport com.hmdp.service.IUserService;\nimport com.hmdp.utils.RegexUtils;\nimport lombok.extern.slf4j.Slf4j;\nimport org.springframework.stereotype.Service;\n\nimport javax.servlet.http.HttpSession;\n\n\/**\n * &lt;p&gt;\n * \u670d\u52a1\u5b9e\u73b0\u7c7b\n * &lt;\/p&gt;\n *\n * @author \u864e\u54e5\n * @since 2021-12-22\n *\/\n@Service\n@Slf4j \/\/log.debug\u62a5\u9519\u7684\u52a0@Sl4j\u6ce8\u89e3\npublic class UserServiceImpl extends ServiceImpl&lt;UserMapper, User&gt; implements IUserService {\n    @Override\n    public Result sendCode(String phone, HttpSession session) {\n        \/\/ 1.\u6821\u9a8c\u624b\u673a\u53f7\n        if (RegexUtils.isPhoneInvalid(phone)) {\n            \/\/ 2.\u5982\u679c\u4e0d\u7b26\u5408\uff0c\u8fd4\u56de\u9519\u8bef\u4fe1\u606f\n            return Result.fail(\"\u624b\u673a\u53f7\u683c\u5f0f\u9519\u8bef\uff01\");\n        }\n        \/\/ 3.\u7b26\u5408\uff0c\u751f\u6210\u9a8c\u8bc1\u7801\n        String code = RandomUtil.randomNumbers(6);\n\n        \/\/ 4.\u4fdd\u5b58\u9a8c\u8bc1\u7801\u5230 session \/\/\u8fd9\u91cc\u63a8\u8350\u4f7f\u7528\u624b\u673a\u53f7\u4f5c\u4e3akey\uff0c\u9a8c\u8bc1\u7801\u4f5c\u4e3a\u503c\n        session.setAttribute(\"code\",code);\n\n        \/\/ 5.\u53d1\u9001\u9a8c\u8bc1\u7801,\u901a\u8fc7aliyun\u90a3\u4e9b\u77ed\u4fe1\u5e73\u53f0\u5b9e\u73b0\n        log.debug(\"\u53d1\u9001\u77ed\u4fe1\u9a8c\u8bc1\u7801\u6210\u529f\uff0c\u9a8c\u8bc1\u7801\uff1a{}\", code);\n        \/\/ \u8fd4\u56deok\n        return Result.ok();\n    }\n}\n<\/code><\/pre>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"42\" width=\"380\" src=\"https:\/\/i-blog.csdnimg.cn\/direct\/c3ccfd45c314442482d563fab31087e1.png\" alt=\"\">\u8fd9\u65f6\u540e\u53f0\u53ef\u4ee5\u76f4\u63a5\u770b\u5230\u53d1\u9001\u77ed\u4fe1\u9a8c\u8bc1\u7801\u6210\u529f\uff0c\u9a8c\u8bc1\u7801245333<\/p>\n\n\n\n<p>\u6211\u4eec\u4ed4\u7ec6\u770blogin\u529f\u80fd\uff0c\u524d\u7aef\u53d1\u9001\u7684\u662fjson\u683c\u5f0f\uff0c\u6240\u4ee5\u9700\u8981RequestBody\u89e3\u6790\u4e0b\uff0cloginFormDTO\u683c\u5f0f\u91cc\u9762\u5305\u62ec\u4e09\u4e2a\u8981\u7d20\uff0c\u63a5\u4e0b\u6765\u8fdb\u4e00\u6b65\u5b8c\u5584controller<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@PostMapping(\"\/login\")\npublic Result login(@RequestBody LoginFormDTO loginForm, HttpSession session){\n    \/\/ \u5b9e\u73b0\u767b\u5f55\u529f\u80fd\n    return userService.login(loginForm, session);\n}<\/code><\/pre>\n\n\n\n<p>UserServiceImpl.java\u4fee\u6539\u5982\u4e0b\uff0c\u8fd9\u91cc\u6709\u5b9e\u9645\u4e0a\u6709\u4e00\u4e2a\u5c0f\u4fdd\u9669\uff0c\u53d1\u9001\u9a8c\u8bc1\u7801\u65f6\u5e94\u8be5\u5c06\u624b\u673a\u53f7\u4fdd\u5b58\u5728session\u4e2d\uff0c\u5728\u767b\u5f55\u65f6\u9a8c\u8bc1\u662f\u5426\u5f53\u524d\u624b\u673a\u53f7\u662f\u5426\u662f\u53d1\u9001\u9a8c\u8bc1\u7801\u7684\u624b\u673a\u53f7\uff0c\u5426\u5219\u5148\u7528\u81ea\u5df1\u624b\u673a\u53f7\u53d1\u9001\u9a8c\u8bc1\u7801\uff0c\u518d\u7528\u522b\u4eba\u624b\u673a\u53f7\u767b\u5f55\u3002\u603b\u4e4b\u5c31\u662f<strong>\u767b\u5f55\u9700\u8981\u6821\u9a8c\u6b64\u624b\u673a\u53f7\u548c\u53d1\u9001\u9a8c\u8bc1\u7801\u7684\u624b\u673a\u53f7\u662f\u540c\u4e00\u4e2a,&nbsp;<\/strong>\u4f60\u4e50\u610f\u7684\u8bdd\u53ef\u4ee5\u52a0\u4e2aip\u5730\u5740\u6821\u9a8c\u4e0d\u8fc7\u4e0d\u592a\u597d\u4f7f\u5524<\/p>\n\n\n\n<p>\u6570\u636e\u5e93\u5728\u4e2dtb_user\u4e2d\u6709nick_name\u5b57\u6bb5,\u624b\u673a\u53f7\u4ec0\u4e48\u7684,\u8fd9\u91cc\u7528lambdaquery\u7684\u670b\u53cb\u6ce8\u610f\u4e86\uff0cmp\u7248\u672c\u89813.5\uff0c\u7528\u8001\u5e08\u7684\u8fd9\u4e2a\u7248\u672c\u67e5\u8be2\u4e3a\u7a7a\u7684\u65f6\u5019\u4f1a\u62a5\u9519<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    @Override\n    public Result login(LoginFormDTO loginForm, HttpSession session) {\n        \/\/ 1.\u6821\u9a8c\u624b\u673a\u53f7\n        String phone = loginForm.getPhone();\n        if (RegexUtils.isPhoneInvalid(phone)) {\n            \/\/ 2.\u5982\u679c\u4e0d\u7b26\u5408\uff0c\u8fd4\u56de\u9519\u8bef\u4fe1\u606f\n            return Result.fail(\"\u624b\u673a\u53f7\u683c\u5f0f\u9519\u8bef\uff01\");\n        }\n        \/\/ 2.\u4eceredis\u83b7\u53d6\u9a8c\u8bc1\u7801\u5e76\u6821\u9a8c\n        Object cacheCode = session.getAttribute(\"code\");\n        String code = loginForm.getCode();\n        if (cacheCode == null || !cacheCode.equals(code)) {\n            \/\/ 3. \u4e0d\u4e00\u81f4\uff0c\u62a5\u9519\n            return Result.fail(\"\u9a8c\u8bc1\u7801\u9519\u8bef\");\n        }\n\n        \/\/ 4.\u4e00\u81f4\uff0c\u6839\u636e\u624b\u673a\u53f7\u67e5\u8be2\u7528\u6237 select * from tb_user where phone = ?\n        User user = query().eq(\"phone\", phone).one();\n\n        \/\/ 5.\u5224\u65ad\u7528\u6237\u662f\u5426\u5b58\u5728\n        if (user == null) {\n            \/\/ 6.\u4e0d\u5b58\u5728\uff0c\u521b\u5efa\u65b0\u7528\u6237\u5e76\u4fdd\u5b58\n            user = createUserWithPhone(phone);\n        }\n\n        session.setAttribute(\"user\",user);\n        return Result.ok();\/\/\u5b9e\u9645\u4e0a\u53ea\u9700\u8981return null,session\u5c31\u76f4\u63a5\u5199\u5230\u4f60\u7684cookie\u4e2d\u4e86\n    }\n\n\n    private User createUserWithPhone(String phone) {\n        \/\/ 1.\u521b\u5efa\u7528\u6237\n        User user = new User();\n        user.setPhone(phone);\n        user.setNickName(USER_NICK_NAME_PREFIX + RandomUtil.randomString(10));\n        \/\/ 2.\u4fdd\u5b58\u7528\u6237\n        save(user);\n        return user;\n    }<\/code><\/pre>\n\n\n\n<p>\u8fd9\u662fmybatisplus\u5728service\u7684\u65b9\u6cd5\uff0c \u4e0d\u7528\u53bb\u521d\u59cb\u5316mapper<\/p>\n\n\n\n<p>\u6211\u4eec\u5728\u524d\u7aef,\u767b\u5f55\u540e\u53ef\u4ee5\u8df3\u8f6c\u4e00\u4e0b,\u4f46\u662f\u6ca1\u6709\u505a\u767b\u5f55\u6821\u9a8c\u529f\u80fd,\u4f60\u5728\u6570\u636e\u5e93\u53ef\u4ee5\u67e5\u627e\u5230\u5bf9\u5e94\u7684\u6570\u636e<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u767b\u9646\u9a8c\u8bc1\u529f\u80fd<\/h3>\n\n\n\n<p>\u4e8b\u5b9e\u4e0a\u7684\u767b\u5f55\u9a8c\u8bc1\u5462\u5c31\u662f\u8fd9\u6837\u7684\u4e00\u4e2a\u8bf7\u6c42,\u8fd9\u4e2auserme\u67e5\u8be2\u5f53\u524d\u6240\u5728\u7684\u7528\u6237\u4fe1\u606f,\u5982\u679c\u4f60\u80fdreturn,\u90a3\u4e48\u5c31\u6210\u529f\u4e86.\u4f46\u662f\u8fd9\u91cc\u6709\u70b9\u95ee\u9898\uff0c\u6211\u4eec\u5728\u9ed1\u9a6c\u70b9\u8bc4\u91cc\u9762\u6709\u5f88\u591a\u5f88\u591acontrol\uff0c\u5176\u4e2d\u521a\u624d\u8bb2\u90a3\u4e2auserme\u767b\u5f55\u6821\u9a8c\u5c5e\u4e8eusercontrol\uff0c\u524d\u7aef\u5411usercontrol\u53d1\u8bf7\u6c42\uff0c\u91cc\u9762\u7f16\u5199\u8fd9\u4e00\u5806\u7684\u4e1a\u52a1\u903b\u8f91\u3002\u4f46\u662f\u5462\u540e\u7eed\u968f\u7740\u4e1a\u52a1\u7684\u5f00\u53d1\uff0c\u8d8a\u6765\u8d8a\u591a\u7684\u4e1a\u52a1\u90fd\u9700\u8981\u53bb\u6821\u9a8c\u7528\u6237\u7684\u767b\u5f55\uff0c\u663e\u7136\u4e0d\u80fd\u5199\u4e00\u5806control\u3002\u8fd9\u4e5f\u662f\u62e6\u622a\u5668\u7684\u7531\u6765\uff0c\u6240\u6709\u8bf7\u6c42\u554a\u90fd\u5fc5\u987b\u5148\u7ecf\u8fc7\u62e6\u622a\u5668\uff0c\u518d\u7531\u62e6\u622a\u5668\u5224\u65ad\u8be5\u4e0d\u8be5\u653e\u884c\u5230\u8fbecontrol<\/p>\n\n\n\n<p>\u62e6\u622a\u5668\u786e\u5b9e\u53ef\u4ee5\u5e2e\u52a9&nbsp;\u6211\u4eec\u5b9e\u73b0\u5bf9\u7528\u6237\u767b\u5f55\u7684\u6821\u9a8c\uff0c\u5728\u5176\u4ed6\u4e1a\u52a1\u4e2d\u4eba\u5bb6\u662f\u9700\u8981\u8fd9\u4e2a\u7528\u6237\u4fe1\u606f\u7684\uff0c\u6821\u9a8c\u8fd9\u662f\u62ff\u5230\u4e86\uff0c\u6240\u4ee5\u9700\u8981\u628a\u8fd9\u4e2a\u62e6\u622a\u5668\u91cc\u62e6\u622a\u5f97\u5230\u7684\u7528\u6237\u4fe1\u606f\u4f20\u9012\u5230control\u91cc\u9762\u53bb\u3002\u800c\u4e14\u5728\u4f20\u9012\u7684\u8fc7\u7a0b\u4e2d\u9700\u8981\u6ce8\u610fslocal\u89e3\u51b3\u7ebf\u7a0b\u7684\u5b89\u5168\u95ee\u9898\uff0c\u62e6\u622a\u5668\u62e6\u622a\u4fe1\u606f\u540e\u4fdd\u5b58\u5728slocal\uff08\u7ebf\u7a0b\u5e8f\u5bf9\u8c61\uff09\u6bcf\u4e00\u4e2a\u8fdb\u5165tomcat\u7684\u8bf7\u6c42\u90fd\u662f\u4e00\u4e2a\u72ec\u7acb\u7684\u7ebf\u7a0b\uff0cslocal\u5728\u6bcf\u4e2a\u7ebf\u7a0b\u5185\u5f00\u8f9f\u4e00\u4e2a\u5185\u5b58\u7684\u7a7a\u95f4\u4fdd\u5b58\u5bf9\u5e94\u7684\u7528\u6237\uff0c\u6bcf\u4e2a\u7ebf\u7a0b\u4e92\u4e0d\u5e72\u6270\u3002<\/p>\n\n\n\n<p>\u53ef\u80fd\u662f\u653e\u5728Session\u91cc\u4f60\u8981\u7528\u7684\u8bdd\uff0c\u8fd9\u4e2asession\u53c2\u6570\u4f60\u8981\u4e00\u76f4\u4f20\u4e0b\u53bb\uff0cThreadLocal\u8c03\u7528\u4e00\u4e2aAPI\u5c31\u80fd\u5b9e\u73b0\u4f60\u8bf4\u54ea\u4e2a\u597d\uff1f<\/p>\n\n\n\n<p>\u62e6\u622a\u5668\u53ef\u4ee5\u5199\u5728utils\u91cc\u9762\uff0c\u53eb\u505aLoginInterceptor.java<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.hmdp.utils;\n\nimport com.hmdp.entity.User;\nimport org.springframework.web.servlet.HandlerInterceptor;\n\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\nimport javax.servlet.http.HttpSession;\n\npublic class LoginInterceptor implements HandlerInterceptor {\n    @Override\n    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {\n        \/\/1.\u83b7\u53d6session\n        HttpSession session= request.getSession();\n        \/\/2.\u83b7\u53d6session\u4e2d\u7684\u7528\u6237\n        Object user = session.getAttribute(\"user\");\n        \/\/3.\u5224\u65ad\u7528\u6237\u662f\u5426\u5b58\u5728\n        if (user == null){\n            \/\/4.\u4e0d\u5b58\u5728\uff0c\u62e6\u622a\uff0c\u8fd4\u56de401\u72b6\u6001\u7801\n            response.setStatus(401);\n            return false;\n        }\n        \/\/5.\u5b58\u5728\uff0c\u4fdd\u5b58\u7528\u6237\u4fe1\u606f\u5230ThreadLocal\n        UserHolder.saveUser((User) user);\n        \/\/6.\u653e\u884c\n        return true;\n    }\n    @Override\n    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {\n        UserHolder.removeUser();\n    }\n\n}\n<\/code><\/pre>\n\n\n\n<p>&nbsp;\u8fd9\u91ccuserholder\uff0c\u89c6\u9891\u662fuser\uff0c\u800c\u7ed9\u7684\u6e90\u7801\u662fuserdto\uff0c\u6211\u8ba4\u4e3aextend\u4e00\u4e0b\u5373\u53ef<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">public class User extends UserDTO implements Serializable{<\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>\u56e0\u4e3aThreadLocal\u5e95\u5c42\u662fThreadLocalMap\uff0c\u5f53\u671f\u7ebf\u7a0bThreadlocal\u4f5c\u4e3akey(\u5f31\u5f15\u7528)\uff0cuser\u4f5c\u4e3avalue(\u5f3a\u5f15\u7528)&nbsp;\u8fd9\u91cc\u6d89\u53ca\u5230\u4e86ThreadLocal\u7684\u76f8\u5173\u77e5\u8bc6\uff0c\u4e0d\u61c2\u4e3a\u5565\u8981\u79fb\u9664\uff0c\u907f\u514d\u5185\u5b58\u6cc4\u6f0f\u7684\uff0c\u5efa\u8bae\u67e5\u8be2\u8d44\u6599<\/p>\n\n\n\n<p>ThreadLocal\u7ef4\u62a4\u4e86\u4e00\u4e2aThreadLocalMap\uff0c\u5728map\u4e2d\u7684Entry\u7ee7\u627f\u4e86WeakReference\uff0c\u5176\u4e2dkey\u4e3a\u4f7f\u7528\u4e86\u5f31\u5f15\u7528\u7684ThreadLocal\u5b9e\u4f8b\uff0c\u6ce8\u610f\u8fd9\u91cc\u4ed6\u53d1\u7ed9\u6211\u4eec\u7684\u662fUserDTO\u6211\u4eec\u9700\u8981\u521b\u5efa\u4e00\u4e2aDTO\u5bf9\u8c61\uff08\u8be6\u89c1userholder\uff09\u7136\u540e\u8fdb\u884c\u5c5e\u6027\u62f7\u8d1d\u3001\u4e0d\u53ef\u4ee5\u76f4\u63a5\u5f3a\u8f6c\u4e0d\u7136\u4f1a\u62a5\u53ef\u80fd\u4e3a\u7a7a\u7684\u9519\uff1b\u79fb\u9664\u7528\u6237\u662f\u56e0\u4e3a\uff1a\u56e0\u4e3aThreadLocal\u5bf9\u5e94\u7684\u662f\u4e00\u4e2a\u7ebf\u7a0b\u7684\u6570\u636e\uff0c\u6bcf\u6b21http\u8bf7\u6c42\uff0ctomcat\u90fd\u4f1a\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u7ebf\u7a0b\uff0c\u4e5f\u5c31\u662f\u8bf4\uff0c\u5f53\u524d\u7684ThreadLocal\u53ea\u5728\u5f53\u524d\u7684\u7ebf\u7a0b\u4e2d\u6709\u7528\uff1bjvm\u4e0d\u4f1a\u628a\u5f3a\u5f15\u7528\u7684value\u56de\u6536\u6389\uff0c\u6240\u4ee5value\u6ca1\u88ab\u91ca\u653e\uff1b<\/p>\n\n\n\n<p>&nbsp;\u603b\u4e4b\u79fb\u9664\u7528\u6237\u662f\u56e0\u4e3a\uff1a\u56e0\u4e3aThreadLocal\u5bf9\u5e94\u7684\u662f\u4e00\u4e2a\u7ebf\u7a0b\u7684\u6570\u636e\uff0c\u6bcf\u6b21http\u8bf7\u6c42\uff0ctomcat\u90fd\u4f1a\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u7ebf\u7a0b\uff0c\u4e5f\u5c31\u662f\u8bf4\uff0c\u5f53\u524d\u7684ThreadLocal\u53ea\u5728\u5f53\u524d\u7684\u7ebf\u7a0b\u4e2d\u6709\u7528<\/p>\n<\/blockquote>\n\n\n\n<p>&nbsp;\u8981\u60f3\u8ba9\u62e6\u622a\u5668\u751f\u6548\u8fd8\u8981\u914d\u7f6e\u62e6\u622a\u5668\uff0c\u5728config\u4e2d\u65b0\u5efa\u6587\u4ef6MvcConfig\uff0c\u53bb\u6389code.login\u7b49\u7b49\u7b49\u7b49<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.hmdp.config;\n\nimport com.hmdp.utils.LoginInterceptor;\n\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.data.redis.core.StringRedisTemplate;\nimport org.springframework.web.servlet.config.annotation.InterceptorRegistry;\nimport org.springframework.web.servlet.config.annotation.WebMvcConfigurer;\n\nimport javax.annotation.Resource;\n\n@Configuration\npublic class MvcConfig implements WebMvcConfigurer {\n\n    @Override\n    public void addInterceptors(InterceptorRegistry registry) {\n        \/\/ \u767b\u5f55\u62e6\u622a\u5668\n        registry.addInterceptor(new LoginInterceptor())\n                .excludePathPatterns(\n                        \"\/shop\/**\",\n                        \"\/voucher\/**\",\n                        \"\/shop-type\/**\",\n                        \"\/upload\/**\",\n                        \"\/blog\/hot\",\n                        \"\/user\/code\",\n                        \"\/user\/login\"\n                );\n    }\n}\n<\/code><\/pre>\n\n\n\n<p>\u505a\u767b\u5f55\u6821\u9a8c\u7528\u5230\u90a3\u4e2a\u53ebuser\/me\u7684\u4e00\u4e2a\u63a5\u53e3\uff0c\u8fd9\u4e2a\u63a5\u53e3\u6700\u7ec8\u8fd8\u9700\u8981\u628a\u5f53\u524d\u767b\u5f55\u7684\u7528\u6237\u4fe1\u606f\u8fd4\u56de\u5230\u524d\u7aef\uff0c\u62e6\u622a\u5668\u5df2\u7ecf\u628a\u7528\u6237\u653e\u5230\u4e86userholder\u91cc\u9762\u53bb\u4e86\uff0c\u6240\u4ee5\u53ea\u9700\u8981userholder.get\u5373\u53ef\u4e86<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    @GetMapping(\"\/me\")\n    public Result me(){\n        \/\/ \u83b7\u53d6\u5f53\u524d\u767b\u5f55\u7684\u7528\u6237\u5e76\u8fd4\u56de\n        UserDTO user = UserHolder.getUser();\n        return Result.ok(user);\n    }\n<\/code><\/pre>\n\n\n\n<p>\u73b0\u5728\u53ef\u80fd\u4f1a\u51fabug\uff0c\u7ee7\u7eed\u505a\u4e0b\u4e00\u96c6\u5c31ok\u4e86<\/p>\n\n\n\n<p>\u00a0\u767b\u5f55\u6821\u9a8c\u529f\u80fd\u8fd4\u56de\u7684\u4fe1\u606f\u6709\u70b9\u591a\uff0c\u6ce8\u610f\uff1a\u8df3\u8f6c\u5230\u4e3b\u9875\u7684\uff0c\u9700\u8981\u53bb\u4fee\u6539\u524d\u7aef\u4ee3\u7801\uff0c\u6539\u4e3a\u8df3\u8f6c\u5230\u4e2a\u4eba\u8be6\u60c5\u9875<img loading=\"lazy\" decoding=\"async\" height=\"144\" width=\"537\" src=\"https:\/\/i-blog.csdnimg.cn\/direct\/e93b3d66c23e44689c193b9b63781007.png\" alt=\"\"><\/p>\n\n\n\n<p>\u6ce8\u610f\uff1a\u8df3\u8f6c\u5230\u4e3b\u9875\u7684\uff0c\u9700\u8981\u53bb\u4fee\u6539\u524d\u7aef\u4ee3\u7801\uff0c\u6539\u4e3a\u8df3\u8f6c\u5230\u4e2a\u4eba\u8be6\u60c5\u9875\uff0c\u76f4\u63a5\u8df3\u5230\u9996\u9875\u5e76\u4e14\u70b9\u51fb\u6211\u7684<br>\u6216\u8005\u8df3\u56de\u9996\u9875\u7684 \u53ef\u4ee5\u770b\u770b\u524d\u7aeflogin\u90e8\u5206\u662f\u4e0d\u662f\u6ca1\u6709\u8df3\u5230info\u800c\u662f\u53bbindex\u4e86<\/p>\n\n\n\n<p>\u9700\u8981\u4ece\u65b0\u767b\u5f55\u7684\u5728login\u8fd9\u91cc\u4e0b\u9762\u8fd4\u56de\u7684\u6539\u6210\u8fd9\u4e2aResult.ok(userService.login(loginForm,session))&nbsp;<\/p>\n\n\n\n<p>\u6211\u4eec\u56de\u5230me\u65b9\u6cd5\uff0c\u4eceuserholder\u91cc\u5f97\u5230\u7528\u6237\u4ee5\u540e\u5c31\u76f4\u63a5\u8fd4\u56de\u4e86\uff0c\u5176\u5b9e\u4e5f\u8bf4\u660e\u53d6\u51fa\u7684\u4fe1\u606f\u5c31\u662f\u5b8c\u6574\u7684\u4fe1\u606f\uff0c\u8fd9\u4e2a\u6d88\u606f\u662f\u62e6\u622a\u5668\u90a3\u4e2asession\u5b58\u50a8\u7684\uff0c\u968f\u7740\u65f6\u95f4\u63a8\u79fb\u91cc\u9762\u7684\u4fe1\u606f\u8d8a\u6765\u8d8a\u591a\uff0c\u4e5f\u5c31\u8bf4\u660e\u538b\u529b\u4e5f\u5927\uff0c\u5176\u4e2d\u8c01\u7ed9session\u4fe1\u606f\u5462\uff1f\u5c31\u662flogin\u554a\u4e8e\u662f\u5c31\u8fd9\u6837\u4e86<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>UserServiceImpl.java\n..............\n\/\/7.\u4fdd\u5b58\u7528\u6237\u4fe1\u606f\u5230session\u4e2d\nsession.setAttribute(\"user\",Beanutil.copyProperties(user,UserDTO.class));\nreturn Result.ok();\n\n\u90a3\u4e48\u62e6\u622a\u5668\u7684\u5bf9\u8c61\u4e5f\u5c31\u662fUserDTO\u5bf9\u8c61\u4e86\nLoginInterceptor.java\n................\n\/\/5.\u5b58\u5728\uff0c\u4fdd\u5b58\u7528\u6237\u4fe1\u606f\u5230ThreadLocal\nUserHolder.saveUser((UserDTO) user);\n\/\/6.\u653e\u884c\nreturn true;\n\n\u987a\u9053\u518dUserHolder\u91cc\u9762\u6539\u4e3adto\nprivate static final ThreadLocal&lt;UserDTO&gt; tl = new ThreadLocal&lt;&gt;();\n\npublic static void saveUser\uff08UserDTO user){\n    tl.set(user);\n}\n\u5f88\u591a\u5f88\u591a\u4f9d\u8d56\u90fd\u6539\u6210userdto\nBlogController\u7684saveBlog\u548cqueryMyBlog\u7684\u7b2c\u4e00\u53e5\uff0c UserController\u901a\u901a\u6539\u6210UserDTO user<\/code><\/pre>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"15\" src=\"blob:https:\/\/eve2333.top\/2e3abfce-8b17-4587-b954-12ef245ead4d\" width=\"15\"><\/p>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"301\" width=\"278\" src=\"https:\/\/i-blog.csdnimg.cn\/direct\/6fdeb114c51a423f9d401907b0ce8f53.png\" alt=\"\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u96c6\u7fa4\u7684session\u5171\u4eab\u95ee\u9898<\/h3>\n\n\n\n<p>session\u5171\u4eab\u95ee\u9898\uff1a\u591a\u53f0Tomcat\u5e76\u4e0d\u5171\u4eabsession\u5b58\u50a8\u7a7a\u95f4\uff0c\u5f53\u8bf7\u6c42\u5207\u6362\u5230\u4e0d\u540ctomcat\u670d\u52a1\u65f6\u5bfc\u81f4\u6570\u636e\u4e22\u5931\u7684\u95ee\u9898\u3002<\/p>\n\n\n\n<p>\u65e9\u671f\u7684\u89e3\u51b3\u65b9\u6848\u662ftomcat\u4e4b\u95f4\u914d\u7f6e\u62f7\u8d1d\uff0c\u4f46\u662f\u6709\u51e0\u4e2a\u95ee\u9898\uff0c\u62f7\u8d1d\u8017\u5185\u5b58\uff0c\u5e76\u4e14\u6709\u5ef6\u8fdf<\/p>\n\n\n\n<p>session\u7684\u66ff\u4ee3\u65b9\u6848\u5e94\u8be5\u6ee1\u8db3\uff1a1.\u6570\u636e\u5171\u4eab\u00a0 2.\u5185\u5b58\u5b58\u50a8\u00a0 \u00a03.key\u3001value\u7ed3\u6784<img loading=\"lazy\" decoding=\"async\" height=\"293\" width=\"663\" src=\"https:\/\/i-blog.csdnimg.cn\/direct\/36394df7e1dc4b3d97923762cecbcb87.png\" alt=\"\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u57fa\u4e8eRedis\u5b9e\u73b0\u5171\u4eabsession\u767b\u5f55<\/h3>\n\n\n\n<p>redis\u4f5c\u4e3akey--value\u6765\u8bf4\uff0credis \u662f\u4e00\u4e2a\u5171\u4eab\u7684\u4e00\u4e2a\u5185\u5b58\u7a7a\u95f4\uff0c\u4e0d\u7ba1\u662f\u8c01\u6765\u53d1\u8bf7\u6c42\uff0c\u5728\u6211\u4eec\u670d\u52a1\u7aef\u662f\u4e0d\u662f\u53ea\u6709\u4e00\u4e2arelease\uff0c\u5927\u5bb6\u90fd\u5f80\u91cc\u9762\u53bb\u5b58\u3002\u5982\u679c\u4f60\u7684\u624b\u673a\u53f7\u6765\u7684\u65f6\u5019\u7528code\u554a\uff0c\u6709\u4e00\u4e2a\u624b\u673a\u53c8\u4e00\u4e2acode\uff0c\u90a3\u4e48\u4e0d\u540c\u7684\u624b\u673a\u53f7\u90fd\u7528code\u4e3akey\uff0c\u4e92\u76f8\u5c31\u8986\u76d6\uff1b&nbsp;\u90a3\u4e48\u8fd9\u4e2a\u9a8c\u8bc1\u7801\u5c06\u6765\u662f\u4e0d\u662f\u5c31\u4e22\u5931\u4e86\u5f88\u591a\uff0c\u5f88\u591a\u4eba\u5c31\u767b\u5f55\u4e0d\u4e0a\u3002\u6211\u4eec\u5fc5\u987b\u786e\u4fdd\u6bcf\u4e00\u4e2a\u4e0d\u540c\u7684\u624b\u673a\u53f7\u9a8c\u8bc1\u4fdd\u5b58\u7684key\u662f\u4e0d\u4e00\u6837\u7684\u3002<\/p>\n\n\n\n<p>\u624b\u673a\u53f7\u4f5c\u4e3akey \u9a8c\u8bc1\u7801\u505a\u4e3avalue\uff0c\u73b0\u5728 \u662fredis\uff0c\u6ca1\u6709\u539f\u6765\u7684\u81ea\u52a8\u6bcf\u4e00\u6b21 \u8bf7\u6c42\u90fd\u4f1a\u5e26\u7740Session ID\u6765\u3002\u73b0\u5728\u662f\u5ba2\u6237\u7aef\u8fd8\u5f97\u5e26\u7740\u8fd9\u4e2a\u4fe1\u606f\u6765\u53d6\u624d\u80fd\u9a8c\u8bc1\u3002\u90a3\u4e48\u8fd9\u6837\u4e00\u6765\u6211\u4eec\u53bb\u6821\u9a8c\u7684\u65f6\u5019\uff0c\u53ef\u4ee5\u57fa\u4e8e\u624b\u673a\u53f7\u4e3akey\uff0c\u4eceredis\u53bb\u8bfb\u53d6\u5230\u554a\u8fd9\u4e2a\u9a8c\u8bc1\u7801\u7136\u540e\u8ddf\u4ed6\u63d0\u4ea4\u7684\u9a8c\u8bc1\u7801\u505a\u6bd4\u8f83\u5c31\u884c\u4e86\uff08\u8fd9\u91cc\u89e3\u51b3\u4e86\u524d\u9762 \u7684\u7c7bbug\uff1a\u53d1\u9001\u548c\u767b\u5f55\u624b\u673a\u53f7\u4e0d\u4e00\u81f4\u7684\u95ee\u9898\uff09<\/p>\n\n\n\n<p>\u7b2c\u4e8c\u8981\u8003\u8651\u7684\u5c31\u662f\u6211\u4eec\u8fd9\u4e2akey\uff0c\u4fdd\u5b58\u9a8c\u8bc1\u7801\u7684\u65f6\u5019\u6211\u4eec\u7528\u7684\u662fstring\u7c7b\u578b\uff0c\u56e0\u4e3a\u4ed6\u5927\u90e8\u5206\u662f\u516d\u4f4d\u6570\u7684\u7684\u6570\u5b57\uff0c\u7528\u4e86\u5b57\u7b26\u4e32\u5f62\u5f0f\u53bb\u4fdd\u5b58\u3002\u4f46\u5728\u8fd9\u91cc\u5462\u4f60\u4fdd\u5b58\u7684\u662f\u4e00\u4e2a\u7528\u6237\u7684\u5bf9\u8c61\uff0c\u4fdd\u5b58\u5bf9\u8c61\u6211\u4eec\u5e94\u8be5\u9009\u62e9\u54ea\u79cd\u6570\u636e\u7c7b\u578b<\/p>\n\n\n\n<p>\u00a0\u5f53\u6211\u4eec\u5728redis\u4e2d\u4fdd\u5b58\u5bf9\u8c61\u65f6\u4e00\u822c\u4e24\u79cd\u7ed3\u6784\uff0c\u7b2c\u4e00\u79cd\u662fstring\u7ed3\u6784\uff0c\u7b2c\u4e8c\u79cd\u662fhash\uff1a string\u5176\u5b9e\u5c31\u662f\u628a\u6211\u4eec\u7684java\u5bf9\u8c61\u5e8f\u5217\u5316\u4e3ajson\u7684\u5b57\u7b26\u4e32<br>hash\u90a3\u5b83\u7684value\u554a\u662f\u4e00\u4e2a\u54c8\u5e0c\uff0c\u53ef\u4ee5\u7406\u89e3\u4e3amap\uff0c\u5b83\u5176\u5b9e\u5c31\u662f\u628a\u6211\u4eec\u7684java\u5bf9\u8c61\u4e2d\u7684\u6bcf\u4e00\u4e2a\u5b57\u6bb5\u90fd\u4f5c\u4e3a\u8fd9\u4e2avalue\u4e2d\u7684\u4e00\u4e2afield\u548cvalue\uff0cstring\u628a\u6574\u4e2a\u6570\u636e\u53d8\u6210\u4e00\u4e2a\u4e32\uff0c\u800c\u54c8\u5e0c\u7ed3\u6784\u5462\u6bcf\u4e2a\u5b57\u6bb5\u662f\u72ec\u7acb\u7684\uff0c\u6240\u4ee5\u8bf4\u5b83\u53ef\u4ee5\u9488\u5bf9\u5355\u4e2a\u5b57\u6bb5\u505acrud<img loading=\"lazy\" decoding=\"async\" height=\"405\" width=\"682\" src=\"https:\/\/i-blog.csdnimg.cn\/direct\/c329a217737344e19565c19e7f27f201.png\" alt=\"\"><\/p>\n\n\n\n<p>\u00a0\u5bf9\u4e8ekey\u7684\u8981\u6c42\uff1a1.\u4fdd\u8bc1\u552f\u4e002.\u5ba2\u6237\u7aef\u5c06\u6765\u80fd\u591f\u53bb\u643a\u5e26\u8fd9\u6837\u4e00\u4e2a\u5462key\u65b9\u4fbf\u4eceredis\u91cc\u518d\u53bb\u53d6\u51fa\u8fd9\u4e2a\u503c\u3002<img loading=\"lazy\" decoding=\"async\" height=\"356\" width=\"678\" src=\"https:\/\/i-blog.csdnimg.cn\/direct\/9bf16e8acb1b447aa6b82e756b8ed389.png\" alt=\"\"><\/p>\n\n\n\n<p>&nbsp;\u4e0d\u4e00\u6837\u7684 \u8fd9\u4e2a\u9879\u76ee\u5c31\u662f\u5b66redis\u53ef\u4ee5\u4e0d\u80fd\u7528jwt\u554a jwt\u5c31\u662f\u540e\u7aef\u4e0d\u5b58\u50a8\uff0c\u76f4\u63a5\u6839\u636ejwt\u89e3\u6790\u3002<\/p>\n\n\n\n<p>\u524d\u7aef\u767b\u5f55\u9875\u9762\u4e2d\u662f\u7528\u4e00\u4e2aaxiou\u7684\u8bf7\u6c42\u554a\u6765\u53bb\u505a\uff0c\u5728\u8fd9\u4e2a\u8bf7\u6c42\u7684\u54cd\u5e94\u91cc\u9762\uff0c\u8fd9\u4e2adata\u5176\u5b9e\u5c31\u662f\u6211\u4eec\u8981\u8fd4\u56de\u5230\u524d\u7aef\u7684\u8fd9\u6837\u767b\u5f55\u51ed\u8bc1token\uff0c\u5b83\u4f1a\u628a\u5b83\u4fdd\u5b58\u5728session storage\u91cc\u3002\u5728\u6211\u4eec\u524d\u7aef\u7684commonjs\u91cc\u8fd8\u6709\u8fd9\u4e48\u4e00\u70b9\u903b\u8f91\uff1a\u5c31\u662f\u4ecesession storage\u91cc\u5f97\u5230\u8fd9\u4e2atoken\uff0c\u4e0b\u8fb9\u662f\u4e00\u4e2a\u62e6\u622a\u5668\uff0c\u800c\u6bcf\u6b21\u53d1\u8bf7\u6c42\u90fd\u4f1a\u6267\u884c\u8fd9\u6837\u4e00\u6bb5\u903b\u8f91\u3002token\u4f5c\u4e3a\u8fd9\u4e2a\u8bf7\u6c42\u5934\uff0c\u8fd9\u4e2a\u5934\u7684\u540d\u5b57\u53ebauthorization\uff0c\u786e\u4fdd\u4ee5\u540e\u51e1\u662f\u6709axios\u53d1\u8d77\u7684\u8fd9\u79cd\u8bf7\u6c42\u90fd\u4f1a\u643a\u5e26authorization\u8fd9\u4e2a\u5934\uff0c\u5728\u670d\u52a1\u7aef\u5c31\u80fd\u83b7\u53d6\u8fd9\u4e2a\u5934\uff0c\u5b9e\u73b0\u767b\u9646\u9a8c\u8bc1<img loading=\"lazy\" decoding=\"async\" height=\"350\" width=\"682\" src=\"https:\/\/i-blog.csdnimg.cn\/direct\/7375088ce464480c914459d68d5f7bfa.png\" alt=\"\"><\/p>\n\n\n\n<p>\u73b0\u5728\u4fee\u6539\u4ee3\u7801\uff0c\u53ea\u6709\u4fee\u6539\u9a8c\u8bc1\u7801\u53d1\u751f\u53d8\u5316\u4e0d\u518d\u662f\u4fdd\u5b58\u5230redis\u65f6\u8fd9\u4e2akey\u554a\u4e0d\u518d\u662fcode\uff0c\u800c\u662f\u4ee5\u624b\u673a\u53f7\u4e3akey\uff0c\u597d\u6211\u4eec\u4fee\u6539UserServiceImpl<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    @Resource\n    private StringRedisTemplate stringRedisTemplate;\n\n    @Override\n    public Result sendCode(String phone, HttpSession session) {\n        \/\/ 1.\u6821\u9a8c\u624b\u673a\u53f7\n        if (RegexUtils.isPhoneInvalid(phone)) {\n            \/\/ 2.\u5982\u679c\u4e0d\u7b26\u5408\uff0c\u8fd4\u56de\u9519\u8bef\u4fe1\u606f\n            return Result.fail(\"\u624b\u673a\u53f7\u683c\u5f0f\u9519\u8bef\uff01\");\n        }\n        \/\/ 3.\u7b26\u5408\uff0c\u751f\u6210\u9a8c\u8bc1\u7801\n        String code = RandomUtil.randomNumbers(6);\n\n        \/\/ 4.\u4fdd\u5b58\u9a8c\u8bc1\u7801\u5230 session\n        stringRedisTemplate.opsForValue().set(LOGIN_CODE_KEY + phone, code, LOGIN_CODE_TTL, TimeUnit.MINUTES);\n\n        \/\/ 5.\u53d1\u9001\u9a8c\u8bc1\u7801\n        log.debug(\"\u53d1\u9001\u77ed\u4fe1\u9a8c\u8bc1\u7801\u6210\u529f\uff0c\u9a8c\u8bc1\u7801\uff1a{}\", code);\n        \/\/ \u8fd4\u56deok\n        return Result.ok();\n    }<\/code><\/pre>\n\n\n\n<p>\u5176\u4e2d\u5728util\u4e2d\u65b0\u5efaRedisConstants\u6587\u4ef6\u6765\u5b9a\u4e49\uff08\u5b9e\u9645\u4e0a\u539f\u6587\u4ef6\u5df2\u7ecf\u5b9a\u4e49\u597d\u4e86\uff09<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.hmdp.utils;\n\npublic class RedisConstants {\n    public static final String LOGIN_CODE_KEY = \"login:code:\";\n    public static final Long LOGIN_CODE_TTL = 2L;\n}\n<\/code><\/pre>\n\n\n\n<p>autowired\u548cresource\u7684\u529f\u80fd\u7c7b\u4f3c\u53ea\u4e0d\u8fc7autowired\u662f\u5148\u627e\u7c7b\u578b\u518d\u627e\u540d\u5b57\uff0cresource\u662f\u5148\u627e\u540d\u5b57\u518d\u627e\u7c7b\u578b\uff0c\u63a5\u4e0b\u6765\u5199\u77ed\u4fe1\u529f\u80fd<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    @Override\n    public Result login(LoginFormDTO loginForm, HttpSession session) {\n        \/\/ 1.\u6821\u9a8c\u624b\u673a\u53f7\n        String phone = loginForm.getPhone();\n        if (RegexUtils.isPhoneInvalid(phone)) {\n            \/\/ 2.\u5982\u679c\u4e0d\u7b26\u5408\uff0c\u8fd4\u56de\u9519\u8bef\u4fe1\u606f\n            return Result.fail(\"\u624b\u673a\u53f7\u683c\u5f0f\u9519\u8bef\uff01\");\n        }\n        \/\/ 3.\u4eceredis\u83b7\u53d6\u9a8c\u8bc1\u7801\u5e76\u6821\u9a8c\n        String cacheCode = stringRedisTemplate.opsForValue().get(LOGIN_CODE_KEY + phone);\n        String code = loginForm.getCode();\n        if (cacheCode == null || !cacheCode.equals(code)) {\n            \/\/ \u4e0d\u4e00\u81f4\uff0c\u62a5\u9519\n            return Result.fail(\"\u9a8c\u8bc1\u7801\u9519\u8bef\");\n        }\n\n        \/\/ 4.\u4e00\u81f4\uff0c\u6839\u636e\u624b\u673a\u53f7\u67e5\u8be2\u7528\u6237 select * from tb_user where phone = ?\n        User user = query().eq(\"phone\", phone).one();\n\n        \/\/ 5.\u5224\u65ad\u7528\u6237\u662f\u5426\u5b58\u5728\n        if (user == null) {\n            \/\/ 6.\u4e0d\u5b58\u5728\uff0c\u521b\u5efa\u65b0\u7528\u6237\u5e76\u4fdd\u5b58\n            user = createUserWithPhone(phone);\n        }\n\n        \/\/ 7.\u4fdd\u5b58\u7528\u6237\u4fe1\u606f\u5230 redis\u4e2d\n        \/\/ 7.1.\u968f\u673a\u751f\u6210token\uff0c\u4f5c\u4e3a\u767b\u5f55\u4ee4\u724c\n        String token = UUID.randomUUID().toString(true);\n        \/\/ 7.2.\u5c06User\u5bf9\u8c61\u8f6c\u4e3aHashMap\u5b58\u50a8\n        UserDTO userDTO = BeanUtil.copyProperties(user, UserDTO.class);\n        Map&lt;String, Object&gt; userMap = BeanUtil.beanToMap(userDTO);\n        \/\/ 7.3.\u5b58\u50a8\n        String tokenKey = LOGIN_USER_KEY + token;\n        stringRedisTemplate.opsForHash().putAll(tokenKey, userMap);\n        \/\/ 7.4.\u8bbe\u7f6etoken\u6709\u6548\u671f\n        stringRedisTemplate.expire(tokenKey, LOGIN_USER_TTL, TimeUnit.MINUTES);\n\n        \/\/ 8.\u8fd4\u56detoken\n        return Result.ok(token);\n    }<\/code><\/pre>\n\n\n\n<p>\u5728\u5b9e\u73b0\u7528\u6237\u767b\u5f55\u529f\u80fd\u65f6\uff0c\u9996\u5148\u9700\u8981\u751f\u6210\u4e00\u4e2a\u968f\u673atoken\u4f5c\u4e3a\u7528\u6237\u8eab\u4efd\u51ed\u8bc1\u3002\u8fd9\u91cc\u5efa\u8bae\u4f7f\u7528UUID\uff08\u901a\u7528\u552f\u4e00\u8bc6\u522b\u7801\uff09\uff0c\u56e0\u5176\u5177\u5907\u9ad8\u552f\u4e00\u6027\u548c\u7b80\u4fbf\u6027\u3002\u5177\u4f53\u53ef\u91c7\u7528Hutool\u5de5\u5177\u5e93\u63d0\u4f9b\u7684UUID\u65b9\u6cd5\u751f\u6210\u4e0d\u542b\u4e2d\u5212\u7ebf\u7684\u7b80\u6d01\u5b57\u7b26\u4e32\uff0c\u5982<code>UUID.randomUUID().toString(true)<\/code>\u3002\u751f\u6210token\u540e\uff0c\u9700\u5c06\u5176\u4f5c\u4e3aRedis\u7684key\uff0c\u5c06\u7528\u6237\u4fe1\u606f\u4ee5\u54c8\u5e0c\u7ed3\u6784\u5b58\u50a8\u3002\u4e3a\u907f\u514d\u591a\u6b21\u4e0eRedis\u4ea4\u4e92\uff0c\u5e94\u901a\u8fc7BeanUtil\u5de5\u5177\u5c06UserDTO\u5bf9\u8c61\u8f6c\u6362\u4e3aMap\uff0c\u5229\u7528<code>putAll<\/code>\u65b9\u6cd5\u4e00\u6b21\u6027\u5b58\u5165\u591a\u4e2a\u5b57\u6bb5\u3002\u5b58\u50a8\u65f6\u9700\u6ce8\u610f\u4e3akey\u6dfb\u52a0\u4e1a\u52a1\u524d\u7f00\uff08\u5982<code>login:user:token<\/code>\uff09\uff0c\u5e76\u8bbe\u7f6e30\u5206\u949f\u7684\u6709\u6548\u671f\uff0c\u9632\u6b62\u5185\u5b58\u8fc7\u5ea6\u5360\u7528\u3002\u5177\u4f53\u5b9e\u73b0\u6b65\u9aa4\u4e3a\uff1a\u6821\u9a8c\u624b\u673a\u53f7\u683c\u5f0f\uff0c\u6bd4\u5bf9Redis\u4e2d\u5b58\u50a8\u7684\u9a8c\u8bc1\u7801\uff0c\u67e5\u8be2\u6216\u521b\u5efa\u7528\u6237\uff0c\u751f\u6210token\uff0c\u8f6c\u6362\u7528\u6237\u6570\u636e\u4e3aMap\u7ed3\u6784\uff0c\u5b58\u5165Redis\u5e76\u8bbe\u7f6e\u8fc7\u671f\u65f6\u95f4\uff0c\u6700\u7ec8\u8fd4\u56detoken\u7ed9\u524d\u7aef\u3002\u5176\u4e2d\uff0c\u5bf9\u8c61\u8f6c\u6362\u9700\u4f7f\u7528<code>BeanUtil.copyProperties<\/code>\u548c<code>BeanUtil.beanToMap<\/code>\u65b9\u6cd5\uff0c\u540c\u65f6\u5ffd\u7565\u7a7a\u503c\u5b57\u6bb5\u5e76\u7edf\u4e00\u5b57\u6bb5\u503c\u7c7b\u578b\uff0c\u786e\u4fddRedis\u5b58\u50a8\u7ed3\u6784\u7684\u89c4\u8303\u6027\u3002\u540c\u6837\u7684redisconstants\u4fee\u6539<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.hmdp.utils;\n\npublic class RedisConstants {\n    public static final String LOGIN_CODE_KEY = \"login:code:\";\n    public static final Long LOGIN_CODE_TTL = 2L;\n    public static final String LOGIN_USER_KEY = \"login:token:\";\n    public static final Long LOGIN_USER_TTL = 36000L;\n}<\/code><\/pre>\n\n\n\n<p>\u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u9700\u8981\u5bf9\u4ee3\u7801\u4e2d\u7684\u53d8\u91cf\u540d\u8fdb\u884c\u8c03\u6574\u3002\u6bd4\u5982\u539f\u6765\u7684<code>login_code<\/code>\u73b0\u5728\u4e0d\u518d\u9700\u8981\u4e86\uff0c\u53ef\u4ee5\u5c06\u5176\u6539\u4e3a<code>login_user<\/code>\uff0c\u56e0\u4e3a\u8fd9\u662f\u4e0e\u7528\u6237\u767b\u5f55\u76f8\u5173\u7684\u4e1a\u52a1\u3002\u76f8\u5e94\u7684\uff0cRedis\u7684key\u524d\u7f00\u4e5f\u53ef\u4ee5\u547d\u540d\u4e3a<code>login:user:key<\/code>\uff0c\u800ctoken\u7684\u6709\u6548\u671f\u5219\u8bbe\u7f6e\u4e3a30\u5206\u949f\u3002\u8fd9\u91cc\u7684token\u540d\u79f0\u53ef\u4ee5\u53eb<code>login_token<\/code>\u6216\u8005<code>user_token<\/code>\uff0c\u90fd\u662f\u53ef\u4ee5\u63a5\u53d7\u7684\u3002\u7136\u800c\uff0c\u4ec5\u4ec5\u8bbe\u7f6e30\u5206\u949f\u7684\u6709\u6548\u671f\u8fd8\u4e0d\u591f\u3002\u76ee\u524d\u7684\u903b\u8f91\u662f\uff0c\u4ece\u7528\u6237\u767b\u5f55\u90a3\u4e00\u523b\u5f00\u59cb\u8ba1\u65f6\uff0c30\u5206\u949f\u540e\u65e0\u8bba\u7528\u6237\u662f\u5426\u6d3b\u8dc3\uff0cRedis\u90fd\u4f1a\u5c06\u8be5\u7528\u6237\u7684\u767b\u5f55\u72b6\u6001\u79fb\u9664\u3002\u8fd9\u663e\u7136\u4e0d\u7b26\u5408\u5b9e\u9645\u9700\u6c42\uff0c\u56e0\u4e3a\u6211\u4eec\u5e0c\u671b\u7684\u662f\uff1a\u53ea\u8981\u7528\u6237\u6301\u7eed\u8bbf\u95ee\u7cfb\u7edf\uff0ctoken\u7684\u6709\u6548\u671f\u5c31\u5e94\u8be5\u4e0d\u65ad\u5237\u65b0\uff0c\u800c\u4e0d\u662f\u5728\u56fa\u5b9a\u65f6\u95f4\u540e\u5f3a\u5236\u5931\u6548\u3002<\/p>\n\n\n\n<p>\u90a3\u4e48\u95ee\u9898\u6765\u4e86\uff1a\u5982\u4f55\u5224\u65ad\u7528\u6237\u662f\u5426\u5728\u8bbf\u95ee\u7cfb\u7edf\uff1f\u5176\u5b9e\uff0c\u6211\u4eec\u4e4b\u524d\u5b9e\u73b0\u8fc7\u4e00\u4e2a\u529f\u80fd\u2014\u2014\u767b\u5f55\u62e6\u622a\u5668\u3002\u6240\u6709\u7684\u8bf7\u6c42\u8fdb\u5165\u7cfb\u7edf\u65f6\uff0c\u90fd\u4f1a\u7ecf\u8fc7\u8fd9\u4e2a\u62e6\u622a\u5668\u7684\u6821\u9a8c\u3002\u5982\u679c\u8bf7\u6c42\u901a\u8fc7\u4e86\u6821\u9a8c\uff0c\u5c31\u8bf4\u660e\u4e24\u70b9\uff1a\u7b2c\u4e00\uff0c\u8be5\u7528\u6237\u5df2\u7ecf\u767b\u5f55\uff1b\u7b2c\u4e8c\uff0c\u8be5\u7528\u6237\u5f53\u524d\u5904\u4e8e\u6d3b\u8dc3\u72b6\u6001\u3002\u57fa\u4e8e\u8fd9\u4e24\u70b9\uff0c\u6211\u4eec\u53ef\u4ee5\u5728\u62e6\u622a\u5668\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u903b\u8f91\uff1a\u6bcf\u6b21\u7528\u6237\u8bbf\u95ee\u7cfb\u7edf\u65f6\uff0c\u66f4\u65b0Redis\u4e2d\u5bf9\u5e94token\u7684\u6709\u6548\u671f\u3002\u8fd9\u6837\u4e00\u6765\uff0c\u53ea\u8981\u7528\u6237\u6301\u7eed\u8bbf\u95ee\u7cfb\u7edf\uff0ctoken\u7684\u6709\u6548\u671f\u5c31\u4f1a\u4e0d\u65ad\u5ef6\u957f\uff0c\u53ea\u6709\u5f53\u7528\u6237\u8d85\u8fc730\u5206\u949f\u6ca1\u6709\u4efb\u4f55\u64cd\u4f5c\u65f6\uff0ctoken\u624d\u4f1a\u88ab\u79fb\u9664\u3002<\/p>\n\n\n\n<p>\u56e0\u6b64\uff0c\u5728\u4fee\u6539\u767b\u5f55\u72b6\u6001\u6821\u9a8c\u7684\u4e1a\u52a1\u903b\u8f91\u65f6\uff0c\u6211\u4eec\u9700\u8981\u5728\u539f\u6709\u903b\u8f91\u7684\u57fa\u7840\u4e0a\u589e\u52a0\u4e00\u4e2a\u65b0\u529f\u80fd\uff1a\u66f4\u65b0token\u6709\u6548\u671f\u3002\u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u53ef\u4ee5\u627e\u5230\u4e0e\u767b\u5f55\u76f8\u5173\u7684\u4e1a\u52a1\u4ee3\u7801\uff0c\u8fd9\u90e8\u5206\u903b\u8f91\u5199\u5728\u62e6\u622a\u5668\uff08<code>LoginInterceptor<\/code>\uff09\u4e2d\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public class LoginInterceptor implements HandlerInterceptor {\n\n    private StringRedisTemplate stringRedisTemplate;\n\n    @Override\n    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {\n        \/\/ 1.\u5224\u65ad\u662f\u5426\u9700\u8981\u62e6\u622a\uff08ThreadLocal\u4e2d\u662f\u5426\u6709\u7528\u6237\uff09\n        if (UserHolder.getUser() == null) {\n            \/\/ \u6ca1\u6709\uff0c\u9700\u8981\u62e6\u622a\uff0c\u8bbe\u7f6e\u72b6\u6001\u7801\n            response.setStatus(401);\n            \/\/ \u62e6\u622a\n            return false;\n        }\n        \/\/ \u6709\u7528\u6237\uff0c\u5219\u653e\u884c\n        return true;\n    }\n}<\/code><\/pre>\n\n\n\n<p>\u5728\u8fd9\u4e2a\u5730\u65b9\uff0c\u6211\u4eec\u65e0\u6cd5\u4f7f\u7528<code>@Autowired<\/code>\u3001<code>@Resource<\/code>\u7b49\u6ce8\u89e3\u6765\u8fdb\u884c\u4f9d\u8d56\u6ce8\u5165\uff0c\u800c\u53ea\u80fd\u901a\u8fc7\u6784\u9020\u51fd\u6570\u7684\u65b9\u5f0f\u6765\u5b9e\u73b0\u4f9d\u8d56\u6ce8\u5165\u3002\u8fd9\u662f\u56e0\u4e3a\u5f53\u524d\u7c7b\u7684\u5bf9\u8c61\u662f\u6211\u4eec\u624b\u52a8\u901a\u8fc7<code>new<\/code>\u5173\u952e\u5b57\u521b\u5efa\u7684\uff0c\u800c\u4e0d\u662f\u7531Spring\u5bb9\u5668\u7ba1\u7406\u7684\u3002\u6362\u53e5\u8bdd\u8bf4\uff0c\u8fd9\u4e2a\u7c7b\u7684\u5bf9\u8c61\u5e76\u6ca1\u6709\u901a\u8fc7<code>@Component<\/code>\u6216\u5176\u4ed6\u7c7b\u4f3c\u7684\u6ce8\u89e3\u4ea4\u7ed9Spring\u6765\u521b\u5efa\u548c\u7ba1\u7406\uff0c\u56e0\u6b64Spring\u65e0\u6cd5\u81ea\u52a8\u4e3a\u6211\u4eec\u5b8c\u6210\u4f9d\u8d56\u6ce8\u5165\u3002\u5bf9\u4e8eSpring\u7ba1\u7406\u7684\u5bf9\u8c61\uff0c\u6bd4\u5982\u6dfb\u52a0\u4e86<code>@Autowired<\/code>\u6ce8\u89e3\u7684\u7c7b\uff0cSpring\u4f1a\u81ea\u52a8\u5b8c\u6210\u4f9d\u8d56\u6ce8\u5165\uff1b\u4f46\u5982\u679c\u6211\u4eec\u624b\u52a8\u521b\u5efa\u5bf9\u8c61\uff0c\u5219\u6ca1\u6709\u4efb\u4f55\u673a\u5236\u80fd\u591f\u5e2e\u52a9\u6211\u4eec\u5b8c\u6210\u4f9d\u8d56\u6ce8\u5165\uff0c\u4e5f\u5c31\u65e0\u6cd5\u4f7f\u7528<code>@Resource<\/code>\u7b49\u6ce8\u89e3\u3002<\/p>\n\n\n\n<p>\u90a3\u4e48\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u9009\u62e9\u901a\u8fc7\u6784\u9020\u51fd\u6570\u6ce8\u5165\u7684\u65b9\u5f0f\u89e3\u51b3\u95ee\u9898\u3002\u90a3\u4e48\u8c01\u6765\u8d1f\u8d23\u4e3a\u6211\u4eec\u6ce8\u5165\u4f9d\u8d56\u5462\uff1f\u8fd9\u5c31\u9700\u8981\u770b\u662f\u8c01\u5728\u4f7f\u7528\u8fd9\u4e2a\u7c7b\u4e86\u3002\u56de\u987e\u4e00\u4e0b\uff0c\u6211\u4eec\u5728<code>MvcConfig<\/code>\u914d\u7f6e\u7c7b\u4e2d\u7684\u62e6\u622a\u5668\u90e8\u5206\u4f7f\u7528\u4e86\u8fd9\u4e2a\u7c7b\uff0c\u800c\u8fd9\u91cc\u62a5\u9519\u4e86\uff0c\u8bf4\u660e\u6211\u4eec\u9700\u8981\u5bf9\u8fd9\u90e8\u5206\u4ee3\u7801\u8fdb\u884c\u8c03\u6574\u3002\u89e3\u51b3\u65b9\u6cd5\u662f\uff0c\u5728<code>MvcConfig<\/code>\u4e2d\u83b7\u53d6<code>RedisTemplate<\/code>\u5b9e\u4f8b\u3002\u5927\u5bb6\u53ef\u4ee5\u770b\u5230\uff0c<code>MvcConfig<\/code>\u7c7b\u4e0a\u6dfb\u52a0\u4e86<code>@Configuration<\/code>\u6ce8\u89e3\uff0c\u8fd9\u610f\u5473\u7740\u8fd9\u4e2a\u7c7b\u662f\u7531Spring\u6765\u6784\u5efa\u548c\u7ba1\u7406\u7684\u3002\u65e2\u7136\u662f\u7531Spring\u7ba1\u7406\u7684\u7c7b\uff0c\u5c31\u53ef\u4ee5\u5229\u7528Spring\u7684\u4f9d\u8d56\u6ce8\u5165\u529f\u80fd\uff0c\u56e0\u6b64\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7<code>@Resource<\/code>\u6ce8\u89e3\u76f4\u63a5\u83b7\u53d6<code>StringRedisTemplate<\/code>\u5b9e\u4f8b\uff0c\u4ece\u800c\u5b8c\u6210\u4f9d\u8d56\u6ce8\u5165\u3002<\/p>\n\n\n\n<p><strong>\u6240\u4ee5\u628a\u8fd9\u4e2a\u624b\u52a8new\u7684\u6362\u6210@Component\uff0c\u5c31\u53ef\u4ee5\u7528\u81ea\u52a8\u88c5\u914d\u4e86\uff1b\u4f46\u662f\u4e0d\u80fd\u52a0Competent\uff0c\u62e6\u622a\u5668\u662f\u4e00\u4e2a\u975e\u5e38\u8f7b\u91cf\u7ea7\u7684\u7ec4\u4ef6\uff0c\u53ea\u6709\u5728\u9700\u8981\u65f6\u624d\u4f1a\u88ab\u8c03\u7528\uff0c\u5e76\u4e14\u4e0d\u9700\u8981\u50cf\u63a7\u5236\u5668\u6216\u670d\u52a1\u4e00\u6837\u5728\u6574\u4e2a\u5e94\u7528\u7a0b\u5e8f\u4e2d\u53ef\u7528\u3002\u56e0\u6b64\uff0c\u5c06\u62e6\u622a\u5668\u58f0\u660e\u4e3a\u4e00\u4e2aSpring Bean\u53ef\u80fd\u4f1a\u5f15\u5bfc\u81f4\u6027\u80fd\u4e0b\u964d\u3002<\/strong><\/p>\n\n\n\n<p>&nbsp;\u90a3MvcConfig\u8fd9\u91cc\u600e\u4e48\u83b7\u53d6redis template\uff1f\u8fd9\u4e2a\u7c7b\u52a0\u4e86configuration\u6ce8\u89e3\u8bf4\u660e\u8fd9\u4e2a\u7c7b\u5c06\u6765\u662f\u4e0d\u662f\u7531spring\u6784\u5efa\u7684\uff0c\u7531spring\u6765\u6784\u5efa\u8fd9\u4e2a\u7c7b\u7684\u5bf9\u8c61\u4ed6\u5c31\u53ef\u4ee5\u505a\u4f9d\u8d56\u6ce8\u5165\uff0c\u56e0\u6b64\u53ef\u4ee5\u5229\u7528resource\u6ce8\u89e3\u6765\u83b7\u53d6string redis template\u554a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.hmdp.config;\n\nimport com.hmdp.utils.LoginInterceptor;\nimport com.hmdp.utils.RefreshTokenInterceptor;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.data.redis.core.StringRedisTemplate;\nimport org.springframework.web.servlet.config.annotation.InterceptorRegistry;\nimport org.springframework.web.servlet.config.annotation.WebMvcConfigurer;\n\nimport javax.annotation.Resource;\n\n@Configuration\npublic class MvcConfig implements WebMvcConfigurer {\n\n    @Resource\n    private StringRedisTemplate stringRedisTemplate;\n\n    @Override\n    public void addInterceptors(InterceptorRegistry registry) {\n        \/\/ \u767b\u5f55\u62e6\u622a\u5668\n        registry.addInterceptor(new LoginInterceptor(stringRedisTemplate))\n                .excludePathPatterns(\n                        \"\/shop\/**\",\n                        \"\/voucher\/**\",\n                        \"\/shop-type\/**\",\n                        \"\/upload\/**\",\n                        \"\/blog\/hot\",\n                        \"\/user\/code\",\n                        \"\/user\/login\"\n                ).order(1);\n            }\n    }\n}\n<\/code><\/pre>\n\n\n\n<p>\u56de\u5230LoginInterceptor\uff0c\u8fd9\u91cc\u5462\u5c31\u62ff\u5230\u4e86redistemplate\u4e86<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.hmdp.utils;\n\nimport cn.hutool.core.bean.BeanUtil;\nimport cn.hutool.core.util.StrUtil;\nimport com.hmdp.dto.UserDTO;\nimport org.springframework.data.redis.core.StringRedisTemplate;\nimport org.springframework.web.servlet.HandlerInterceptor;\n\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\nimport java.util.Map;\nimport java.util.concurrent.TimeUnit;\n\npublic class LoginInterceptor implements HandlerInterceptor {\n\n    private StringRedisTemplate stringRedisTemplate;\n\n    public LoginInterceptor(StringRedisTemplate stringRedisTemplate) {\n        this.stringRedisTemplate = stringRedisTemplate;\n    }\n\n    @Override\n    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {\n        \/\/ 1.\u83b7\u53d6\u8bf7\u6c42\u5934\u4e2d\u7684token\n        String token = request.getHeader(\"authorization\");\n        if (StrUtil.isBlank(token)) {\n            \/\/ \u4e0d\u5b58\u5728\uff0c\u62e6\u622a\uff0c\u8fd4\u56de401\u72b6\u6001\u7801\n            response.setStatus(401);\n            return false;\n        }\n\n\/\/ 2.\u57fa\u4e8eTOKEN\u83b7\u53d6redis\u4e2d\u7684\u7528\u6237\n        String key = RedisConstants.LOGIN_USER_KEY + token;\n        Map&lt;Object, Object&gt; userMap = stringRedisTemplate.opsForHash().entries(key);\n\/\/ 3.\u5224\u65ad\u7528\u6237\u662f\u5426\u5b58\u5728\n        if (userMap.isEmpty()) {\n            \/\/ 4.\u4e0d\u5b58\u5728\uff0c\u62e6\u622a\uff0c\u8fd4\u56de401\u72b6\u6001\u7801\n            response.setStatus(401);\n            return false;\n        }\n\n\/\/ 5.\u5c06\u67e5\u8be2\u5230\u7684Hash\u6570\u636e\u8f6c\u4e3aUserDTO\u5bf9\u8c61\n        UserDTO userDTO = BeanUtil.fillBeanWithMap(userMap, new UserDTO(),false);\n\n\/\/ 6.\u5b58\u5728\uff0c\u4fdd\u5b58\u7528\u6237\u4fe1\u606f\u5230 ThreadLocal\n        UserHolder.saveUser(userDTO);\n\n\/\/ 7.\u5237\u65b0token\u6709\u6548\u671f\n        stringRedisTemplate.expire(key, RedisConstants.LOGIN_USER_TTL, TimeUnit.MINUTES);\n\/\/ 8.\u653e\u884c\n        return true;\n    }\n    @Override\n    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {\n        \/\/ \u79fb\u9664\u7528\u6237\n        UserHolder.removeUser();\n    }\n}\n<\/code><\/pre>\n\n\n\n<p>\u8fd9\u4e00\u6b65\u653e\u5728mvcconfig\u91cc\u597d\u4e00\u70b9\u5427\uff0c\u4e0d\u7136\u8d70\u88ab\u62e6\u622a\u7684\u8bf7\u6c42\u5c31\u4e0d\u66f4\u65b0\u4e86\uff1b\u542f\u52a8\u62a5\u9519 BeanCreationException\u7684\u8bb0\u5f97\u7ed9@Resource \u7684\u540d\u5b57\u6539\u4e3astringRedisTemplate--\u6216\u8005\u5c06\u6ce8\u89e3\u6539\u4e3a@Autowied\u8fd9\u91cc\u8ddf\u6ce8\u89e3\u7684\u7279\u6027\u6709\u5173\u4e0d\u591a\u89e3\u91ca\u4e86<\/p>\n\n\n\n<p>java.lang.Long cannot be cast to java.lang.String<\/p>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"153\" width=\"664\" src=\"https:\/\/i-blog.csdnimg.cn\/direct\/35eb25334cef47de854d6b23a6fefd9b.png\" alt=\"\"><\/p>\n\n\n\n<p>\u8f93\u5165\u767b\u5f55\uff0c\u4f1a\u51fa\u73b0\u62a5\u9519\u4e86\uff08\u670d\u52a1\u5668\u9519\u8bef\uff09\uff0c\u628a\u6211\u4eec\u7684usermap\u5411redistemplate\u5199\u7684\u65f6\u5019\u62a5\u9519\u4e86\uff1a\u7c7b\u578b\u8f6c\u6362long\u4e0d\u80fd\u8f6c\u5316\u4e3astring\uff0c\u90a3\u4e48userdto\u91cc\u5176\u5b9e\u53ea\u6709id\u662flong\u7c7b\u578b\u5bf9\u5427\uff0credis\u65e0\u6cd5\u5b58\u50a8\u3002\u4e3a\u4ec0\u4e48\uff1fredis template\uff0cstring template\u5b83\u6709\u4e00\u4e2a\u4ec0\u4e48\u7279\u70b9\uff0c\u4ed6\u8981\u6c42\u4f60\u7684key\u6216\u8005value\u90fd\u662fstring\u7ed3\u6784\uff0c\u800c\u6211\u4eec\u628a\u6570\u636e\u8f6c\u6210map\u7684\u65f6\u5019\uff0c\u6211\u4eec\u90a3\u4e2a\u5b57\u6bb5id\u662flong\u7c7b\u578b\u3002<\/p>\n\n\n\n<p>\u56e0\u6b64\u786e\u4fdd\u8fd9\u91cc\u8fb9\u7684\u6bcf\u4e00\u4e2a\u503c\u90fd\u8981\u4ee5string\u7684\u5f62\u5f0f\u5b58\u50a8\u7684\uff0c\u662fmap\u7684key\u548cvalue\u90fd\u5f97\u662fstring\u7ed3\u6784\u3002\u6709\u4e24\u79cd\u65b9\u6cd5\uff0c<br>\u7b2c\u4e00\u79cd\u7b28\u529e\u6cd5\uff0c\u81ea\u5df1new\u4e00\u4e2amap\uff0c\u4e0d\u518dMap&lt;String \uff0cObject&gt; userMap = BeanUtil.beanToMap\uff08userDTO);\u7136\u540e\u628a\u8fd9\u4e2a\u5bf9\u8c61\u91cc\u9762\u7684\u5b57\u6bb5\u540d\u4f5c\u4e3akey\uff1b<br>\u7b2c\u4e8c\u79cd\uff0cObjectbean,Map&lt;String,object&gt;targetMap,CopyOptionscopyOptions \uff0c\u5141\u8bb8\u4f60\u5bf9key\u548cvalue\u505a\u81ea\u5b9a\u4e49<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> @Override\n    public Result login(LoginFormDTO loginForm, HttpSession session) {\n        \/\/ 1.\u6821\u9a8c\u624b\u673a\u53f7\n        String phone = loginForm.getPhone();\n        if (RegexUtils.isPhoneInvalid(phone)) {\n            \/\/ 2.\u5982\u679c\u4e0d\u7b26\u5408\uff0c\u8fd4\u56de\u9519\u8bef\u4fe1\u606f\n            return Result.fail(\"\u624b\u673a\u53f7\u683c\u5f0f\u9519\u8bef\uff01\");\n        }\n        \/\/ 3.\u4eceredis\u83b7\u53d6\u9a8c\u8bc1\u7801\u5e76\u6821\u9a8c\n        String cacheCode = stringRedisTemplate.opsForValue().get(LOGIN_CODE_KEY + phone);\n        String code = loginForm.getCode();\n        if (cacheCode == null || !cacheCode.equals(code)) {\n            \/\/ \u4e0d\u4e00\u81f4\uff0c\u62a5\u9519\n            return Result.fail(\"\u9a8c\u8bc1\u7801\u9519\u8bef\");\n        }\n\n        \/\/ 4.\u4e00\u81f4\uff0c\u6839\u636e\u624b\u673a\u53f7\u67e5\u8be2\u7528\u6237 select * from tb_user where phone = ?\n        User user = query().eq(\"phone\", phone).one();\n\n        \/\/ 5.\u5224\u65ad\u7528\u6237\u662f\u5426\u5b58\u5728\n        if (user == null) {\n            \/\/ 6.\u4e0d\u5b58\u5728\uff0c\u521b\u5efa\u65b0\u7528\u6237\u5e76\u4fdd\u5b58\n            user = createUserWithPhone(phone);\n        }\n\n        \/\/ 7.\u4fdd\u5b58\u7528\u6237\u4fe1\u606f\u5230 redis\u4e2d\n        \/\/ 7.1.\u968f\u673a\u751f\u6210token\uff0c\u4f5c\u4e3a\u767b\u5f55\u4ee4\u724c\n        String token = UUID.randomUUID().toString(true);\n        \/\/ 7.2.\u5c06User\u5bf9\u8c61\u8f6c\u4e3aHashMap\u5b58\u50a8\n        UserDTO userDTO = BeanUtil.copyProperties(user, UserDTO.class);\n        Map&lt;String, Object&gt; userMap = BeanUtil.beanToMap(userDTO, new HashMap&lt;&gt;(),\n                CopyOptions.create()\n                        .setIgnoreNullValue(true)\n                        .setFieldValueEditor((fieldName, fieldValue) -&gt; fieldValue.toString()));\n\/*copyoption\u5c31\u662f\u505a\u6570\u636e\u62f7\u8d1d\u65f6\u7684\u4e00\u4e2a\u9009\u9879\uff0c\u8fd9\u6837\u5c31\u521b\u5efa\u51fa\u6765\u4e00\u4e2acopyoption\u4e86\u3002\n\u4f46\u662f\u5462\u8fd9\u4e2a\u5730\u65b9\u521b\u5efa\u51fa\u6765\u662f\u9ed8\u8ba4\u7684\uff0c\u6211\u4eec\u8981\u81ea\u5b9a\u4e49\u5141\u8bb8\u4f60\u505a\u5404\u79cd\u5404\u6837\u7684set\uff0c\u6bd4\u5982\u8bf4\u5462set \nignore null value\u5c31\u662f\u5ffd\u7565\u4e00\u4e9b\u7a7a\u7684\u503c*\/\n        \/\/ 7.3.\u5b58\u50a8\n        String tokenKey = LOGIN_USER_KEY + token;\n        stringRedisTemplate.opsForHash().putAll(tokenKey, userMap);\n        \/\/ 7.4.\u8bbe\u7f6etoken\u6709\u6548\u671f\n        stringRedisTemplate.expire(tokenKey, LOGIN_USER_TTL, TimeUnit.MINUTES);\n\n        \/\/ 8.\u8fd4\u56detoken\n        return Result.ok(token);\n    }<\/code><\/pre>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"149\" width=\"677\" src=\"https:\/\/i-blog.csdnimg.cn\/direct\/3ab835b616b94a18b274f957d413f0c4.png\" alt=\"\"><\/p>\n\n\n\n<p>\u95ee\u9898\u5c31\u662fStringRedisTemplate\u662f\u5b9a\u4e49\u4e00\u4e2aString\u7c7b\u578b\u7684key\u548cvalue\uff0c\u4f46\u662f\u518dmap\u8f6c\u6362\u6210user\u7684\u65f6\u5019\u65e0\u6cd5\u5c06string\u8f6c\u6362\u6210long\uff0c\u6240\u4ee5\u9700\u8981\u8fd9\u79cd\u65b9\u5f0f\u6216\u8005\u81ea\u5b9a\u4e49\u4e00\u4e2amap.<\/p>\n\n\n\n<p>\u8f6c\u5316\u4e0bmap\u503c\u7c7b\u578b userMap.forEach((key,value)-&gt;{if(null!=value) userMap.put(key, String.valueOf(value)); });<\/p>\n\n\n\n<p>\u767b\u5f55\u540e\u53c8\u56de\u6765\u7684\uff0c\u8bb0\u5f97\u5728login\u4e1a\u52a1\u91cc\u8fd4\u56detoken\u5230\u63a7\u5236\u5c42\uff08\u8981\u91cd\u65b0\u767b\u5f55\u7684\u770b\u4e00\u4e0b\u662f\u4e0d\u662flogin\u65b9\u6cd5ok\u91cc\u6709\u6ca1\u6709\u8fd4\u56detoken \u6240\u4ee5\u62e6\u622a\u5668\u4e2d\u5c31\u6ca1\u6709\u83b7\u53d6\u5230 \u5c31\u7ed9\u4f60\u6253\u56de\u4e86\uff09controller\u5c42\u7684login\u662fretuen userService.login(loginForm,session)<\/p>\n\n\n\n<p>\u6211\u4eec\u7684\u767b\u5f55\u529f\u80fd\u662f\u57fa\u4e8e\u62e6\u622a\u5668\u505a\u7684\u6821\u9a8c\u5bf9\u5427\uff1f\u6ca1\u6709\u8bf7\u6c42\u8fdb\u5165\u4e86\u62e6\u622a\u5668\u4ee5\u540e\uff0c\u6211\u4eec\u4f1a\u5c1d\u8bd5\u53bb\u83b7\u53d6\u8bf7\u6c42\u5934\u4e2d\u7684 token\u3002\u90a3\u4e48\u5982\u679c\u8bf4\u4ed6\u4e4b\u524d\u767b\u5f55\u8fc7\u4ed6\u7684\u5934\u91cc\u4e00\u5b9a\u4f1a\u6709token\u5bf9\u4e0d\u5bf9\uff1f\u90a3\u4e48\u6211\u4eec\u518d\u53bb\u6839\u636etoken\u5230redis\u91cc\u67e5\u8be2\u5bf9\u5e94\u7684\u7528\u6237\u4fe1\u606f\uff0c\u90a3\u4e48\u67e5\u4e86\u4ee5\u540e\u5bf9\u7528\u6237\u505a\u4e00\u4e2a\u5224\u65ad\uff0c\u5b58\u5728\u6216\u8005\u662f\u4e0d\u5b58\u5728\uff0c\u4e0d\u5b58\u5728\u7ed9\u4f60\u62e6\u622a\uff0c\u5b58\u5728\u6211\u5c31\u7ee7\u7eed\uff0c\u7ee7\u7eed\u5e72\u4ec0\u4e48\uff1f\u7528\u6237\u5b58\u5728\uff0c\u6211\u5c31\u4f1a\u628a\u5b83\u4fdd\u5b58\u5230\u6240\u6709\u7684local\u5f53\u4e2d\uff0c\u65b9\u4fbf\u540e\u7eed\u7684control\u7684\u4e1a\u52a1\u53bb\u4f7f\u7528\u5b83\uff0c\u5bf9\u5427\uff1f\u597d\uff0c\u90a3\u4e48\u4fdd\u5b58\u5b8c\u4e86\uff0c\u6211\u4eec\u8fd8\u505a\u4e86\u4e00\u4ef6\u4e8b\uff0c\u5c31\u662f\u53bb\u5237\u65b0token\u7684\u6709\u6548\u671f\uff0c\u4e3a\u4ec0\u4e48\uff1f\u56e0\u4e3a\u6211\u4eec\u5728redis\u91cc\u4fdd\u5b58\u7684 Token\u6709\u6548\u671f\u662f30\u5206\u949f\uff0c\u5982\u679c\u8bf4\u4e0d\u53bb\u505a\u5237\u65b0\uff0c\u7528\u623730\u5206\u949f\u540e\u5c31\u53ef\u80fd\u5931\u53bb\u4e86\u767b\u5f55\u72b6\u6001\u4e86\uff0c\u8fd9\u4e2a\u5c31\u4e0d\u592a\u53cb\u597d\u3002<\/p>\n\n\n\n<p>\u6240\u4ee5\u6211\u4eec\u53bb\u505a\u4e00\u4e2a\u5237\u65b0\uff0c\u6bcf\u5f53\u7528\u6237\u6765\u8bbf\u95ee\uff0c\u6211\u4eec\u90fd\u4f1a\u53bb\u5237\u65b0\u4e00\u6b21\uff0c\u786e\u4fdd\u53ea\u8981\u7528\u6237\u4e00\u76f4\u5728\u64cd\u4f5c\uff0c\u90a3\u4e48\u5b83\u8fd9\u4e2atoken\u5c31\u4e0d\u4f1a\u6d88\u5931\u3002\u597d\uff0c\u8fd9\u662f\u6211\u4eec\u5237\u65b0token\u7684\u4e00\u4e2a\u76ee\u7684\uff0c\u90a3\u4e48\u6700\u540e\u653e\u884c\u5c31\u53ef\u4ee5\u4e86\u3002\u4f46\u662f\u6211\u4eec\u73b0\u5728\u80fd\u4e0d\u80fd\u771f\u6b63\u7684\u8fbe\u6210\uff0c\u8bf4\u662f\u53ea\u8981\u7528\u6237\u4e00\u76f4\u5728\u8bbf\u95ee\u5c31\u4e0d\u4f1a\u8fc7\u671f\uff0c\u8fd8\u4e0d\u592a\u884c\uff0c\u4e3a\u4ec0\u4e48\uff1f\u56e0\u4e3a\u62e6\u622a\u5668\u5b83\u62e6\u622a\u7684\u8def\u5f84\u4e0d\u662f\u4e00\u5207\u8def\u5f84\uff0c\u5b83\u62e6\u7684\u662f\u90a3\u4e9b\u9700\u8981\u505a\u767b\u5f55\u6821\u9a8c\u7684\u8def\u5f84\u3002<\/p>\n\n\n\n<p>\u6bd4\u5982\u8bf4\u6211\u4eec\u7684userme\uff0c\u518d\u6bd4\u5982\u8bf4\u5c06\u6765\u7528\u6237\u7684\u4e0b\u5355\u652f\u4ed8\u7b49\u7b49\u8fd9\u6837\u7684\u4e00\u4e9b\u5bf9\u7528\u6237\u4fe1\u606f\u6709\u9700\u6c42\u7684\u8def\u5f84\uff0c\u6216\u8005\u8bf4\u88ab\u62e6\u622a\u5668\u62e6\u622a\u7684\u8def\u5f84\uff0c\u4f46\u5b83\u4e0d\u662f\u62e6\u622a\u4e00\u5207\u3002\u6240\u4ee5\u8fd9\u5c31\u5bfc\u81f4\u4e86\u5982\u679c\u8bf4\uff0c\u6211\u4eec\u7684\u7528\u6237\u4e00\u76f4\u8bbf\u95ee\u7684\u662f\u4e0d\u9700\u8981\u767b\u5f55\u7684\u8fd9\u6837\u7684\u4e00\u4e9b\u9875\u9762\u3002\u4e3e\u4e2a\u4f8b\u5b50\uff0c\u6211\u4eec\u7684\u9996\u9875\uff0c\u5546\u6237\u7684\u8be6\u60c5\u9875\uff0c\u90a3\u4e48\u8fd9\u4e9b\u90fd\u662f\u4e0d\u9700\u8981\u767b\u5f55\u5c31\u80fd\u770b\u7684\uff0c\u90a3\u4e48\u8fd9\u6837\u62e6\u622a\u5668\u5c31\u4e0d\u751f\u6548\uff0c\u90a3\u4e48\u5b83\u5c31\u4e0d\u4f1a\u53bb\u5237\u65b0\u3002\u63a5\u4e0b\u6765\u5982\u679c\u8bf430\u5206\u949f\u4ee5\u540e\uff0c\u5c3d\u7ba1\u7528\u6237\u4e00\u76f4\u5728\u8bbf\u95ee\uff0c\u7528\u6237\u7684\u767b\u5f55\u662f\u4e0d\u662f\u5c31\u4e5f\u6d88\u5931\u4e86\uff0c\u6240\u4ee5\u8fd9\u662f\u4e0d\u592a\u5408\u7406\u7684\u4e00\u4e2a\u70b9\uff0c\u9488\u5bf9\u8fd9\u4e2a\u70b9\u6211\u4eec\u8be5\u600e\u4e48\u4f18\u5316\uff0c\u6211\u4eec\u53ef\u4ee5\u8fd9\u4e48\u6765\u505a\u3002<\/p>\n\n\n\n<p>&nbsp;\u8fd9\u91cc\u610f\u601d\u662f\u5982\u679c\u4f60\u767b\u5f55\u4e86\uff0c\u4f46\u662f\u4f60\u8bbf\u95ee\u7684\u662f\u4e3b\u9875\uff0c\u4e3b\u9875\u4e0d\u9700\u8981\u62e6\u622a\uff0c\u65e2\u7136\u4e0d\u80fd\u5237\u65b0token\uff0c\u5c31\u5728\u4f60\u770b\u9996\u9875\u6216\u8005\u5546\u5bb6\u7684\u65f6\u5019\u4f60\u7a81\u7136\u4e0b\u5355\uff0c\u8fd9\u65f6token\u8fc7\u671f\u5c31\u5931\u8d25\u4e86<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u89e3\u51b3\u767b\u5f55\u72b6\u6001\u5237\u65b0\u7684\u95ee\u9898<\/h3>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"327\" width=\"680\" src=\"https:\/\/i-blog.csdnimg.cn\/direct\/9a54184f4936433f8def99e2e62be846.png\" alt=\"\"><\/p>\n\n\n\n<p>\u5728\u539f\u6709\u8fd9\u4e2a\u62e6\u622a\u5668\u7684\u57fa\u7840\u4e0a\uff0c\u518d\u52a0\u4e00\u4e2a\u65b0\u7684\u62e6\u622a\u5668\uff0c\u8fd9\u6837\u7528\u6237\u8bf7\u6c42\u5c31\u8981\u5148\u7ecf\u8fc7\u7b2c\u4e00\u4e2a\u8fde\u63a5\u5668\uff0c\u518d\u7ecf\u8fc7\u7b2c\u4e8c\u4e2a\u3002\u56e0\u4e3a\u4ec0\u4e48\uff1f\u6211\u4eec\u7684\u7b2c\u4e8c\u4e2a\u8fde\u63a5\u5668\u5b83\u62e6\u622a\u7684\u662f\u9700\u8981\u767b\u5f55\u7684\u90a3\u4e9b\u4e1c\u897f\uff0c\u800c\u4e0d\u662f\u6240\u6709\u7684\u8def\u5f84\uff0c\u6240\u4ee5\u6ca1\u6709\u529e\u6cd5\u7ed9\u6240\u6709\u7684\u8bf7\u6c42\u90fd\u505a\u5237\u65b0\uff0c\u5bf9\u4e0d\u5bf9\uff1f\u6211\u5728\u65b0\u52a0\u8fd9\u4e2a\u8fde\u7ebf\u6211\u5c31\u8ba9\u4ed6\u5e72\u4ec0\u4e48\uff1f\u62e6\u622a\u4e00\u5207\u8def\u5f84\u3002\u4e5f\u5c31\u662f\u8bf4\u6240\u6709\u8bf7\u6c42\u90fd\u4f1a\u7ecf\u8fc7\u6211\uff0c\u6211\u662f\u4e0d\u662f\u53ef\u4ee5\u5728\u62e6\u622a\u5668\u91cc\u6765\u505a\u5237\u65b0token\u6709\u6548\u671f\u7684\u52a8\u4f5c\uff1f<\/p>\n\n\n\n<p>\u6211\u5728\u8fd9\u91cc\u83b7\u53d6token\uff0c\u83b7\u53d6rest\u7684\u7528\u6237\u3002\u5f53\u7136\u4e86\u6709\u7684\u65f6\u5019\u4f60\u67e5\u7684\u65f6\u5019\u8bf4\u4e07\u4e00\u4e0d\u5b58\u5728\u600e\u4e48\u529e\uff1f\u597d\u4e0d\u5b58\u5728\u6211\u653e\u884c\u6211\u4e0d\u7ba1\uff0c\u53ea\u8981\u4f60\u5b58\u5728\uff0c\u6211\u5c31\u7ed9\u4f60\u4fdd\u5b58\u5230\u6240\u6709logo\u505a\u5237\u65b0\u7684\u52a8\u4f5c\u3002\u4e5f\u5c31\u662f\u8bf4\u6211\u8fd9\u91cc\u4e0d\u505a\u62e6\u622a\uff0c\u6211\u8fd9\u4e2a\u62e6\u622a\u5668\u867d\u7136\u662f\u62e6\u622a\u4e00\u4e9b\u8def\u5f84\uff0c\u4f46\u662f\u552f\u4e00\u76ee\u7684\u5176\u5b9e\u5c31\u662f\u4fdd\u5b58\u4e86\u6240\u6709logo\u548c\u5237\u65b0\u7684\u52a8\u4f5c\u3002<\/p>\n\n\n\n<p>\u597d\uff0c\u90a3\u4e48\u8fd9\u6837\u662f\u4e0d\u662f\u53ef\u4ee5\u786e\u4fdd\u4e00\u5207\u8bf7\u6c42\u90fd\u4f1a\u89e6\u53d1\u521b\u65b0\u7684\u52a8\u4f5c\uff1f\u62e6\u622a\u7684\u52a8\u4f5c\u5728\u54ea\u505a\uff1f\u5728\u7b2c\u4e8c\u4e2a\u62e6\u622a\u5668\u91cc\uff0c\u5728\u7b2c\u4e8c\u4e2a\u62e6\u622a\u5668\u91cc\u6211\u5c31\u4e0d\u7528\u91cd\u590d\u4e0a\u9762\u8fd95\u6b65\u4e86\uff0c\u6211\u53ea\u9700\u8981\u4eceThreadLocal\u91cc\u9762\u67e5\uff0c\u56e0\u4e3a\u4f60\u8fd9\u4e2a\u6765\u5199\u5df2\u7ecf\u628a\u5b83\u4fdd\u5b58\u5230\u7b97\u4e86\u5bf9\u5427\uff1f\u6211\u53bb\u67e5\u67e5\u4e86\u4ee5\u540e\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u6211\u5c31\u62e6\u622a\uff0c\u5982\u679c\u5b58\u5728\u6211\u662f\u4e0d\u662f\u5c31\u53ef\u4ee5\u653e\u884c\u4e86\uff1f\u90a3\u4e5f\u5c31\u662f\u7b2c\u4e00\u4e2a\u8054\u7cfb\u5b83\u7684\u6838\u5fc3\u5de5\u4f5c\u5c31\u662f\u5f97\u5230\u7528\u6237\u4fdd\u5b58\u8d77\u6765\uff0c\u5e76\u4e14\u5237\u65b0\u3002&nbsp; \u90a3\u4e48\u7b2c\u4e8c\u4e2a\u5f15\u8d77\u7684\u6838\u5fc3\u52a8\u4f5c\u624d\u662f\u505a\u767b\u5f55\u62e6\u622a\uff0c\u4e24\u4e2a\u5206\u5de5\u8fd9\u4e2a\u95ee\u9898\u5c31\u5f97\u5230\u89e3\u51b3\u4e86\u3002\u5728utils\u4e2d\u65b0\u5efa\u4e00\u4e2aRefreshTokenInterceptor<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.hmdp.utils;\n\nimport cn.hutool.core.bean.BeanUtil;\nimport cn.hutool.core.util.StrUtil;\nimport com.hmdp.dto.UserDTO;\nimport org.springframework.data.redis.core.StringRedisTemplate;\nimport org.springframework.web.servlet.HandlerInterceptor;\n\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\nimport java.util.Map;\nimport java.util.concurrent.TimeUnit;\n\nimport static com.hmdp.utils.RedisConstants.LOGIN_USER_KEY;\nimport static com.hmdp.utils.RedisConstants.LOGIN_USER_TTL;\n\npublic class RefreshTokenInterceptor implements HandlerInterceptor {\n\n    private StringRedisTemplate stringRedisTemplate;\n\n    public RefreshTokenInterceptor(StringRedisTemplate stringRedisTemplate) {\n        this.stringRedisTemplate = stringRedisTemplate;\n    }\n\n    @Override\n    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {\n        \/\/ 1.\u83b7\u53d6\u8bf7\u6c42\u5934\u4e2d\u7684token\n        String token = request.getHeader(\"authorization\");\n        if (StrUtil.isBlank(token)) {\n            return true;\n        \/*\u6b64\u5904return true\u662f\u5bf9\u7684\uff0c\u82e5return false\uff0c\u7b2c\u4e00\u6b21\u8bbf\u95ee\u767b\u5f55\u9875\u9762\u65f6\u5c31\u4f1a\u88ab\u62e6\u622a\uff1b\n\u82e5return true\uff0c\u7b2c\u4e00\u6b21\u8bbf\u95ee\u767b\u5f55\u9875\u4f1a\u8fdb\u5165Login\u62e6\u622a\u5668\uff0c\u7531\u4e8e\u767b\u5f55\u9875\u4e3a\u653e\u884c\u8def\u5f84\uff0c\u653e\u884c*\/\n        }\n        \/\/ 2.\u57fa\u4e8eTOKEN\u83b7\u53d6redis\u4e2d\u7684\u7528\u6237\n        String key  = LOGIN_USER_KEY + token;\n        Map&lt;Object, Object&gt; userMap = stringRedisTemplate.opsForHash().entries(key);\n        \/\/ 3.\u5224\u65ad\u7528\u6237\u662f\u5426\u5b58\u5728\n        if (userMap.isEmpty()) {\n            return true;\n        }\n        \/\/ 5.\u5c06\u67e5\u8be2\u5230\u7684hash\u6570\u636e\u8f6c\u4e3aUserDTO\n        UserDTO userDTO = BeanUtil.fillBeanWithMap(userMap, new UserDTO(), false);\n        \/\/ 6.\u5b58\u5728\uff0c\u4fdd\u5b58\u7528\u6237\u4fe1\u606f\u5230 ThreadLocal\n        UserHolder.saveUser(userDTO);\n        \/\/ 7.\u5237\u65b0token\u6709\u6548\u671f\n        stringRedisTemplate.expire(key, LOGIN_USER_TTL, TimeUnit.MINUTES);\n        \/\/ 8.\u653e\u884c\n        return true;\n    }\n\n    @Override\n    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {\n        \/\/ \u79fb\u9664\u7528\u6237\n        UserHolder.removeUser();\n    }\n}\n<\/code><\/pre>\n\n\n\n<p>\u4fee\u6539LoginInterceptor&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.hmdp.utils;\n\nimport cn.hutool.core.bean.BeanUtil;\nimport cn.hutool.core.util.StrUtil;\nimport com.hmdp.dto.UserDTO;\nimport com.hmdp.entity.User;\nimport org.springframework.data.redis.core.StringRedisTemplate;\nimport org.springframework.web.servlet.HandlerInterceptor;\n\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\nimport javax.servlet.http.HttpSession;\nimport java.util.Map;\nimport java.util.concurrent.TimeUnit;\n\npublic class LoginInterceptor implements HandlerInterceptor {\n\n    @Override\n    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {\n        \/\/1.\u5224\u65ad\u662f\u5426\u9700\u8981\u62e6\u622a\uff08ThreadLocal\u4e2d\u662f\u5426\u6709\u7528\u6237\uff09\n        if (UserHolder.getUser() == null) {\n            \/\/\u6ca1\u6709\uff0c\u9700\u8981\u62e6\u622a\uff0c\u8bbe\u7f6e\u72b6\u6001\u7801\n            response.setStatus(401);\n            \/\/\u62e6\u622a\n            return false;\n            \/\/\u6709\u7528\u6237\uff0c\u5219\u653e\u884c\n        }\n        \/*\u4ece\u767b\u5f55\u62e6\u622a\u5668\u7684\u540d\u5b57LoginInterceptor\u5c31\u80fd\u770b\u51fa\n        \u5176\u5b9e\u4eba\u5bb6\u53ea\u9700\u8981\u505a\u4e00\u4ef6\u4e8b  \u5c31\u662f\u5224\u65ad\u7ebf\u7a0b\u4e2d\u6709\u6ca1\u6709\u7528\u6237\u5c31\u53ef\u4ee5\u4e86  \u5176\u4ed6\u4e8b\u60c5\u4ea4\u7ed9\u5176\u4ed6\u7c7b\u505a*\/\n        return true;\n    }\n    @Override\n    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {\n        UserHolder.removeUser();\n    }\n\n}\n<\/code><\/pre>\n\n\n\n<p>&nbsp;\u6211\u4eec\u5e0c\u671b\u7684\u662frefresh\u5148\u6267\u884c\uff0c\u53ea\u6709\u4ed6\u5148\u6267\u884c\u4e86\u62ff\u5230\u6211\u4eec\u7684\u7528\u6237\u4fdd\u5b58\u5230\u4e86sever local\uff0c\u90a3\u4e48\u5728\u62e6\u622a\u624d\u80fd\u53bb\u505a\u62e6\u622a\u7684\u5224\u65ad\uff0c\u662f\u4e0d\u662f\u8fd9\u6837\u5b50\uff1f\u6240\u4ee5\u8bf4\u8fd9\u4e24\u4e2a\u5176\u5b9e\u662f\u6709\u4e2a\u5148\u540e\u987a\u5e8f\u7684\uff0c\u90a3\u4e48\u6211\u4eec\u600e\u4e48\u63a7\u5236\u62e6\u622a\u5668\u7684\u6267\u884c\u987a\u5e8f\u5462\uff1f\u4e8b\u5b9e\u4e0a\u5728\u6211\u4eec\u8fd9\u4e2a\u5730\u65b9\u6211\u4eec\u6dfb\u52a0\u62e6\u622a\u5668\u7684\u65f6\u5019\uff0c\u5927\u5bb6\u53ef\u4ee5\u6839\u636e\u770b\u4e00\u773c\uff0c\u5728\u6211\u4eec\u6dfb\u52a0\u62e6\u622a\u5668\u7684\u65f6\u5019\uff0c\u62e6\u622a\u5668\u5176\u5b9e\u4f1a\u88ab\u6ce8\u518c\u6210\u4e00\u4e2a\u4e1c\u897f\u53eb intercept registration. \u5c31\u662f\u6ce8\u518c\u5668\u3002<\/p>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"212\" width=\"680\" src=\"https:\/\/i-blog.csdnimg.cn\/direct\/fada6b132daa4618b1def6f96923a4e3.png\" alt=\"\"><\/p>\n\n\n\n<p>\u90a3\u4e48\u6ce8\u518c\u5668\u91cc\u9762\u5176\u5b9e\u6709\u4e00\u4e2a\u4ec0\u4e48\u4e1c\u897f\uff0c\u6709\u4e00\u4e2aorder\uff0c\u5c31\u662f\u6765\u4eea\u5668\u7684\u6267\u884c\u987a\u5e8f\uff0c\u5728\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u6240\u6709\u8054\u7cfb\u7684\u987a\u5e8f\u90fd\u662f0\uff0c\u90a3\u90fd\u662f0\u7684\u60c5\u51b5\u4e0b\u4ed6\u4eec\u600e\u4e48\u6267\u884c\u7684\uff0c\u6309\u7167\u6dfb\u52a0\u987a\u5e8f\u6267\u884c\u3002 \u6240\u4ee5\u8bf4\u5982\u679c\u7b80\u5355\u6765\u8bf4\u7684\u8bdd\uff0c\u6211\u4eec\u5176\u5b9e\u53ea\u9700\u8981\u5e72\u4ec0\u4e48\uff1f\u5148\u6dfb\u52a0addInterceptor\u518d\u6dfbaddInterceptor\u662f\u4e0d\u5c31ok\u4e86\uff1f\u4f46\u662f\u5982\u679c\u4f60\u60f3\u63a7\u5236\u7684\u4e25\u8c28\u4e00\u70b9\uff0c\u4f60\u5c31\u53ef\u4ee5\u5e72\u4ec0\u4e48\uff1f\u7ed9\u4ed6\u7684order\u8c03\u7684\u7a0d\u5fae\u5c0f\u4e00\u70b9\uff0c\u7136\u540e\u7ed9\u54e5\u4eec\u7684order\u8c03\u5230\u4ec0\u4e48\u5927\u4e00\u70b9\uff0c\u56e0\u4e3a\u503c\u8d8a\u5927\uff0c\u6267\u884c\u7684\u4f18\u5148\u7ea7\u53cd\u800c\u8d8a\u4f4e\uff0c\u8d8a\u5c0f\u4f18\u5148\u7ea7\u662f\u8d8a\u9ad8\u7684\uff0c\u8fd9\u6837\u7684\u8bdd\u6211\u4eec\u5c31\u53ef\u4ee5\u786e\u4fdd\u4ec0\u4e48\uff1f\u4e0b\u9762\u5148\u6267\u884c\u4e0a\u9762\u90a3\u4e2a\u540e\u6267\u884c\u4e86\u3002Ok\uff0c\u90a3\u4e48\u6211\u4eec\u5c31\u628a\u4e24\u4e2a\u8fde\u63a5\u5668\u6dfb\u52a0\u5b8c\u6bd5\u4e86\uff0c\u662f\u767b\u5f55\u62e6\u622a\u5668\uff0c\u90a3\u4e48\u4e0b\u8fb9\u90a3\u4e2a\u662ftoken\u5237\u65b0\u7684\u62e6\u622a\u5668\u3002&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.hmdp.config;\n\nimport com.hmdp.utils.LoginInterceptor;\nimport com.hmdp.utils.RefreshTokenInterceptor;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.data.redis.core.StringRedisTemplate;\nimport org.springframework.web.servlet.config.annotation.InterceptorRegistry;\nimport org.springframework.web.servlet.config.annotation.WebMvcConfigurer;\n\nimport javax.annotation.Resource;\n\n@Configuration\npublic class MvcConfig implements WebMvcConfigurer {\n\n    @Resource\n    private StringRedisTemplate stringRedisTemplate;\n\n    @Override\n    public void addInterceptors(InterceptorRegistry registry) {\n        \/\/ \u767b\u5f55\u62e6\u622a\u5668\n        registry.addInterceptor(new LoginInterceptor(stringRedisTemplate))\n                .excludePathPatterns(\n                        \"\/shop\/**\",\n                        \"\/voucher\/**\",\n                        \"\/shop-type\/**\",\n                        \"\/upload\/**\",\n                        \"\/blog\/hot\",\n                        \"\/user\/code\",\n                        \"\/user\/login\"\n                ).order(1);\n        \/\/ token\u5237\u65b0\u7684\u62e6\u622a\u5668\n        registry.addInterceptor(new RefreshTokenInterceptor(stringRedisTemplate)).addPathPatterns(\"\/**\").order(0);\n    }\n}<img loading=\"lazy\" decoding=\"async\" height=\"15\" width=\"15\" src=\"blob:https:\/\/eve2333.top\/977ba4bd-4e4f-4607-b045-d38917d50dee\"><\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\u00a0 &nbsp;\u672c\u7bc7\u5c06\u4e3b\u8981\u9610\u8ff0\u77ed\u4fe1\u767b\u5f55\u7684\u76f8\u5173\u77e5\u8bc6\uff0c\u611f\u8c22\u9ed1\u9a6c\u7a0b\u5e8f\u5458\u5f00\u6e90\uff0c\u611f\u8c22\u63d0\u4f9b\u521d\u59cb\u6e90\u6587\u4ef6\uff08\u7ed9\u5230\u7684\u662f\u5b9e\u6218\u7b2c7\u96c6\u5f00\u59cb\u7684\u4ee3\u7801\uff09\u3010Redi &#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"emotion":"","emotion_color":"","title_style":"","license":"","footnotes":""},"categories":[3],"tags":[26,16,20],"class_list":["post-960","post","type-post","status-publish","format-standard","hentry","category-3","tag-redis","tag-sql","tag-20"],"_links":{"self":[{"href":"https:\/\/eve2333.top\/index.php?rest_route=\/wp\/v2\/posts\/960","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/eve2333.top\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/eve2333.top\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/eve2333.top\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/eve2333.top\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=960"}],"version-history":[{"count":1,"href":"https:\/\/eve2333.top\/index.php?rest_route=\/wp\/v2\/posts\/960\/revisions"}],"predecessor-version":[{"id":961,"href":"https:\/\/eve2333.top\/index.php?rest_route=\/wp\/v2\/posts\/960\/revisions\/961"}],"wp:attachment":[{"href":"https:\/\/eve2333.top\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=960"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/eve2333.top\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=960"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/eve2333.top\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=960"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}