【个人随手记】
2.1发送邮件
开发社区的登录模块





那么如何利用thymleaf模板引擎发送一个html邮件。


开发注册功能

将功能按照请求拆解,可以大概分析出来是有上面三个请求。
每一个请求都是先开发数据访问层,然后业务层,最后视图层。


这两步骤并没有发挥替换的作用呀。因为原来的还在。
- 开发第二个请求,提交注册的数据
- 导包,判断字符串集合数据是不是空值的情况。
commons lang3 apache推出 -
将网站的域名配置好。目前就是配置的本机的ip地址。因为发邮件的时候需要有链接连接到我们的网站。连接在开发测试和上线的时候是不一样的,需要弄成可配置的。
image.png
- 写一个工具类,提供两个方法
这个工具类不适用容器托管了,方法是静态的公有方法
UUID生成的字符串中间包含了字母和横线 ,我们一般不想用横线。
md5算法只能加密,不能解密。每一个字符串对应的是一个确定的字符串。简单的密码都是可以得到的。
非常同意进行破解,因此一定要加上随机的字符串作为盐。
StringUtils.isBlank(key)它能够判断一个字符串是不是空的,或者是不是null或者是不是一个空格非常方便。

-
开发注册的业务
注册时针对用户进行的操作,因此在userService中进行操作。但是需要注入模板引擎,和邮件客户端,因为需要发邮件。激活码中需要办函域名和项目名。
image.png

接下来时注册的业务:






中间页面:
在模板文件中,绝对路径不进行更改,只有相对路径才进行更改。


- 激活注册账号
- 激活成功
- 激活成功之后重复激活
-
激活码是伪造或者瞎编的。
image.png
model用来给模板传参,

2.11会话管理
什么是会话管理:

什么是cookie:


-
理解cookie的语法
第一步:浏览器首次访问服务器,服务器设置cookies并将cookie设置为响应头传给浏览器。
cookie默认存储在内存中,当浏览器关闭的时候就失效了,但是可以通过设置cookies的保存时间,将cookie设置在硬盘中。
image.png
下面这个图中有cookie的最大时间等相关信息。
image.png
-
@CookieValue这个注解是用来取出重多cookies中的某一个。而不是将所有的cookies都取出来然后进行遍历,这样太麻烦了。
服务器可以获得cookies进行一些验证,也可以传递给模板引擎。
image.png
但是coolkie存在于浏览器,不安全,因此尽量不要存储密码等敏感隐私的内容
并且,cookie每次都参与从浏览器到服务器,占用流量,对于流量来说是一种浪费。
可以使用session:

对于以上这两个需要看情况使用。
session的工作流程:
session的本质上是依赖于cookie的。

-
演示session的使用:
image.png
cookies是需要来回进行传递,因此只能存储一对字符串作为键值对,但是session可以存储各种数据,除此之外,session是不需要进行创建的,springmvc会帮我们自动注入对象。

path默认是整个项目下面都有效。没有时限的限制,因此在浏览器关闭之后消除了cookie(sessionId)。
结果:


因此若想进行连续的会话,究竟是使用cookie还是session需要根据具体的情况来确定。尽量使用cookie。
只有一台服务器的话可以使用session,但是在分布式部署的情况下,尽量不使用session。会有什么问题呢?

解决办法:
- 粘性session:对于同一个IP分配给同一个服务器进行处理。难以保证负载均衡。
-
同步session:某一个服务器创建了session之后,会同步给所有的其他服务器。但是服务器之间会有相互的影响,没有做到完全的独立。
3。 共享session:有一台专门用来存储session的服务器,其他所有的服务器都先访问这个服务器。这台服务器一旦挂掉,就玩完了。
image.png
4.将会话数据存储在数据库中,但是关系型数据库是将数据存储在硬盘中,并发量比较高的时候会有影响,因此使用nosql,Redis,这个是目前比较常见的处理方式。
数据库之间进行集群或者是组成备份时比较常见的,性能也会比较高。

2.17生成验证码


写道pom.xml中;
为这个小包写一个配置类:




这个实例化的Bean可以创建验证码和图片,
code->surround with可以使用try catch 包围代码块。
向浏览器输出图片可以使用的工具ImageIo.write()。这个流不用关闭,springmvc进行维护。
使用日志记录错误。

它的返回结果是空的,需要手动使用response进行输出。敏感数据,存在session中。
看一下结果:

应用到登陆页面:

模板里 @{}就相当于是补充了/community。
有些浏览器比较智能,会认为访问的路径没有发生变化,因此需要添加一些变化项。

ctrl+F9重新部署
将鼠标放在上面会发现左下角的javascript发生了变化。
2.23开发登录,退出功能

登录凭证:

写一个登陆凭证实体类:

在dao和mapper下面写相关方法和sql实现。

这一次我们不再写配置文件了,而是写注解。
@options对sql进行相关的设置,
@options(useGeneratedKey = true, keyProperty = "id")使用主键自增长,同时将生成的主键赋值给id。

注解里面也可以写动态的sql。如下所示:
如果想使用if这种标签,必须加上<script>来说明这表示脚本。

进行测试如下:

数据库第一条的id就是1。

经过以上的测试说明mapper没有问题。
接下来开始写业务层:



登陆成功了,生成登录凭证,以后每次访问服务器都拿着凭证。

开始写表现层:
两个方法的访问路径可以是一样的,但是method不能是一样的。


然后就是设置页面。
对于普通的参数而言,并不会自动封装到model里面,只有对象才能自动封装。但是他们存在于request请求中。当执行到页面的时候,request还没有消失,请求还没有结束,因此我们依然可以进行取值。
request.getParameter("username")相当于param.username。



重定向的时候,默认就是get请求。
最后更改一下index.html中退出登录的href。
2.27 显示登录信息

显示登录信息就是指根据是否登录来决定页面的显示内容。
每一个请求都需要进行判断。如果在每一个controller中都加上判断,太繁杂,耦合度比较高。最终使用spring的拦截器。
在controller文件夹下面创建一个intercepter文件夹。
在preHandler方法中可以处理自己的请求或者是响应吗??老师上课说了一下。


postHandler是在controller之后,模板之前执行
afterCompletion是在模板之后执行。
-
配置拦截器,除去静态资源,设置必须访问的路径。
image.png
拦截器中的参数Object handler表示拦截的目标,也就是某一个方法login()。
因此,写一个类,稍微进行配置,就可以实现拦截器的使用。

每次请求都需要进行上述的过程。因此应该写一个拦截器来实现。
通过request可以得到cookie。
-
首先在工具包下面新建一个文件,是用来取出cookie的。
image.png
-
userService中新增加一个查询ticket的方法。
image.png
-
在下面的preHandler中我们不会使用查询到的信息,我们会在后面的模板中使用,或者后面的模板中使用,
image.png
image.png
-
在util工具包中新创建了一个类HostHolder用来隔离各种线程,表示每一个线程都各自保存一份独立的数据。起到了容器的作用,用来代替session对象,程序中不想使用session对象,虽然能够携带信息,并且线程隔离。
image.png
写完了拦截器之后,就需要进行配置,将刚才的拦截器注入进来。

- 接下来我们需要对模板进行一定的处理,改写index.html的页面。
2.33 账号设置

对于上传头像的功能,我们要将功能做成可配置的,因为上线之后,没准儿系统会在什么地方运行。

-
服务层只写更新头像的方法,
image.png
multipartFile是属于表现层的类,我们就不在服务层使用了,避免耦合。


多个MultipartFile就使用一个数组。


点击立即上传,立刻刷新到首页,如果可以看到头像变了,那就说明更新文件成功了。

- 如何获取头像呢?
若想解析到路径中的参数,需要使用@PathVariable这个注解
输入流是自己创建的,需要自行关闭,输出流是springmvc创建的,我们不用在意它的关闭情况。


-
找错误的时候主要看caused by
image.png
没有目录的时候就不能自己创建吗?
2.41 检查登录状态

自定义注解:

/setting和/upload方法都必须得登录了才能进行访问。至于头像,没有登陆也可以访问。
直接写在同一个拦截器里面不就行了
若拦截的是一个方法hander就是handlerMethod类型(springmvc规定)


我觉得一个一个加注解和挨个加路径效果一样啊,都很麻烦的。
一些小问题:
- StringUtils.isBlank()的功能。
2.input标签下面,value和placeholder有什么区别?? - cookie能保留多久啊,难道关了浏览器还能有?能不能在请求的时候人为添加ticket,那样,也能进行访问了。是不是压根不需要账号和密码,只需要知道cookie不就可以进行登录了吗??
- 退出了之后,超时时间会不会发生变化,好像是会的,当登录的时候,超时时间会进行设置???。
- 假如还没有登陆就直接访问user/setting肿么办。
- generateUUID要是产生了两个完全一样的字符串可怎么办。毕竟架不住用户比较多。除非是和时间相关的。
- controller中重定向到首页和直接返回到首页有什么区别吗? 重定向和response.sendRedirect的作用是一样的。
7.为什么要写这么多个拦截器,直接写一个不就完事儿了吗?
8.request.getContextPath可以取得应用的路径。
学习时间:
12:50
网友评论