学习内容

  使用Spring MVC编写Restful API

  使用Spring MVC处理其他web应用常见的需求和场景

    如何处理静态资源和异常,如何使用Spring MVC的拦截器,文件的上传下载,如何进行请求的异步开发

  RESTful API开发常用辅助框架

    Swagger-生成服务文档,WireMock-伪造服务

RESTful API介绍

  特点:

  1.用URL描述资源

  2.使用HTTP方法描述行为,使用HTTP状态码来表示不同结果

    增删改查对应POST、DELETE、PUT、GET,使用状态码来表示结果而不是用报文里面的内容。

  3.使用json交互数据

  4.RESTful只是一种风格,并不是强制标准

编写第一个RESTful API

  使用注解声明RESTful API

    常用注解

      @RestController 标明此Controller提供RESTful API

      @RequestMapping及其变体 映射http请求url到java方法

      @RequestParam 映射请求参数到java方法的参数

      @PageableDefault 指定分页参数的默认值

  在RESTful API中传递参数

    @RequestParam

      required,name,defaultValue,required表示参数是否必须,name表示HTTP请求参数名,defaultValue表示未传参数时使用的默认值。

@RequestMapping(value = "/user", method = RequestMethod.GET)
public List<User> query(@RequestParam(required = true, name = "username", defaultValue = "Tom") String username) {
System.out.println(username);
List<User> users = new ArrayList<User>();
users.add(new User());
users.add(new User());
users.add(new User());
return users;
}

      如果传递参数太多,Spring MVC可以自动将参数组装到对象中,可以声明一个类UserQueryCondition有多个属性。

public class UserQueryCondition {

    private String username;
private int age;
private int ageTo; public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getAgeTo() {
return ageTo;
}
public void setAgeTo(int ageTo) {
this.ageTo = ageTo;
} }
@RequestMapping(value = "/user", method = RequestMethod.GET)
public List<User> query(UserQueryCondition condition) {
System.out.println(ReflectionToStringBuilder.toString(condition, ToStringStyle.MULTI_LINE_STYLE));
List<User> users = new ArrayList<User>();
users.add(new User());
users.add(new User());
users.add(new User());
return users;
}
@Test
public void whenQuerySuccess() throws Exception {
mockMvc.perform(get("/user")
.param("username", "jojo")
.param("age", "10")
.param("ageTo", "20")
.contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(status().isOk())
.andExpect(jsonPath("$.length()").value(3));
}

    @PageableDefault

      page,size,sort,表示默认查第几页,一页数据条数,排序

@RequestMapping(value = "/user", method = RequestMethod.GET)
public List<User> query(UserQueryCondition condition, @PageableDefault(page = 1, size = 10, sort = "username,asc") Pageable pageable) {
System.out.println(ReflectionToStringBuilder.toString(condition, ToStringStyle.MULTI_LINE_STYLE));
System.out.println(ReflectionToStringBuilder.toString(pageable, ToStringStyle.MULTI_LINE_STYLE));
List<User> users = new ArrayList<User>();
users.add(new User(1));
users.add(new User(2));
users.add(new User(3));return users;
}
@Test
public void whenQuerySuccess() throws Exception {
mockMvc.perform(get("/user")
.param("username", "jojo")
.param("age", "10")
.param("ageTo", "20")
.param("size", "5")
.param("page", "2")
.param("sort", "age,desc")
.contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(status().isOk());
}

编写用户详情服务

  @PathVariable 映射url片段到java方法的参数

    name,required,name要和url片段相同,required表示是否必须

@RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
public User getInfo(@PathVariable(name = "id") String userid) {
User user = new User();
user.setId(userid);
user.setUsername("Tom");
return user;
}
@Test
public void whenGetInfoSuccess() throws Exception {
String result = mockMvc.perform(get("/user/1")
.contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(status().isOk())
.andExpect(jsonPath("$.username").value("Tom"))
.andReturn().getResponse().getContentAsString();
System.out.println(result);
}  

  在url片段的声明中使用正则表达式

@RequestMapping(value = "/user/{id:\\d+}", method = RequestMethod.GET)
public User getInfo(@PathVariable(name = "id") String userid) {
User user = new User();
user.setId(userid);
user.setUsername("Tom");
return user;
}
@Test
public void whenGetInfoFail() throws Exception {
mockMvc.perform(get("/user/a")
.contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(status().is4xxClientError());
}

  @JsonView控制json输出内容

    假设query不想返回用户密码,getInfo时返回给前台用户密码,即在返回相同对象时控制返回哪些字段。

    使用步骤:

      1.使用接口声明多个视图 2.在值对象的get方法上指定视图 3.在Controller方法上指定视图

public class User {

    public interface UserSimpleView {}; //视图1
public interface UserDetailView extends UserSimpleView {}; //视图2,因继承视图1,所以使用视图2也会显示视图1的属性 private String id;
private String username;
private int age;
private String password; @JsonView(UserSimpleView.class)
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@JsonView(UserSimpleView.class)
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@JsonView(UserSimpleView.class)
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@JsonView(UserDetailView.class)
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
} }
@RequestMapping(value = "/user", method = RequestMethod.GET)
@JsonView(User.UserSimpleView.class)
public List<User> query(UserQueryCondition condition, @PageableDefault(page = 1, size = 10, sort = "username,asc") Pageable pageable) {
System.out.println(ReflectionToStringBuilder.toString(condition, ToStringStyle.MULTI_LINE_STYLE));
System.out.println(ReflectionToStringBuilder.toString(pageable, ToStringStyle.MULTI_LINE_STYLE));
List<User> users = new ArrayList<User>();
users.add(new User());
users.add(new User());
users.add(new User());
return users;
} @RequestMapping(value = "/user/{id:\\d+}", method = RequestMethod.GET)
@JsonView(User.UserDetailView.class)
public User getInfo(@PathVariable(name = "id") String userid) {
User user = new User();
user.setId(userid);
user.setUsername("Tom");
return user;
}

  代码重构

    1.将url相同部分提到类上声明

    2.使用RequestMapping的变体GetMapping

@RestController
@RequestMapping("/user")
public class UserController { @GetMapping()
@JsonView(User.UserSimpleView.class)
public List<User> query(UserQueryCondition condition, @PageableDefault(page = 1, size = 10, sort = "username,asc") Pageable pageable) {
System.out.println(ReflectionToStringBuilder.toString(condition, ToStringStyle.MULTI_LINE_STYLE));
System.out.println(ReflectionToStringBuilder.toString(pageable, ToStringStyle.MULTI_LINE_STYLE));
List<User> users = new ArrayList<User>();
users.add(new User());
users.add(new User());
users.add(new User());
return users;
} @GetMapping("/{id:\\d+}")
@JsonView(User.UserDetailView.class)
public User getInfo(@PathVariable(name = "id") String userid) {
User user = new User();
user.setId(userid);
user.setUsername("Tom");
return user;
} }

  

第二章:RESTful API的更多相关文章

  1. 第二章 Stream API

    引例: 1 List<String> strList = Arrays.asList("zhaojigang","nana","tiany ...

  2. HBase第二章 基本API

    1.pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www ...

  3. HTML5 WebSocket 权威指南 学习一 (第二章 WebSocket API)

    WebSocket 协议两种URL方案 ws 客户端和服务器之间的非加密流量 wss 客户端和服务器之间的加密流量 WebSocket Secure 表示使用传输层安全性(SSL)的WebSocket ...

  4. ArcGIS API for JavaScript 4.2学习笔记[10] 2D添加指北针widget、视图保存、视图padding(第二章完结)

    这几个例子是第二章除了入门之外比较简单的几个,就做个合集,把最核心的代码(第二参数)和 引用放上来即可,不作多解释. 2D地图添加指北针widget 2D地图一般修正方向为正北方就需要这个widget ...

  5. ASP.NET Core 中文文档 第二章 指南 (09) 使用 Swagger 生成 ASP.NET Web API 在线帮助测试文档

    原文:ASP.NET Web API Help Pages using Swagger 作者:Shayne Boyer 翻译:谢炀(kiler) 翻译:许登洋(Seay) 对于开发人员来说,构建一个消 ...

  6. ArcGIS API for JavaScript 4.2学习笔记[3] 官方第二章Mapping and Views概览与解释

    目录如下: 连接:第二章 Mapping and Views 根据本人体会, [这一章节主要是介绍地图(Map)和视图(View)的.] 其中,Get started with MapView(2D) ...

  7. 基于轻量型Web服务器Raspkate的RESTful API的实现

    在上一篇文章中,我们已经了解了Raspkate这一轻量型Web服务器,今天,我们再一起了解下如何基于Raspkate实现简单的RESTful API. 模块 首先让我们了解一下"模块&quo ...

  8. RESTful API 设计最佳实践

    背景 目前互联网上充斥着大量的关于RESTful API(为了方便,以后API和RESTful API 一个意思)如何设计的文章,然而却没有一个"万能"的设计标准:如何鉴权?API ...

  9. ****RESTful API 设计最佳实践(APP后端API设计参考典范)

    http://blog.jobbole.com/41233/ 背景 目前互联网上充斥着大量的关于RESTful API(为方便,下文中“RESTful API ”简写为“API”)如何设计的文章,然而 ...

随机推荐

  1. gitbook一仓库多本书持续化部署

    引言 本文档用户指导新手如何部署GitLab+Jenkins自动化构建GitBook,并使用Nginx发布资料.在部署过程中,如遇到任何问题,请自行百度. 注意: 此文章的环境和数据,仅为用于调试的片 ...

  2. C# 服务端控件 asp:RadioButton 选择选中值

    1.服务端控件RadioButton <asp:RadioButton ID="rbNewUser" runat="server" GroupName=& ...

  3. SpringSecurity 3.2入门(10)自定义权限控制认证及授权的过程

    上一章的代码实现还存在一些问题,如角色表.权限表的用处没有体现出来,但是已经能完成URL拦截功能,后面将会继续完善认证及授权的过程. 认证及授权的过程如下: 1.容器启动,MyInvocationSe ...

  4. python-requests 简单实现数据抓取

    安装包: requests,lxmlrequest包用于进行数据抓取,lxml用来进行数据解析对于对网页内容的处理,由于html本身并非如数据库一样为结构化的查询所见即所得,所以需要对网页的内容进行分 ...

  5. 码农的好助手:版本管理工具git的使用

    一.什么是github? GitHub 是一个面向开源及私有软件项目的托管平台,因为只支持 Git 作为唯一的版本库格式进行托管,故名 GitHub. GitHub 于 2008 年 4 月 10 日 ...

  6. C#学习笔记4

    1.C#只支持单一继承,若想要实现多重继承的效果.有2种方式: 第一种为传递继承,A为基类,B继承A,C继承B,通过传递来增迭要包含的元素,但这种继承的设计,在业务上具有明显的从属关系. 第二种为聚合 ...

  7. swagger快速开发

    转载:https://blog.csdn.net/xxoo00xx00/article/details/77163399 swagger 学习笔记 搭建环境: 1,jdk1.8 2,idea 3,sp ...

  8. spring事务之多个业务之间怎么共享用同一个事务

    应用场景:一个月前在学校做一个羽毛球馆的项目时,那个时候用的是springboot,然后项目分成几个模块,教练模块,学生模块,管理员模块,场地模块等等,然后Service层是按模块化进行的设计. 但是 ...

  9. Flask插件---flask_script与flask_migrate

    import app from flask_script import Manager from flask_migrate import Migrate,MigrateCommand my_app ...

  10. css滤镜模糊效果filter和backdrop-filter

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...