问题背景
对于controller返回的结果(http接口),虽然一直有约定的json结构,但是在代码层面还是由程序员手动去拼写。这样有个缺点,就是程序员的不稳定性,在这里,他可能将列表数据命名为rows,而另一个程序员,她可能命名为list,这样就导致了不一致的结果,针对这个问题,出现了接口文档。仔细想想,这个地方完全可以用代理的方式,通过一个代理类,返回特定格式的结果。这个代理类还规定好了,结果的提示语,比如“操作成功”就是“操作成功”,不会出现“添加成功”、“添加结果成功”、“数据添加成功”等不一致的结果信息。它的作用有
- 自动包装接口数据和格式,固定格式,方便前端、客户端的调用
- 统一提示处理,可以针对各种情况,配置相应的提示结果,保证提示结果的一致性和易修改性,还可以在这里完成提示语的国际化功能
- 提高开发效率,程序员只需要把业务数据放入代理类,节省其他无关繁杂操作。
- 可以在这里进行日志打印处理
实现方法
定义一个返回结果的基类BaseResponse,其中有基本属性,操作代码和提示消息,其余的结果类都是它的子类,定义一个返回page列表结果的类PageResponse,继承它。它们Uml如下。
定义数据打包的RespPackUtil类,通过代理模式,在controller中将service的调用代理到RespPackUtil中去执行。并且在RespPackUtil执行日志打印(耗时),状态提示语,多语言支持。执行代码大致如下
代码语言:javascript复制public class RespPackUtil {
public static BaseResponse execInvokeService(BaseRequest request, BaseResponse response,ServiceWrapper wrapper) {
int resultCode = wrapper.invokeMethod();
/** code对应提示语 **/
/** 日志打印 **/
/** 结果包装、多语言提示(中英) **/
}
}
代码语言:javascript复制public abstract class ServiceWrapper{
public abstract Integer invokeService();
/**
* 配置项
* 是否打印debug日志
* 是否监控失败请求
* 是否监控成功请求
* 超时时间
*/
}
代码语言:javascript复制public class UserController {
@Autowird
private UserService userService;
@RequestMapping("query")
@ResponseBody
public PageResponse<User> query(@RequestBody final UserQueryRequest request) {
PageResponse<User> response = new PageResponse<User>();
return (PageResponse<User>) RespPackUtil.execInvokeService(request, response, new ServiceWrapper(){
public Integer invokeService(){
userService.query();
response.setRows(userService.query());
return BaseApiCode.OPERATE_SUCCESS;
}
});
}
@RequestMapping("add")
@ResponseBody
public BaseResponse add(@RequestBody final UserAddRequest request) {
Response response = new Response();
return RespPackUtil.execInvokeService(request, response, new ServiceWrapper(){
public Integer invokeService(){
userService.add(request);
return BaseApiCode.OPERATE_SUCCESS;
}
});
}
}