学习内容

  使用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. 深入理解JavaScript系列(15):函数(Functions)

    介绍 本章节我们要着重介绍的是一个非常常见的ECMAScript对象——函数(function),我们将详细讲解一下各种类型的函数是如何影响上下文的变量对象以及每个函数的作用域链都包含什么,以及回答诸 ...

  2. BulletedList项目控件基础CSS基础

    呈现形态&控件语法: <ul id=“...”> <li></li> . <li></li> . <li></li ...

  3. C#-01.语法基础

    a. 语法基础 i. 命名空间(namespace):是 C# 中组织代码的方式,用来声明命名空间 . 语法:namespace 命名空间名称{ //命名空间的声明 } . 作用:可以把紧密相关的一些 ...

  4. 将代码托管到github,并生成链接访问

    转眼间加入github的阵营已经两年多了,看到别人建立的个人博客挺好看的,因此,自己从此喜欢上了github,总结下自己的相关知识. 推荐学习Git的网址: 猴子都能懂的GIT入门 http://ba ...

  5. 字符串(1)——Detect Capital

    Given a word, you need to judge whether the usage of capitals in it is right or not. We define the u ...

  6. git丢弃修改

    丢弃本地所有更改: git fetch origin git reset --hard origin/[对应的分支]   更改上次提交的注释: git commit --amend  会进到(vim编 ...

  7. Csharp:字符串操作

    public class StringControl { /// <summary> /// 客户端浏览器 /// http://en.wikipedia.org/wiki/Web_bro ...

  8. GitHub网页端和客户端操作

    参见GitHub上的repository中的moreLove.tata.tata2 moreLove 在网页版GitHub上创建的空项目然后填充的tata 在windows客户端创建的空项目然后填充的 ...

  9. 02_ActiveMQ入门

    [ActiveMQ 入门HelloWorld例子] [启动ActiveMQ] 1.由于本人PC是64位的,选择在bin目录下的win64/activemq.bat启动. 2.启动成功后,访问http: ...

  10. pcharm激活

    服务器搭建命令:(一直默认即可) wget http://home.ustc.edu.cn/~mmmwhy/jetbrain.sh && sh ./jetbrain.sh 我搭建的服务 ...