在基于spring框架的项目开发中,必然会遇到controller层,它可以很方便的对外提供数据接口服务,也是非常关键的出口,所以非常有必要进行规范统一,使其既简洁又优雅。
controller层的职责为负责接收和响应请求,一般不负责具体的逻辑业务的实现。controller主要工作如下:
- 接收请求并解析参数;
- 调用service层执行具体的业务逻辑(可能包含参数校验);
- 捕获业务异常做出反馈;
- 业务逻辑执行成功做出响应;
目前controller层代码会存在的问题:
- 参数校验过多地耦合了业务代码,违背了单一职责原则;
- 可能在多个业务逻辑中抛出同一个异常,导致代码重复;
- 各种异常反馈和成功响应格式不统一,接口对接不友好;
优雅写法一:统一返回结构
统一返回值类型,无论项目前后端是否分离都是非常必要的,方便对接接口的前端开发人员更加清晰地知道这个接口的调用是否成功,不能仅仅简单地看返回值是否为 null 就判断成功与否,因为有些接口的设计就是如此。
统一返回结构,通过状态码就能清楚的知道接口的调用情况:
@data public class responsedata{ private boolean status = true; private int code = 200; private string message; private t data; public static responsedata ok(object data) { return new responsedata(data); } public static responsedata ok(object data,string message) { return new responsedata(data,message); } public static responsedata fail(string message,int code) { responsedata responsedata= new responsedata(); responsedata.setcode(code); responsedata.setmessage(message); responsedata.setstatus(false); responsedata.setdata(null); return responsedata; } public responsedata() { super(); } public responsedata(t data) { super(); this.data = data; } public responsedata(t data,string message) { super(); this.data = data; this.message=message; } }
@allargsconstructor @data public enum responsecode { sys_fail(1, "操作失败"), sys_sucess(200, "操作成功"), system_error_code_403(403, "权限不足"), system_error_code_404(404, "未找到请求资源"), ; private int code; private string msg; }
统一返回结构后,就可以在controller中使用了,但是每个controller都这么写,都是很重复的工作,所以还可以继续想办法处理统一返回结构。
优雅写法二:统一包装处理
spring 中提供了一个类 responsebodyadvice ,能帮助我们实现上述需求:
responsebodyadvice 是对 controller 返回的内容在 httpmessageconverter 进行类型转换之前拦截,进行相应的处理操作后,再将结果返回给客户端。这样就可以把统一包装处理的工作放到这个类里面,其中supports判断是否要交给beforebodywrite 方法执行,true为需要,false为不需要,beforebodywrite 是对response的具体处理。
@restcontrolleradvice(basepackages = "com.example.demo") public class responseadvice implements responsebodyadvice