04《Spring Boot 入门教程》使用模板引擎开发 Web 项目

物联网0156

04《Spring Boot 入门教程》使用模板引擎开发 Web 项目,第1张

业务中需要应用到Websocket长连接进行数据传输,由于服务使用的是Zuul10版本,对ws协议支持较弱,后续尝试使用了 spring-boot-starter-websocket 来完成的。关于怎么集成的话网上有非常多的文章了,我就不多费口舌了。

我们目前实现的功能是可以通过WebSocket调用接口发送埋点,另外还需要监听用户离开的事件为这个埋点画上一个终止访问时间。目前测试下场景有:

前4点触发了任意操作,服务端都会监听到 DISCONNECT 离开事件。但是第5点直接断网, 服务端竟然是无感知的,这个时候产生的问题就是客户断网了,服务端是认为在线的,如果不重新联网登录的话,那么这个用户将会一直一直在线,埋点会一直计算。完了个蛋~

至于为什么断网之后,ws会认为他是在线的, 可能管道打开了之后由于断网导致断开时间发送不出去吧。

我目前能够想到比较简单的办法就是: 心跳续约

捋清了思路,大概就知道如何做了。

然后特意看了下 spring-boot-starter-websocket 的源码,发现其实他有提供此功能。

先说下如何实现:

我们是在在实现了 DelegatingWebSocketMessageBrokerConfiguration 的配置类中重写 configureMessageBroker 方法。

比较关键就是 setTaskScheduler 和 setHeartbeatValue 一个负责调度、一个负责配置间隔。

这俩要么都填要么都不填。

配置了这俩参数之后,服务启动的时候会触发一个 HeartbeatTask 线程来专门维持心跳。

我们可以看看他的流程是如何运转的。

核心任务调度类: orgspringframeworkmessagingsimpbrokerSimpleBrokerMessageHandlerHeartbeatTask

服务端在启动的时候 SimpleBrokerMessageHandler 在初始化完成之后会回调 start 的方法,然而他会触发一个 startInternal 开始调度任务,判断依据就是有没有配置 TaskScheduler ( 对应的就是配置类中的setTaskScheduler ),一旦启动之后,会根据你给的心跳数组 serverHeartbeat ,来选择调度时间。

orgspringframeworkmessagingsimpbrokerSimpleBrokerMessageHandler

检测心跳、超过间隔则剔除、并且定期回写心跳给客户端。

还有一点需要注意的是读的间隔时间:

假设用户网络不好,心跳漏发了一次,这个时候如果按照本次的逻辑而言,该用户的最后心跳时间肯定会超时。而它的做法是, 将设定的读超时时间 3 ,就相当于有3次机会。

这个在创建session的时候 SessionInfo 里面就已经做好了处理:

orgspringframeworkmessagingsimpbrokerSimpleBrokerMessageHandlerSessionInfo#SessionInfo

所以这个时候,你可能需要根据业务能够接受的时长去配置,也别忘了这个事。

还有很关键的一点就是让客户端的心跳发送间隔和服务端尽可能保持一致,不然有可能出现莫名其妙的下线情况,尽可能还是在这种地方加好日志。

好了,希望在遇到断网问题的时候,能够帮助到你。

如果有疑问请留言,我会尽快答复。

回答如下:

在开发中的区别还是存在的,虽然springboot简化了配置,但并不代表不需要编写配置文件,还是需要在自带的applicationyml文件中去编写一些内容;只不过编写的方式变得简单了,虽然简单了,但是和SSM整合的方式还有些区别。

在使用SSM开发的时候,多数会选择Jsp作为视图,但是springboot不推荐使用jsp,主推的是thymeleaf和freemarker等模板引擎,也造成了使用SSM开发到springboot开发也需要一定的学习成本。不过如果掌握了SSM的话,学习springboot也是水到渠成,异常的简单。

相关介绍:

源特定组播是一种区别于传统组播的新的业务模型,它使用组播组地址和组播源地址同时来标识一个组播会话,而不是向传统的组播服务那样只使用组播组地址来标识一个组播会话。

SSM保留了传统PIM-SM模式中的主机显示加入组播组的高效性,但是跳过了PIM-SM模式中的共享树和RP (Rendezvous Point,集合点)规程。在传统PIM-SM模式中,共享树和RP规程使用(,G)组对来表示一个组播会话,其中(G)表示一个特定的IP组播组,而()表示发向组播组G的任何一个源。

SSM直接建立由(S,G)标识的一个组播最短路径树(SPT:Shortest Path Tree),其中(G)表示一个特定的IP组播组地址,而(S)表示发向组播组G的特定源的IP地址。

SSM的一个(S,G)对也被称为一个频道(Channel),以区分传统PIM-SM组播中的任意源组播组。由于ASM支持点到多点和多点到多点两种组播业务模式,因此源的发现过程是ASM复杂性的原因。

例如在PIM-SM模式中,用户点击浏览器中的组播内容,接收端设备只被通知到组播组的内容,而没有被通知到组播源的信息。而在SSM模式中,用户端将同时接收到组播源和组播组信息。

因此,SSM特别适合于点到多点的组播服务,例如网络娱乐频道、网络新闻频道、网络体育频道等业务,但如果要求多点到多点组播服务则需要ASM模式。

关于业务逻辑层(Service层)

业务逻辑层是被Controller直接调用的层(Controller不允许直接调用持久层),通常,在业务逻辑层中编写的代码是为了 保证数据的完整性和安全性 ,使得数据是随着我们设定的规则而产生或发生变化。

通常,在业务逻辑层的代码会由接口和实现类组件,其中, 接口被视为是必须的

关于抛出的异常,通常是自定义的异常,并且, 自定义异常 通常是`RuntimeException`的子类,主要原因:

所以,在实际编写业务逻辑层之前,应该先规划异常,例如先创建` ServiceException `类:

接下来,再创建具体的对应某种“失败”的异常,例如,在添加管理员时,可能因为“用户名已经存在”而失败,则创建对应的 `UsernameDuplicateException`异常

另外,当插入数据时,如果返回的受影响行数不是1时,必然是某种错误,则 创建对应的插入数据异常

关于抽象方法的参数,应该设计为客户端提交的数据类型或对应的封装类型,不可以是数据表对应的实体类型!如果使用封装的类型,这种类型在类名上应该添加某种后缀,例如` DTO`或其它后缀 ,例如:

并在以上`service`包下创建`impl`子包,再创建`AdminServiceImpl`类:

以上代码未实现对密码的加密处理! 关于密码加密 ,相关的代码应该定义在别的某个类中,不应该直接将加密过程编写在以上代码中,因为加密的代码需要在多处应用(添加用户、用户登录、修改密码等),并且,从分工的角度上来看,也不应该是业务逻辑层的任务!所以,在`cncelinfbootdemoutil`(包不存在,则创建)下创建`PasswordEncoder`类,用于处理密码加密:

完成后,需要在`AdminServiceImpl`中自动装配以上`PasswordEncoder`,并在需要加密时调用`PasswordEncoder`对象的`encode()`方法。

控制器层开发

Spring MVC是用于处理控制器层开发的,在使用Spring Boot时,在`pomxml`中添加`spring-boot-starter-web`即可整合Spring MVC框架及相关的常用依赖项(包含`jackson-databind`),可以将已存在的`spring-boot-starter`直接改为`spring-boot-starter-web`,因为在`spring-boot-starter-web`中已经包含了`spring-boot-starter`。

先在项目的根包下创建`controller`子包,并在此子包下创建`AdminController`,此类应该添加 `@RestController` 和` @RequestMapping (value = "/admins", produces = "application/json; charset=utf-8")`注解,例如:

由于已经决定了服务器端响应时,将响应JSON格式的字符串,为保证能够响应JSON格式的结果,处理请求的方法返回值应该是自定义的数据类型,则从此前学习的`spring-mvc`项目中找到`JsonResult`类及相关类型,复制到当前项目中来。

完成后,运行启动类,即可启动整个项目,在`spring-boot-starter-web`中,包含了Tomcat的依赖项,在启动时,会自动将当前项目打包并部署到此Tomcat上,所以,执行启动类时,会执行此Tomcat,同时,因为是内置的Tomcat,只为当前项目服务,所以,在将项目部署到Tomcat时,默认已经将Context Path(例如spring_mvc_war_exploded)配置为空字符串,所以,在启动项目后,访问的URL中并没有此前遇到的Context Path值。

当项目启动成功后,即可在浏览器的地址栏中输入网址进行测试访问!

注意 :如果是未添加的管理员账号,可以成功执行结束,如果管理员账号已经存在,由于尚未处理异常,会提示500错误。

然后,在`cncelinfbootdemocontroller`下创建`handlerGlobalExceptionHandler`类,用于统一处理异常,例如:

完成后,重新启动项目,当添加管理员时的用户名没有被占用时,将正常添加,当用户名已经被占用时,会根据处理异常的结果进行响应!

由于在 统一处理异常的机制下 ,同一种异常,无论是在哪种业务中出现,处理异常时的描述信息都是完全相同的,也无法精准的表达错误信息,这是不合适的!另外,基于面向对象的“分工”思想,关于错误信息(异常对应的描述信息),应该是由Service来描述,即“谁抛出谁描述”,因为抛出异常的代码片段是最了解、最明确出现异常的原因的!

为了更好的描述异常的原因,应该在自定义的`ServiceException`和其子孙类异常中添加基于父类的全部构造方法(5个),然后,在`AdminServiceImpl`中,当抛出异常时,可以在异常的构造方法中添加`String`类型的参数,对异常发生的原因进行描述,例如:

最后,在处理异常时,可以 调用异常对象的`getMessage()`方法获取抛出时封装的描述信息 ,例如:

完成后,再次重启项目,当用户名已经存在时,可以显示在Service中描述的错误信息!

可以看到,无论是成功还是失败, 响应的JSON中都包含了不必要的数据 (为`null`的数据),这些数据属性是没有必要响应到客户端的,如果需要去除这些不必要的值,可以在对应的属性上使用注解进行配置,例如:

此注解还可以添加在类上,则作用于当前类中所有的属性,例如:

即使添加在类上,也只对当前类的3个属性有效,后续,当响应某些数据时,`data`属性可能是用户、商品、订单等类型,这些类型的 数据中为`null`的部分依然会被响应到客户端 去,所以,还需要对这些类型也添加相同的注解配置!

以上做法相对比较繁琐,可以在`applicationproperties` / `applicationyml`中添加全局配置,则作用于当前项目中所有响应时涉及的类,例如在`properties`中配置为:

注意:当你需要在`yml`中添加以上配置时,前缀属性名可能已经存在,则不允许出现重复的前缀属性名的:

最后,以上配置只是“默认”配置,如果在某些类型中还有不同的配置需求,仍可以在类或属性上通过 `@JsonInclude`进行配置

15 解决跨域问题

在使用前后端分离的开发模式下,前端项目和后端项目可能是2个完全不同的项目,并且,各自己独立开发,独立部署,在这种做法中,如果前端直接向后端发送异步请求,默认情况下,在前端会出现类似以下错误:

以上错误信息的关键字是`CORS`,通常称之为 “跨域问题”

在基于Spring MVC框架的项目中,当需要解决跨域问题时,需要一个Spring MVC的配置类(实现了`WebMvcConfigurer`接口的类),并重写其中的方法,以允许指定条件的跨域访问,例如:

16 关于客户端提交请求参数的格式

通常,客户端向服务器端发送请求时,请求参数可以有2种形式,第1种是直接通过`&`拼接各参数与值,例如:

具体使用哪种做法,取决于服务器端的设计:

- 如果服务器端处理请求的方法中,在参数前添加了`@RequestBody`,则允许使用以上第2种做法(JSON数据)提交请求参数,不允许使用以上第1种做法(使用`&`拼接)

- 如果没有使用 `@RequestBody`,则只能使用以上第1种做法

spring和spring boot区别如下:

1、Spring框架:

就像一个家族有众多衍生产品例如boot、security、jpa等等但他们的基础都是Spring的ioc和aopioc提供了依赖注入的容器aop解决了面向横切面的编程然后在此两者的基础上实现了其他延伸产品的高级功能。

2、spring boot:

是基于Servlet的一个MVC框架主要解决WEB开发的问题因为Spring的配置非常复杂各种XML、JavaConfig、hin处理起来比较繁琐于是为了简化开发者的使用,从而创造性地推出了Springboot,约定优于配置简化了spring的配置流程。

spring短语搭配:

Leaf Spring 钢板弹簧 ; 叶片弹簧 ; [机] 板弹簧 ; [机] 片簧

Early Spring 早春图 ; 早春 ; 早春二月 ; 烟花三月

Spring rolls 春卷 ; 脆皮春卷 ; 第三道春卷 ; 秋卷

Silent Spring 寂静的春天 ; 沉寂的春天 ; 无声的春天 ; 沉静的春天

Air Spring [机] 空气弹簧 ; 气垫 ; 空翻 ; 春秋航空

以上就是关于04《Spring Boot 入门教程》使用模板引擎开发 Web 项目全部的内容,包括:04《Spring Boot 入门教程》使用模板引擎开发 Web 项目、烧脑巨作,Spring Boot请求处理(常用参数注解使用)、实战spring-boot-starter-websocket之断网心跳续期实践等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!