1、发送邮件
使用spring-boot-starter-mail这个包
2、开发注册功能
(1)访问注册页面
功能拆解:
点击顶部的注册按钮,打开注册页面
新增文件:controller->login
具体实现过程:
增加一个getregisterpage的方法,返回注册页面。
对注册模版进行修改。
修改首页模版里的首页和注册的链接。
(2)提交注册数据
功能拆解:
通过表单提交数据
服务端判断账号是否已存在,邮箱是否已注册
服务端发送激活邮箱
具体实现过程:
service->userservice里增加注册方法,完成上述功能。
(3)激活注册账号
具体实现过程:
在service->userservice里增加激活方法,返还激活结果。
在controller->logincontroller里增加激活方法,根据service里的激活方法返回的结果进行判断,如果结果表示成功,就给模版添加success,如果失败,就给模版添加defeat
3、会话管理
分布式时使用session会有问题。解决方法:粘性session,同一个ip分给同一个服务器,但是负载不均衡;同步session,某个服务器上有session后同步给别的服务器,但是影响性能并且服务器产生耦合;共享session,让一个服务器专门存session,但是这台服务器挂了就完了;主流方法:将敏感数据存redis(非关系型)数据库,不敏感消息存cookie。
Cookie 和 Session 是两种在Web开发中常用的保存用户状态信息的技术。
-
Cookie:
- 定义:Cookie是一种在远程浏览器端存储数据,并以此来跟踪和识别用户的机制。服务器通过HTTP响应头向客户端浏览器发送一些数据,浏览器会将这些数据存储起来,并在后续的HTTP请求中将这些数据作为HTTP请求头发送回服务器。
- 存储位置:存储在用户的浏览器上。
- 存储大小:每个Cookie的大小通常不超过4KB。
- 存储时间:有时间限制,可以设定为持久化或者是会话级别的(当浏览器关闭时Cookie会被删除)。
- 安全性:相对较低,因为保存在客户端,所以不应该用来存储敏感信息。
- 用途:用于存储一些不太敏感的信息,例如用户的登录状态、购物车信息、用户偏好设置等。
-
Session:
- 定义:Session是一种在服务器端保持状态信息的解决方案。当客户端首次请求服务器时,服务器会创建一个session,并将相关信息保存在服务器上,然后将session的标识符通过Cookie或URL重写的方式传递给客户端,客户端再次访问时会携带该标识符,服务器会查找已经创建的session并恢复用户的状态信息。
- 存储位置:存储在服务器上。
- 存储大小:由服务器的内存大小决定,一般来说比Cookie能存储的数据要多。
- 存储时间:有时间限制,通常为30分钟。
- 安全性:相对较高,因为保存在服务器端,客户端无法直接访问。
- 用途:用于存储敏感信息,例如用户的登录信息、购物车信息等。
4、生成验证码
kapcha
5、开发登录、退出功能
功能拆解:
(1)访问登录页面
(2)登录
验证账号、密码、验证码
成功时,生成登录凭证,发送给客户端
失败时,跳转回登陆页面
(3)退出
将登陆凭证改为失效状态
跳转至网站首页
具体实现:
登录凭证(login ticket)通常与cookie和session一起使用来验证用户的登录状态。以下是一种常见的使用流程:
-
用户登录:当用户首次登录应用时,后端会验证用户的凭据(如用户名和密码)。如果验证通过,后端将创建一个登录凭证(login ticket),并将其保存在数据库中。
-
设置cookie:创建登录凭证后,后端将把登录凭证的值(通常是一个唯一的随机字符串)放入一个cookie中,并将该cookie发送到用户的浏览器。浏览器会将该cookie保存在本地。
-
后续请求:当用户向服务器发送后续请求(例如浏览页面、提交表单等)时,浏览器会自动将之前保存的cookie一同发送到服务器。服务器可以通过cookie中的登录凭证值来验证用户的登录状态。
-
验证登录凭证:当服务器收到一个包含登录凭证的请求时,它会将登录凭证与数据库中的记录进行匹配。如果登录凭证有效(未过期、未被注销、与数据库中的记录匹配),则服务器会视用户为已登录,并处理用户的请求。如果登录凭证无效,服务器可能会要求用户重新登录。
-
登出:当用户选择登出时,服务器将会使数据库中的登录凭证无效(例如设置其状态为1),并可能清除用户浏览器中的cookie。这样,即使用户再次发送之前的登录凭证,服务器也不会再认为用户是登录状态。
6、显示登录信息
功能拆解:
根据登陆与否,首页显示不同内容
具体实现:
使用拦截器。 拦截器在请求之前从cookie里获取ticket,根据ticket获取到user。在请求之后,将user给模版。在模版之后清除数据。
在Spring Boot中,你可以使用拦截器(Interceptor)来实现基于用户登录状态的内容显示。拦截器可以拦截和处理请求,再将请求传递到相应的控制器(Controller)。
下面是一个简单的例子,展示如何使用拦截器实现这个功能:
- 创建拦截器类:首先,你需要创建一个类并实现
HandlerInterceptor
接口。这个类里有三个方法:第一个是获取用户,第二个是将用户放入模版,第三个是清除用户 - 注册拦截器:在配置类中,实现
WebMvcConfigurer
接口并重写addInterceptors
方法,注册拦截器。配置拦截器的作用范围。 - 在控制器中使用用户信息:在控制器方法中,你可以通过
HttpServletRequest
对象获取之前存入请求中的用户信息,并根据用户登录状态显示不同的内容。在community项目中,直接改index.html模版。
7、账号设置
功能拆解:
上传头像和修改密码(访问账号设置页面,上传头像,获取头像)
具体实现:
在login controller里添加上传和获取头像的方法:
-
getSettingPage()方法:在"/setting"路径上,通过GET方法请求设置页面。
-
uploadHeader()方法:在"/upload"路径上,通过POST方法上传头像图片。该方法接收一个
MultipartFile
参数,该参数表示用户上传的文件。该方法首先检查文件是否存在、是否有后缀。然后将文件保存到指定路径,并将头像的URL更新到数据库中。最后,该方法将重定向到首页。- 先检查上传的文件是否为空,为空则返回一个错误消息。
- 提取文件的后缀名,并检查其有效性。
- 生成一个随机的文件名,并确定文件的存储路径。
- 使用
transferTo()
方法将上传的文件保存到指定路径。 - 更新用户的头像URL,并保存到数据库中。
- 重定向到首页。
-
getHeader()方法:在"/header/{fileName}"路径上,通过GET方法请求头像图片。该方法接收一个
@PathVariable
参数fileName
,表示请求的头像文件名。该方法会根据文件名找到服务器上的文件,然后将文件作为HTTP响应发送回客户端。- 提取文件的后缀名,并设置响应的ContentType。
- 使用
FileInputStream
和HttpServletResponse
的OutputStream
来将文件读入内存,并写入到HTTP响应中。 - 如果发生IO异常,则在日志中记录错误消息。
问题:
头像的url和本地的upload路径有什么关系吗
回答:
头像的URL和本地的上传路径有直接的关系。URL通常是一个可以在Web浏览器中访问的地址,而上传路径是文件在服务器文件系统上的物理存储位置。当用户请求查看头像时,服务器会根据URL找到对应的本地文件路径,然后将文件发送给用户。
下面是你的代码中这两者关系的详细说明:
-
你的代码中,当用户上传新的头像图片时,
uploadHeader()
方法会将图片文件保存到uploadPath
指定的本地目录中。这个uploadPath
是文件在服务器上的物理存储路径。 -
接着,代码会生成一个可以在Web浏览器中访问的URL,然后将这个URL保存到数据库中,作为用户头像的Web访问地址。这个URL由
domain
、contextPath
和文件名组成。 -
最后,当用户请求查看头像时(比如访问
/user/header/xxx.png
),getHeader()
方法会根据fileName
参数找到本地存储的文件(使用uploadPath
和fileName
构造完整的本地路径),然后将文件发送给用户。
8、检查登录状态
功能拆解:
使未登录用户无法使用某些功能。使用拦截器,拦截所有请求,只处理带有该注解的方法。
自定义注解:
元注解是用来标记和定义其他注解的注解,它们提供了注解应该如何被处理的元数据。
下面是几个常见的元注解及其用途:
-
@Retention: 该元注解定义了注解的保留策略。它有三个可选值:RetentionPolicy.SOURCE(只在源代码中保留)、RetentionPolicy.CLASS(在.class文件中保留)和RetentionPolicy.RUNTIME(在运行时保留,可通过反射访问)。
-
@Target: 该元注解指定了注解可以应用于哪些Java元素(类、方法、字段等)。
-
@Documented: 该元注解表示当使用javadoc生成文档时,该注解应该被包含在其中。
-
@Inherited: 该元注解表示如果一个类使用了被此元注解标记的注解,那么它的子类也会自动继承这个注解。
具体实现:
1、新增login required注解
2、对需要限制(设置头像)的两个方法打上注解
3、创建login required拦截器,里面重写preHandle方法:这个方法读取method,取method的loginrequired注解,如果是login required注解并且用户为空,那就重定向到登录页面。