SpringBoot系列五:接口架构风格——RESTful


什么是REST

REST是软件架构的规范体系结构,它将资源的状态以适合客户端的形式从服务端发送到客户端(或相反方向)。在REST中,通过URL进行资源定位,用HTTP动作(GET、POST、DELETE、PUSH等)描述操作,完成功能。可以查看另一篇博客:Spring MVC对RESTful的支持

遵循RESTful风格,可以使开发的接口通用,以便调用者理解接口的作用。基于REST构建的API就是RESTful(REST风格)API。这样可以统一规范,减少沟通、学习和开发的成本。
在这里插入图片描述

HTTP方法与CRUD动作映射

RESTful风格使用同一个URL,通过约定不同HTTP方法来实施不同业务。

普通网页CRUD和RESTful风格的CRUD的区别如下表:

动作普通CRUD的URL普通CRUD的HTTP方法RESTful的URLRESTful的CRUD的HTTP方法
查询Article/id=1GETArticle/{id}GET
添加Article?title=xxx&body=xxxGET/POSTArticlePOST
删除Article/update?id=xxxGETArticle/{id}PUT/PATCH
修改Article/delete?id=xxxGETArticle/{id}DELETE

通过以上的对比看出,RESTful风格的CRUD比传统的CRUD简单明了,通过HTTP方法来区别增加、删除、修改、查询。
在这里插入图片描述


在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

HTTP的返回状态

HTTP的返回状态一般有以下几种

  • 200:成功
  • 400:错误请求
  • 404:没找到资源
  • 403:禁止
  • 500:服务器内部错误

详细请看:图解HTTP知识点

通过实例展示RESTful

响应枚举类

public enum  ExceptionMsg {
    SUCCESS("200", "操作成功"),
    FAILED("999999","操作失败"),
    ParamError("000001", "参数错误!"),
    FileEmpty("000400","上传文件为空"),
    LimitPictureSize("000401","图片大小必须小于2M"),
    LimitPictureType("000402","图片格式必须为'jpg'、'png'、'jpge'、'gif'、'bmp'")
    ;
    ExceptionMsg(String code, String msg) {
        this.code = code;
        this.msg = msg;
    }
    private String code;
    private String msg;
    public String getCode() {
        return code;
    }
    public String getMsg() {
        return msg;
    }
}

响应对象实体

public class Response {
    /** 返回信息码*/
    private String rspCode="200";
    /** 返回信息内容*/
    private String rspMsg="操作成功";
	public Response() {
	    }
    public Response(ExceptionMsg msg){
        this.rspCode=msg.getCode();
        this.rspMsg=msg.getMsg();
    }
    public Response(String rspCode) {
        this.rspCode = rspCode;
        this.rspMsg = "";
    }
    public Response(String rspCode, String rspMsg) {
        this.rspCode = rspCode;
        this.rspMsg = rspMsg;
    }

封装返回结果

public class ResponseData extends Response {
    private Object data;
    public ResponseData(Object data) {
        this.data = data;
    }
    public ResponseData(ExceptionMsg msg) {
        super(msg);
    }
    public ResponseData(String rspCode, String rspMsg) {
        super(rspCode, rspMsg);
    }
    public ResponseData(String rspCode, String rspMsg, Object data) {
        super(rspCode, rspMsg);
        this.data = data;
    }
    public ResponseData(ExceptionMsg msg, Object data) {
        super(msg);
        this.data = data;
    }

统一异常处理

400 - Bad Request

@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MissingServletRequestParameterException.class)
public Map<String, Object> handleMissingServletRequestParameterException(MissingServletRequestParameterException e) {
    logger.error("缺少请求参数", e);
    Map<String, Object> map = new HashMap<String, Object>();
    map.put("rspCode", 400);
    map.put("rspMsg", e.getMessage());
    //发生异常进行日志记录,写入数据库或者其他处理,此处省略
    return map;
}

 @ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(HttpMessageNotReadableException.class)
public Map<String, Object> handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
    logger.error("参数解析失败", e);
    Map<String, Object> map = new HashMap<String, Object>();
    map.put("rspCode", 400);
    map.put("rspMsg", e.getMessage());
    //发生异常进行日志记录,写入数据库或者其他处理,此处省略
    return map;
}

除了以上两种还有参数验证失败、参数绑定失败等异常。

415 - Unsupported Media Type

@ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
@ExceptionHandler(HttpMediaTypeNotSupportedException.class)
public Map<String, Object> handleHttpMediaTypeNotSupportedException(HttpMediaTypeNotSupportedException e) {
    logger.error("不支持当前媒体类型", e);
    Map<String, Object> map = new HashMap<String, Object>();
    map.put("rspCode", 415);
    map.put("rspMsg", e.getMessage());
    //发生异常进行日志记录,写入数据库或者其他处理,此处省略
    return map;
}

405 - Method Not Allowed

@ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
public Map<String, Object> handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
    logger.error("不支持当前请求方法", e);
    Map<String, Object> map = new HashMap<String, Object>();
    map.put("rspCode", 405);
    map.put("rspMsg", e.getMessage());
    //发生异常进行日志记录,写入数据库或者其他处理,此处省略
    return map;
}

CRUD控制器

/**
 * 增
 * @param article
 * @return
 */
@RequestMapping(value = "/", method = RequestMethod.POST)
public ResponseData add(Article article) {
    articleRepository.save(article);
    // return "{success:true,message: \"添加成功\" }";
    return new ResponseData(ExceptionMsg.SUCCESS,article);
}


/**
 * 删
 * @param id
 * @return
 */
@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
public Response delete(@PathVariable("id") long id) {
    articleRepository.deleteById(id);
    return result(ExceptionMsg.SUCCESS);
    //return new ResponseData(ExceptionMsg.SUCCESS,"");
}


/**
 * 改
 * @param model
 * @return
 */
@RequestMapping(value = "/{id}", method = RequestMethod.PUT)
public ResponseData update(Article model) {
    articleRepository.save(model);
    return new ResponseData(ExceptionMsg.SUCCESS,model);
}

/**
 * 查
 * @param id
 * @return
 * @throws IOException
 */
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public ResponseData findArticle(@PathVariable("id") Integer id) throws IOException {
    Article article = articleRepository.findById(id);
    if (article != null) {
        return new ResponseData(ExceptionMsg.SUCCESS,article);
    }
    return new ResponseData(Exceptio

测试

添加文章接口

在这里插入图片描述
查询文章接口

在这里插入图片描述
修改文章接口

在这里插入图片描述
删除文章接口

在这里插入图片描述

用Swagger实现接口文档

为了便于编写和维护稳定,可以使用Swagger来编写API接口文档,提升团队开发效率。

配置Swagger

添加相关依赖

<!-- 添加Swagger依赖 -->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.9.2</version>
</dependency>
<!-- 添加Swagger-UI依赖 -->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.9.2</version>
</dependency>

Swagger配置类

@Configuration
public class SwaggerConfig {
  @Bean
  public Docket createRestApi() {
      return new Docket(DocumentationType.SWAGGER_2)
              .apiInfo(apiInfo())
              .select()
              .apis(RequestHandlerSelectors.basePackage("cn.lwz.restful.controller"))
              .paths(PathSelectors.any())
              .build();
  }
  private ApiInfo apiInfo() {
      return new ApiInfoBuilder()
              .title(" RESTful APIs")
              .description("RESTful APIs")
              .termsOfServiceUrl("http://localhost:8080/")
              .contact("long")
              .version("1.0")
              .build();
  }
}

在Java目录下添加SwaggerApplication类

@SpringBootApplication
@EnableSwagger2
public class SwaggerApplication {
    public static void main(String[] args) {
        SpringApplication.run(SwaggerApplication.class, args);
    }
}

编写接口文档

完成上述配置之后,就生成了文档,但还是需要自己增加一些说明丰富文档内容,可以添加以下注释来增加说明。
在这里插入图片描述
详细请看:swagger注释API详细说明

测试

在浏览器输入:http://localhost:8080/swagger-ui.html,效果如下:

在这里插入图片描述
可以查看方法说明详情:

在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lw中

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值