Restful风格对接接口使用的规范

描述

概要

本实例适合所有的开发,不仅仅是前后端分离项目,不分离项目使用的AJAX请求后台也可以使用!

例如:

/**
	初学者都喜欢使用@RequestMapping注解直接在Controller的方法中进行映射
 */
	@RequestMapping("/queryById")
    public Demo queryById(Integer id) {
        ......
    }

大多数接口都包含新增、删除、修改、分页查询、部分也查询、按ID查询等6个接口,这样如果业务复杂的请求,一个Controller里面有过多的@RequestMapping映射,那里面映射的单词都不一样,那样开发出来的代码一眼看就是很糟糕!!

使用Restful风格只有在Controller类上有@RequestMapping注解,其中的方法只对应请求方式,比如分页查询的get请求直接使用 @GetMapping在方法上即可!如果有过多的get请求比如通过id查询则使用地址传参的方式 @GetMapping("{id}")然后在方法参数中加入@PathVariable("id") Integer id即可使用参数id!

@GetMapping("{id}")
    public Demo queryById(@PathVariable("id") Integer id) {
       ....
    }

以上只是对请求方式以及请求参数的一种写法,这里还有就是返回参数的问题,在所有的接口请求中都会有着不同的返回,上面都是返回的一个Demo的实体对象,但是在业务操作中,比如再获取列表的接口,那我们就需要返回的是一个集合,如果是修改的接口,那我们可能返回的是一个是否修改成功的标识,那样一个Controller里面就很繁琐了,如果遇到外键查询可能不是一个实体的对象,则就需要单独处理,所以我自己使用的就是一个封装的一个返回对象JsonWrite

package com.ww.talk.util;

/**
 * @author maker
 * @desc 后台返回前台json格式
 */
public class JsonWrite {
    public JsonWrite() {
    }

    /**
     * 状态码
     */
    private String code;
    /**
     * 是否成功
     */
    private boolean success;


    /**
     * 提示消息
     */
    private String msg;
    /**
     * 返回的数据
     */
    private Object data;

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public JsonWrite(String code, boolean success, String msg) {
        this.code = code;
        this.success = success;
        this.msg = msg;
    }


    public JsonWrite(String code, boolean success, String msg, Object data) {
        this.code = code;
        this.success = success;
        this.msg = msg;
        this.data = data;
    }

    /**
     * 自定义返回内容
     *
     * @param code
     * @param success
     * @param msg
     * @param data
     * @return
     */
    public static JsonWrite CUSTOMIZE(String code, boolean success, String msg, Object data) {
        JsonWrite jsonWrite = new JsonWrite();
        jsonWrite.setCode(code);
        jsonWrite.setSuccess(success);
        jsonWrite.setMsg(msg);
        jsonWrite.setData(data);
        return jsonWrite;
    }

    /**
     * 自定义返回内容
     *
     * @param code
     * @param success
     * @param msg
     * @return
     */
    public static JsonWrite CUSTOMIZE(String code, boolean success, String msg) {
        JsonWrite jsonWrite = new JsonWrite();
        jsonWrite.setCode(code);
        jsonWrite.setSuccess(success);
        jsonWrite.setMsg(msg);
        return jsonWrite;
    }

    /**
     * 操作成功,无数据传递
     *
     * @return
     */
    public static JsonWrite SUCCESS() {
        JsonWrite jsonWrite = new JsonWrite();
        jsonWrite.setCode(StatusCode.SUCCESS.getCode());
        jsonWrite.setSuccess(true);
        jsonWrite.setMsg(StatusCode.SUCCESS.getMsg());
        return jsonWrite;
    }

    /**
     * 操作成功,传递数据
     *
     * @return
     */
    public static JsonWrite SUCCESS(Object data) {
        JsonWrite jsonWrite = new JsonWrite();
        jsonWrite.setCode(StatusCode.SUCCESS.getCode());
        jsonWrite.setSuccess(true);
        jsonWrite.setMsg(StatusCode.SUCCESS.getMsg());
        jsonWrite.setData(data);
        return jsonWrite;
    }

    /**
     * 操作失败,无数据传递
     *
     * @return
     */
    public static JsonWrite ERROR() {
        JsonWrite jsonWrite = new JsonWrite();
        jsonWrite.setCode(StatusCode.SUCCESS.getCode());
        jsonWrite.setSuccess(false);
        jsonWrite.setMsg(StatusCode.SUCCESS.getMsg());
        return jsonWrite;
    }

    /**
     * 操作失败,传递数据
     *
     * @param data
     * @return
     */
    public static JsonWrite ERROR(Object data) {
        JsonWrite jsonWrite = new JsonWrite();
        jsonWrite.setCode(StatusCode.SUCCESS.getCode());
        jsonWrite.setSuccess(false);
        jsonWrite.setMsg(StatusCode.SUCCESS.getMsg());
        jsonWrite.setData(data);
        return jsonWrite;
    }

    /**
     * 操作成功,自定义消息
     *
     * @param msg
     * @return
     */
    public static JsonWrite SUCCESS(String msg) {
        JsonWrite jsonWrite = new JsonWrite();
        jsonWrite.setCode(StatusCode.SUCCESS.getCode());
        jsonWrite.setSuccess(true);
        jsonWrite.setMsg(msg);
        return jsonWrite;
    }

    /**
     * 操作成功,传递数据及自定义消息
     *
     * @param msg
     * @param data
     * @return
     */
    public static JsonWrite SUCCESS(String msg, Object data) {
        JsonWrite jsonWrite = new JsonWrite();
        jsonWrite.setCode(StatusCode.SUCCESS.getCode());
        jsonWrite.setSuccess(true);
        jsonWrite.setMsg(msg);
        jsonWrite.setData(data);
        return jsonWrite;
    }

    /**
     * 操作失败,自定义消息
     *
     * @param msg
     * @return
     */
    public static JsonWrite ERROR(String msg) {
        JsonWrite jsonWrite = new JsonWrite();
        jsonWrite.setCode(StatusCode.SUCCESS.getCode());
        jsonWrite.setSuccess(false);
        jsonWrite.setMsg(msg);
        return jsonWrite;
    }

    /**
     * 操作失败,传递数据以及自定义消息
     *
     * @param msg
     * @param data
     * @return
     */
    public static JsonWrite ERROR(String msg, Object data) {
        JsonWrite jsonWrite = new JsonWrite();
        jsonWrite.setCode(StatusCode.SUCCESS.getCode());
        jsonWrite.setSuccess(false);
        jsonWrite.setMsg(msg);
        jsonWrite.setData(data);
        return jsonWrite;
    }

    /**
     * 系统错误
     */
    public static JsonWrite SYSTEMERROR(String msg, Object data){
        JsonWrite jsonWrite = new JsonWrite();
        jsonWrite.setCode(StatusCode.SERVERERROR.getCode());
        jsonWrite.setSuccess(false);
        jsonWrite.setMsg(msg);
        jsonWrite.setData(data);
        return jsonWrite;
    }
}

可以看到我们的返回实体JsonWrite有很多的构造方法,这样可以满足多种返回格式!比如之前上面的通过id请求的结果我们可以写成:

/**
     * 通过主键查询单条数据
     *
     * @param id 主键
     * @return 单条数据
     */
    @GetMapping("{id}")
    public JsonWrite queryById(@PathVariable("id") Integer id) {
        return JsonWrite.SUCCESS(this.userService.queryById(id));
    }

因为通过ID查询一般不会出现查询错误的情况,所以直接就是使用的SUCCESS的方法返回!

介绍

提示:上面的定义的JsonWrite类中也有其他的辅助类:StatusCode(返回状态码枚举)

public enum StatusCode {
    /**
     * 状态码
     */
    SUCCESS("200", "OK"),
    BADREQUIRED("400", "Bad Request"),
    ACCESSERROR("401", "Access-Token Error"),
    AUTHERROR("403", "没有权限"),
    NOTFOUND("404", "Not Found"),
    SERVERERROR("500", "Internal Server Error"),
    REPEAT("600", "Repeat request,Request Forbidden"),
    BADGATEWAY("502", "Bad Gateway"),
    SERVICEUNAVAILABLE("503", "Service Unavailable"),
    ACCOUNT_ERROR("1000", "账户不存在或被禁用"),
    API_NOT_EXISTS("1001", "请求的接口不存在"),
    API_NOT_PER("1002", "没有该接口的访问权限"),
    PARAMS_ERROR("1004", "参数错误或格式错误"),
    SIGN_ERROR("1005", "数据签名错误"),
    API_DISABLE("1011", "查询权限已被限制"),
    UNKNOWN_IP("1099", "非法IP请求");

    /**
     * 状态码
     */
    private String code;
    /**
     * 状态描述
     */
    private String msg;

    public String getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }

    StatusCode(String code, String msg) {
        this.code = code;
        this.msg = msg;
    }
}

不同的返回状态吗对应着不同的含义!这样前端人员调用接口之后看到了返回状态码就知道对应的是什么问题,只有状态码为200的时候才是正常的返回正确结果!这也是一种对于前后端的规范!

案例

提示:这里我们编写了一个案例,大家可以对照案例理解一下思路!

package com.ww.talk.controller;

import com.ww.talk.util.JsonWrite;
import com.ww.talk.util.TableGrid;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

/**
 * (User)表控制层
 *
 * @author makejava
 */
@RestController
@RequestMapping("user")
public class UserController {
    /**
     * 服务对象
     */
    @Resource
    private UserService userService;
    /**
     * 分页查询
     *
     * @param tableGrid  筛选条件
     * @return 查询结果
     */
    @GetMapping
    public JsonWrite queryByPage(TableGrid tableGrid) {
        return JsonWrite.SUCCESS(this.userService.queryByPage(tableGrid));
    }

    /**
     * 通过主键查询单条数据
     *
     * @param id 主键
     * @return 单条数据
     */
    @GetMapping("{id}")
    public JsonWrite queryById(@PathVariable("id") Integer id) {
        return JsonWrite.SUCCESS(this.userService.queryById(id));
    }

    /**
     * 新增数据
     *
     * @param user 实体
     * @return 新增结果
     */
    @PostMapping
    public JsonWrite add(@RequestBody User user) {
        return this.userService.insert(user);
    }

    /**
     * 编辑数据
     *
     * @param user 实体
     * @return 编辑结果
     */
    @PutMapping
    public JsonWrite edit(@RequestBody User user) {
        return this.userService.update(user);
    }

    /**
     * 删除数据
     *
     * @param id 主键
     * @return 删除是否成功
     */
    @DeleteMapping("{id}")
    public JsonWrite deleteById(@PathVariable("id") Integer id) {
        return this.userService.deleteById(id);
    }
}

分析:

上面我们创建了一个UserController类,使用@RequestMapping(“user”)注解,这样前端使用user接口调用都是进入此类中查询对应的接口;然后我们定义了五个基础方法,分别是:分页查询、通过注解id查询、新增、修改和删除;下面我们分析这五个接口对应的写法

  • 分页查询:
/**
     * 分页查询
     *
     * @param tableGrid  筛选条件
     * @return 查询结果
     */
    @GetMapping
    public JsonWrite queryByPage(TableGrid tableGrid) {
        return JsonWrite.SUCCESS(this.userService.queryByPage(tableGrid));
    }

查询都是Get请求,这个不用多说!前端使用接口名称/user,并使用的是Get请求,则会进入方法中,方法参数是封装的分页实体,因为查询列表的方法也是不可能有业务判断或者业务报错的,所以直接使用JsonWrite.SUCCESS返回给前端,查询的数据是通过userService.queryByPage在userService的服务层处理,而JsonWrite.SUCCESS参数就是我们封装的JsonWrite返回到前端的data属性,前端在实体中通过.data获取返回的查询到的数据!

  • 通过注解id查询
/**
     * 通过主键查询单条数据
     *
     * @param id 主键
     * @return 单条数据
     */
    @GetMapping("{id}")
    public JsonWrite queryById(@PathVariable("id") Integer id) {
        return JsonWrite.SUCCESS(this.userService.queryById(id));
    }

同样是获取数据的Get请求,前端使用接口名称/user/3,这里的3是指要查询的数据id,方法正确使用get请求之后进入此方法中,通过@PathVariable("id")注解后台可以直接使用到参数id,由于通过id查询的这个id肯定是数据库存在的,所以这里同样使用JsonWrite.SUCCESS直接成功返回数据!

  • 新增
/**
     * 新增数据
     *
     * @param user 实体
     * @return 新增结果
     */
    @PostMapping
    public JsonWrite add(@RequestBody User user) {
        return this.userService.insert(user);
    }

新增为Post请求,咱们不多说!前端使用/user接口以及Post请求方式将会进入此方法中,前端传入的是一个实体对象,所以我们使用@RequestBody来注明我们接受的数据是一个User对象,因为新增的时候一般会有业务判断,比如用户名是否存在之类的,如果重复了存在了则是新增失败,所以我们再Controller中返回的是一个userService.insert服务层返回的结果,我们看下服务层代码:

/**
     * 新增数据
     *
     * @param user 实例对象
     * @return 实例对象
     */
    @Override
    public JsonWrite insert(User user) {
        int count = this.userDao.insert(user);
        if(count >0){
            return JsonWrite.SUCCESS("数据新增成功!");
        }else{
            return JsonWrite.ERROR("数据新增失败,请检查数据!");
        }
    }

这里在服务层的新增接口中可以看到,这里是做了一个简单的判断,因为对于mysql来说,执行新增操作如果成功会返回执行成功的条数,也就是新增一条数据成功会返回一个Integer类型的1,如果失败则为0,直接判断count执行数据库的结果来返回数据,前端使用JsonWrite的success属性是否为true来判断是否成功!

  • 修改
/**
     * 编辑数据
     *
     * @param user 实体
     * @return 编辑结果
     */
    @PutMapping
    public JsonWrite edit(@RequestBody User user) {
        return this.userService.update(user);
    }

修改为Put请求,前端直接使用/user并使用put请求方式即进入当前方法中,使用@RequestBody注解接收需要被修改的User对象数据,然后执行userService.update中的修改接口,因为修改的业务基本上都需要有判断所以这里直接就是返回的服务层接口,判断是否通过以及返回前台的数据由服务层处理!

  • 删除
/**
     * 删除数据
     *
     * @param id 主键
     * @return 删除是否成功
     */
    @DeleteMapping("{id}")
    public JsonWrite deleteById(@PathVariable("id") Integer id) {
        return this.userService.deleteById(id);
    }

删除请求方式为delete,这里只是简单的通过id删除数据,从前台传入一个id即可,传入的方式与通过id获取是一样的,/user/3这里的3是指需要被删除的对象的id,因为删除也是有很多的业务判断,所以返回的数据结果有service的服务层处理。

小结

提示:细心的同学可能已经发现了,能够直接出结果的都是查询接口,不能出结果的都是操作的数据,针对数据库来说就是‘查询数据’和‘操作数据’,凡是查询数据的都不应该会有问题,所以直接的success,而操作数据的都有可能伴随着业务的判断是失败所以是在业务层中区处理返回对象

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分