SpringBoot 全局化消息返回与错误处理,兼容swagger(二) less than 1 minute read

上一篇中提到的解决方案是不完善的。很多情况下,你需要面对的接口文档是不可理喻的,他们并不知道什么是OpenAPI,甚至连我们上一篇中提到的统一格式返回也不愿意接受,这一篇中,我会为您展示Message定制化的小技巧。

我们以一下应用场景为例:

仍然,我们需要返回这样的一个对象:

{"success": true,"data": {},"message": "error message or success message"}

如果您看过我的上一篇博客,就会发现两者的区别,我们需要返回的字符串,现在并不是”errorMessage”,而是”message”。

无疑,这个改变是灾难性的,这就意味着,我们需要真对不同的接口,返回不同的message。

毫无疑问,通过controllerAdvice对所有的返回处理是无法做到这一点的,当然,有些情况下也可以,比如说,您可以创建一个超类,使他具有一个message属性,再让所有的返回都继承这个超类,进而,在controllerAdvice中,我们去判断返回体的类型,进而读取这一属性,将其设置为message的内容。

我相信您读到这里的时候一定和我一样倒吸了一口凉气,因为这样的写法不仅会使您的程序变得无比的复杂,更会破坏了您代码的优雅,更要命的是,这种写法更破坏了解耦,这无疑是对一个后端程序员尊严的挑战!

幸好,天无绝人之路,我为您提供了一种方法,是您不需要那么难看地去做这件事。

我们需要定义一个注解,像这样:

@Target({ElementType.TYPE, ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Documented@Componentpublic @interface MessageBody { String value();}

如您所见,这是一个普通到不能再普通的注解,我们能够用它来做什么呢?

答案是我们用它来标注方法,像这样:

 @MessageBody("登出成功!") @PostMapping("/logout") public void logout(){ userService.logoutProcess(); }

我想您已经猜出我要做什么了,在接下来的处理中,我们只需要对这个注解进行检测,并将其注入message即可。

read more
SpringBoot 全局化消息返回与错误处理,兼容swagger(一) 1 minute read

依据网络请求 - Ant Design Pro中提出的后端接口规范,后端返回的数据至少应遵循以下模板

{"success": true,"data": {},"errorMessage": "error message"}

为了帮助前端更好地完成工作,后端应强化接口规范。

首先创建一个工具包,再设想中,只要导入工具包,就会自动完成接口的转化。

pom中我们只引入spring-boot-starter-web:

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency>

然后我们定义要统一返回的Message类,这里使用泛型:

public class Message<T> implements Serializable { boolean success; String errorMessage; T data; Timestamp timestamp; public Message(boolean success, String errorMessage, T data read more
			
Spring-boot data JPA(三)JPA的序列化与反序列化 3 minute read

springBoot整合了json转化插件Jackson,配合这一插件可以完成Json的序列化与反序列化。定义一个类

 @Data @NoArgsConstructor public Class Message{ private String name; private String sex; }

在一个Controller中,可以以Message作为接收参数和返回内容:

 public Message messageResponse(@RequestBody message){ return message; }

如在以上的例子中,springBoot会将发送的json字符串中的name保存到Message的name属性中,并把sex保存到message的sex属性中(没有则保存空值).了解了以上就能解决对象序列化与反序列化过程中遇到的大部分问题,仍然有几点值得强调:

(以下的部分需要在pom.xml中引入以下依赖):

 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-json</artifactId> </dependency>

一. 一对多关系的风险及处理

在一对多关系中,以我们在Spring-boot data JPA(一)建库与一对多、多对多关系 - 荆凉凉 (stpjing.github.io)中创建的User与Admin类为例,User序列化时会序列化该User指向的Admin,同时Admin会序列化所有的下辖User对象,陷入无限迭代。

万幸Jackson提供了以下一对注解:@JsonBackReference与 @JsonManagedReference

通常,Admin与User有明显的父子关系,Admin是“父”,User是“子”。

@JsonBackReference用于“子”的一方,被该字段标注的属性不会被序列化。

@JsonManagedReference用于“父”的一方,其意义在于序列化时的自动注入。

@JsonManagedReference注解可以省略,但会造成被@JsonBackReference标注的属性不会被序列化,仍然以User与Admin为例(这里我们省略了User中Role的部分,多对多关系见下面的讨论)。整合了注释的实体类如下所示:

@Data@NoArgsConstructor@Entity@Table(name = "admin")public class Admin{ @Id @GeneratedValue read more