Java项目笔记

Java项目笔记,第1张

目录
  • 一、交流平台
    • 第一章
      • 1.开发社区首页
    • 第二章
      • 2.发送邮件功能
      • 3.回话管理
      • 4.检查登录状态
      • 5.开发登录退出功能
      • 6.生成验证码
      • 7.显示登录信息(拦截器)
      • 8.用户注册功能
      • 9.账号设置
    • 第三章
      • 10.过滤敏感词
      • 11.发布帖子
      • 12.事务管理
      • 13.添加评论
      • 14.发送列表

一、交流平台 第一章 1.开发社区首页

一、新建了三个类:

1.DiscussPost:用户的帖子。

属性: id(自动生成主键),用户 id(外键连接 user 表),帖子的主题 ,帖子内容,帖子类型(普通,置顶),帖子状态(正常,精华,拉黑),帖子的创建时间 ,评论数量, 帖子分数(给帖子排名,按热度)。

2.Page:为了分页。

属性:有当前页码,显示上限,数据总数(用于计算总页数),查询路径(用于复用分页链接),拥有获取当前页起始行、总页数、获取下面页码的起始页码和结束页码方法。

3.User:用户类。

Service: 通过 user id 得到 user 对象。

二、Controller 层

处理网页的查询请求可以通过注解注入 DiscussPost Service 来解决,但 DiscussPost Service 只能返回 DiscussPost 列表,但列表中没有 user 属性,只有 user id(我们一般看到的讨论网页是能看到 user 的) 所以我们还需要注入 UserService 来得到 user 对象,将 user和 discussPost 通过list>放在一起,map 中有<“post”,DiscussPost >和<”user”,user>,将此 list 传给 model,网页模板有 thymeleaf。

为了分页:在模板中配置相对应的方法 首页(末页)路径、第几页 达到首页之后上
一页的按钮不可点(末页同理) 显示的页码范围。

第二章 2.发送邮件功能

①在新浪中将想要作为发送方的邮箱设置 SMTP 服务为开启,通过 Maven 导入 S 任凭 boot mail
的 jar 包,在配置文件中配置域名、端口、发送邮件的账号、密码等,通过 JavaMailSender发送邮件。

②为了能够将发送邮件的逻辑复用,创建 MailClient(因为要调用新浪的服务,所以我们是客户端)类来封装 JavaMailSender(有两种方法:发送邮件主体,创造邮件主体),先通过 JavaMailSender 来创建空的邮件主体之后用 spring 提供的 MimeMessageHelper 帮助类来丰富我们的邮件主体(发件人(配置文件中配置好了),收件人(方法中传入的参数),主题(方法中传入的参数),内容(方法中传入的参数)),之后再通过 JavaMailSender 的 send 方法发送邮件。

③使用 Thymeleaf 发送 html 文件:先创建 Thymeleaf 模板,将 model 和模板给模板引擎生成网
页(字符串类型),赋给发送邮件的内容参数。

3.回话管理

Http 的两个成功执行的请求之间是没有关系的,需要通过 cookie 来解决问题,使得请求能共享相同的上下文信息,达成相同的状态。

cookie 是服务器发送到浏览器,并保存在浏览器端
的一小块数据,浏览器下次访问该服务器时,会自动携带块该数据,将其发送给服务器,一
个 cookie 只能保存一组 key,value,上图的四步为通常的 cookie 设置,最后的返回值是返回
给浏览器的字符串,非网址,是乱写的。

获得 cookie,注意 cookie 在@RequestMapping 中传入给了服务器,可以在响应体中通过@CookieValue(key 值) String code 来获得 cookie 中的某一值,全部获得 cookie 的话是个
数组。

Session - 是 JavaEE 的标准,用于在服务端记录客户端信息。 - 数据存放在服务端更加安
全,但是也会增加服务端的内存压力。

传 cookie 是为了能够查找到对应的session。

Session 是和 model 等类型一样,一经声明 spring mvc 自动注入

2.为何用 cookie 不用 session?

当浏览器发出请求,传给 nginx 代理,经过负载均衡,可能第一次的请求发给了服务器 1,服务器 1 存储了一份 session 返给浏览器一个 cookie(session id),之后第二次浏览器发出请求,经过反向代理可能给服务器 3 发送了此 cookie,但服务器 3 没有对应的 session,会新建一个 session,则此 session 和第一次的请求数据创建的 session 不一样,会造成数据错误,可以通过设置负载均衡的分配策略,一种是粘性 session,只要是同一个浏览器 ip 就固定的分配给同一个服务器处理,但这样就会很难保证服务器的负载是均衡的,负载不均衡,性能不好;

第二种策略是同步 session,当一个服务器创建了 session 后,会同步给每个服务器,首先一台服务器同步给其他很多服务器,会影响性能,而且服务器和服务器之间会产生耦合,产生关联,会影响部署;

第三种方案是共享 session,单独有一个服务器,专门存放 session,当需要获得 session 时,都去找此服务器,但这样如果这个服务器挂掉了,其他服务器没法工作,违背了分布式的初衷:解决性能瓶颈,如果将此服务器搞一个集群,那和方案二没有区别,仍然需要共享;目前主流方案是能将数据存放到 cookie 里就放到 cookie 里,敏感数据比如密码之类的,就放到 nosql 数据库里(关系型数据库会把数据存放到硬盘里,速度慢)

4.检查登录状态

用户如果知道功能路径可以通过超路径访问,但如果是一个需要登陆才能访问的路径,但你直接通过超访问路径访问的话,可能会造成问题,下面的例子是围绕未登录但直接访问账号设置功能来讨论。

自定义注解:
(1)常见的元注解:
@Target:声明自定义的注解可以写在哪个位置,作用在哪个类型上(定义在类、方法、属
性上)
@Retention:声明自定义注解保留的时间(有效的时间:编译时有效,运行时有效)
@Document:生成文档时是否将自定义注解也带上。
@Inherited:用于继承,子类继承一个父类,父类有自定义注解,子类是否要将注解继承。

(2)如何读取注解:
Method.getDeclaredAnnotations() 通过反射 Method 类型对象调用这个方法获取这个方法上所有的注解。Method.getAnnotation(Class annotationClass)尝试获取 annotation(注解)Class 类型的注解。

创建注解

作用域在方法上,有效的时间是程序运行时。

在想要拦截的方法上加上此注解。

定义拦截器,因为只需要拦截方法,所以先判断 handler 是否是拦截方法类型,从拦截方法中获取方法,通过反射得到方法的此注解类型的注解,判断只要拥有此注解的且 user 为空(还未登录)则返回登录页面,return false 不继续往下执行。

拦截器的使用范围,不拦截一些静态的东西,不用管拦截范围,按默认全局就可以,因为在定义拦截器的时候已经拥有了相关的逻辑,也可以像第一个拦截器定义域一样,添加定义域不按默认值,但这样的话太麻烦,因为可能有好多路径都需要添加,一个一个麻烦。

5.开发登录退出功能

1.访问登录页面:点击顶部区域内的链接,打开登录页面。

2.登录:验证账号、密码、验证码,成功时,生成登录凭证,发送给客户端,失败时,跳转回登录页,登录有一个登录凭证表,首先创建一个登录凭证实体类,在 dao 层创建用于与登录凭证表相连接的接口 , 通过注解来实现与 登 录 凭 证 表 连 接 ,如下图所 示

在 service 层,创建方法,返回值为 map 用于判断用户在传递过来的账号、密码是否正确、以及记住我选项(对应登录凭证表的存活时间):空值处理、验证账号、验证状态、验证密码(注意与 user 表中的保存密码不同,还需要加盐、加密才可以与数据库中的密码相同),通过 dao 生成登录凭证在 controller 层,检查验证码,通过 service 层来检查用户账号和密码,不正确返回登录页面,正确返回主页,且通过 cookie 把登录凭证里的 ticket 返给客户端。

3.退出:将登录凭证修改为失效状态,跳转至网站首页在 service 层通过 dao 层中的 updateStatus 方法将凭证改为失效状态,controller 层通过service 更改凭证,重定向到登录页面。

6.生成验证码

Kaptcha:现成的验证码工具

导入 jar 包,编写 Kaptcha 配置类,生成随机字符、生成图片。

导入 jar 包:从 maven 中导入 jar 包,编写 Kaptcha 配置类:因为 sring 没有整合 kaptcha,所以我们需要创建一个配置类(颜色字体 长 宽 高 , 有 哪 些 随 机 字 符 , 一 个 验 证 码 有 几 个 字 符 ), 去 整 合kaptcha。

主要看 properties

生成验证码:先生成文本,再将文本变成图片;因为此次请求只是将验证码图片传给页面,但当你点击登录时,会将此次的验证码文本与登录时输入的验证码文本作比较,所以两次请求有关联,是一次会话,且是敏感信息,要通过 session 来完成会话;之后要将图片输出给浏览器,首先声明你回应的类型是什么,之后开启输出流,将图片输出出去,spring mvc 会自动关闭输出流。

Ps:只要响应体不是字符串或网址,则方法返回空值,且将响应体当做参数传入方法中,进行 *** 作

Ps:注意在模板中将验证码的路径改下,改成你验证码中的请求路径。

7.显示登录信息(拦截器)

在网页头部因为每个请求都需要判断显示的按钮(首页、登录、注册、消息、个人头像、),反 复 实 现 所 以 用 拦 截 器 处 理 , 逻 辑 如 下 图 所 示。
在请求给 controller 之前先拦截一次,获取请求的持有对象(因为 controller 层也可能会用到):通过 cookie 得到 ticket,之后用 ticket 通过登录表得到 userID,将这个 id 传给 ThrendLocal对 象 ( 为 了 防 止 线 程 冲 突 , 因 为 浏览 器 和 服 务 器 是 多 对 一 的 关 系 )。

在模板引擎之前再拦截一次,在 ThrendLocal中获取 user 对象传给 model在模板引擎之后拦截一次,将 ThrendLocal中的对象清理掉,减少内存。

8.用户注册功能

Ps:CommunityUtil 是自己写的类拥有生成随机字符串的方法(封装了 uuid)以及 MD5 加密方法。

可以将用户注册功能分为三个请求,访问注册页面,提交注册数据,激活注册账号(按请求来开发用户注册功能)

1.访问注册页面:在 controller 层编写响应方法,返回注册页面路径。

2.提交注册数据:通过 maven 导入 commons lang 的 jar 包,为了判断常用的数据是否空值,在UserService 层中编写一个注册方法,传入的参数类型为 user,返回值为 map 因为可能是某一字段不能为空,账号已存在等等信息。

首先对空值处理,判断 user 是否为 null,是的话抛出异常,在判断 user 里的属性是否为空,若为空将错误信息 put(key=“usernamemsg”,value=“账号不能为空” 等映射)进返回的 map 中,直接 ruturn map,若上述错误都没有判断 username、Email 是否重复,若重复 return,都没有问题,将用户设置的密码进行加密(通过 CommunityUtil设置 salt 与用户密码拼接在一起之后传入给 CommunityUtil 的加密方法)覆盖用户密码,将一些用户没有编写的属性赋值(type、status 等),赋给用户一个随机头像(应该传入路径参数,共有 1000 个随机头像,大体的路径相同,只有一个数字不同可以通过 random 随机生成),用 insertUser 方法导入数据库中,给用户发邮件方法(让其激活),将context(对应 email 以及对应的网址(域名+项目访问路径+项目下激活的访问功能路径+用户 id+激活码))和网站模板传给模板引擎,调用发送邮件方法传入用户邮箱,主题为激活账号,内容为模板引擎生成的网站,在 LoginController 层的注册方法中首先得到 userservice 的注册方法返回的 map,如果 map 为空说明成功注册,返回一个说明注册已成功,且过几秒会跳转到首页的网站模板路径(其中要将动态值(mas:注册成功,我们已经向您的邮箱发送了一封邮件,请尽快激活;跳转的网页目标:首页路径)加入进模板),如果失败在 model 中分别添加用户名,密码,邮件等的错误信息 return 注册网站的路径,其中当返回注册页面时,想要保存上次的填写信息(错误的信息),可以在模板中设置一个判断,比如返回上次的用户名填写信息,先判断 user 是否为空,若不为空则填入 nsername,错误时有 is-invalid 标志。

3.激活注册账号:不用编写 dao 层,已经在数据库中有了,只是没有激活,在 UserService 层:

编写激活方法(参数为 userId,激活码 code),通过 userId 查到 user 对象,判断 user 对象的状态(status)若为 1 则说明已经激活过,返回 2 为重复激活,如果激活码与传入激活码一样则先将用户状态改为 1,返回 0 成功激活,否则(激活码不对)返回 1 激活失败,在LoginController 层处理请求,路径为网址,方法参数为 model,userId(通过@PathVariable 得到路径中对应的 userId 值(被{}括住,且名字相同),code 值(激活码,获取方法同上)),返回的是跳转模板的路径,调用 service 的激活方法赋给 result,判断 result 的值,若激活成功,要将动态值(mas:激活成功,您的账号已经可以正常使用;跳转的网页目标:登陆页面路径)加入进 model,若重复激活,将动态值 mas:无效 *** 作,该账号已经激活过了;跳转的网页目标:登陆页面路径加入进 model,若激活失败,将动态值(mas:激活失败,您提供的激活码不正确;跳转的网页目标:首页路径)加入进 model。

9.账号设置

开发步骤:访问账号设置页面、上传头像、获取头像。

1.上传头像:通过 MultipartFile 来处理获得用户上传数据,判断是否为空等,在 controller 层来处理,调用 service 层来 update 用户(通过 ThreadLocal 借助 cookie 来获得具体是哪一个用户)的头像地址(web 访问路径,非本地访问地址)(经过随机处理更改后的文件名称,用subString 来获取文件后缀,拼接文件名称)

2.获取头像:在 controller 层,通过请求路径可以得到用户头像的文件名称,获得服务器存放
地址,通过字节输入流得到图片文件,字节输出流输出。

第三章 10.过滤敏感词


和算法相关,创建一个敏感词树(多叉),将每个敏感词的第一个字符(不重复)记入根节点的子节点 ,敏感词最后一个字符记上标记,在检查敏感词时,一个指针指向敏感词字符查到的位置,两个指针指向字符串(需要过滤敏感词的文本),一个指向敏感词头部(不是就往后移动一位),一个指向需要匹配的字符。

11.发布帖子

通过异步请求 AJAX(不刷新页面、局部刷新得到想要得到的东西,和消息队列中的异步不太 一 样 ) 来 发 送 帖 子 , 如 下 图 所示。

主页没有刷新,但在主页的基础上,加了一个发布的页面,这个功能可以通过 jQuery 来实现,那在 response 中就不能返回一个页面了,否则会跳转,jQuery 在前端,也需要一些信息传入,但不能和模板中传入 model 来实现,所以可以通过 json 来做信息传入,在 response 中返回一个 jQuery 可以解析成 json 对象的字符串(前面在 response 中只返回了字符串(应该,没回去验证),感觉 response中只能返回字符串(可以代表 html 页面)),取出相应的值。

2.导入 fastjson jar 包

获得 json 字符串方法,传入编码(404 类似),提示信息(成功与否),业务数据在 dao 层插入帖子接口,链接数据库,写 sql 语句在 service 层判断帖子若为空抛出异常,运用 spring 工具 HtmlUtils 转义主题和内容(防止有标签等,执行了标签(语句)),过滤敏感词(主题)(内容)

在 controller 层首先获得当前用户(ThreadLocal),如果为空则 return 一个 jQuery 可以将其转换为 json 的字符串,其余 语句都差不多。

12.事务管理


乐观锁:先运行相应的代码,在提交前判断是否在这个期间版本号更新过,若更新则取消本次的更新 spring 引以为傲的地方,任何数据库都可以用这套事务管理,不管是关系型还是非关系型。


通过注解,声明事务,spring 通过@Transactional(隔离级别,传播方式)来实现方法的事务,将一整个方法作为一个事务,事务传播方式是在 a事务调用 b 事务的情况下引出的理念,由于最后一行代码运行错误,所以事务回滚。

通过编程管理事务:

通 过 transactionTemplate 对 象 来 实 现 , spring 自 动 装 配.

直接注入就可以,通过前两行设置隔离级别和传播机制,在 execute 方法中传入TransactionCallback接口类型对象,其中接口中的 doInTransactioon 方法是需要添加进事务的代码,如下图:

13.添加评论

在添加评论时,需要向评论表中添加一个评论数据,而帖子表还有一个评论数量的属性,在添加评论时要更新对应帖子对象的此属性,两者应一同完成,所以用事务写在一起。

14.发送列表

Dao 层

传入集合 mybatis 的 *** 作:

Service 层

Controller 层:返回 json 格式,因为要异步

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/785778.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-04
下一篇 2022-05-04

发表评论

登录后才能评论

评论列表(0条)

保存