本人在Java代码开发时对RESTful的使用
吐槽
分享贴,分享贴。
这个疑惑是我在对若依框架使用的时候发现异常类对返回码与状态码不统一(这个问题其实在上一家公司的时候我们老大就说过,不过我那会在睡觉…),而我们家前端是对返回码进行处理的,而我的上一家公司的前端是对状态码进行的统一处理,这就给了只喜欢抠细枝末节不喜欢钻研前沿技术的我产生了很大的疑惑,这我能忍!
我自己的感觉是若依是把状态码当成了一个响应状态工具,只要接口通了就是200,至于业务逻辑错了导致的返回码为500,这就不管状态码的事情了。而我上家公司是对Spring
自带的ResponseEntity
来构建和返回 HTTP 响应,加上我们老大自己封装的Msg响应类(我不清楚这是不是我们老大自己网上找的,不过没关系,毕竟我是从他那里拿的,我会把它放在文章的最下面),这种方式是由状态码来统一控制,然后再配合Spring
的ResponseStatusException
异常响应类来统一控制整个系统对前端页面的响应,好了废话不多说了,我先展开说一说在CRUD
接口上的使用方式
CRUD上的应用
查询列表接口
传入的请求实体与返回实体,应该不用说。直接看返回,return
后面跟着的ResponseEntity.ok(Msg.success
直接固定写就可以,后面这些(SysRoleInfo.asPage(sysRolePage)))
是把查出来的实体转换为出参实体
查询详情接口
主要看第四行,把出参放到Meg里然后第五行直接CV就可以
新增接口
还是一样return ResponseEntity.status(HttpStatus.CREATED).body(Msg.success());
这部分直接CV就可以了,ResponseEntity<Msg<Object>>
这一块的Object
不用写成你想返回的类,直接写Object
就行,毕竟它是所有类的超类
修改接口
跟新增一样,唯一的区别是请求注解用的PUT
删除接口
照抄,没什么好解释的
批量删除接口
最开始我们开发这个项目的时候批量删除接口注解使用的是@BatchDelete
,我忘了是什么不支持导致的不能使用,不过@Delete
也能使用,需要注意的时候批量删除要写自己的入参实体类,大概原因就是请求头对url长度有限制,当过长时会返回414状态码,具体请看http请求的url或body或header有长度或大小的限制吗?这一篇文章
其他的接口没什么要说的,至于 @PatchMapping
注解的话跟删除接口一样的写法就行,注意记得换注解
对异常类的应用
异常类吐槽
我在上家公司的时候,我们老大对我们非常严格,每一个异常要写独立的异常类,就是为了遵循 《代码整洁之道》这一本书中,提到的单一权责原则
,但是在我发布文章时所在的这家公司,并没有对代码风格有强烈的规范,所以我都是按照以前的习惯,加上有时候微微懒惰,形成了自己喜欢用的方式。
公共异常类
我们的系统充斥着大量的公共异常。例如,空指针异常,这个我们总不能都一个一个自定义,那多麻烦。下方举例
这样写继承异常类,构造函数里第一个参数是返回的状态码,第二个是自定义的信息
自定义异常类
至于有些我们需要自定义的异常类,就是想回复其中一个接口专属的异常信息可以这样。下方举例
我的习惯是用410这个状态码,你可以自定义你想用的状态码,具体使用,你可以在你想抛出自定义异常信息的地方。下方举例
然后让前端专门处理你这个异常响应类的返回码即可。
下方是Msg类
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Msg<T> {
private MessageType status;
@JsonInclude(NON_NULL)
private String error;
@JsonInclude(NON_NULL)
private T data;
public static Msg<Object> success() {
return Msg.builder()
.status(MessageType.SUCCESS)
.build();
}
public static Msg<Object> failure(String message) {
return Msg.builder()
.status(MessageType.FAILURE)
.error(message)
.build();
}
public static <T> Msg<T> success(T data) {
return Msg.<T>builder()
.status(MessageType.SUCCESS)
.data(data)
.build();
}
private enum MessageType {
SUCCESS,
FAILURE
}
}