使用Spring MVC开发RESTful API
第3章 使用Spring MVC开发RESTful API
Restful简介
第一印象
左侧是传统写法,右侧是RESTful写法
用url描述资源,而不是行为
用http方法描述行为,使用http状态码来表示不同的结果(200表示成功,500表示错误)
使用json交互数据
RESTful只是一种风格,并不是强制的标准
REST成熟度模型
编写第一个Restful API
通过用户查询,创建,删除,修改来学习怎么写一个Restful API
编写针对RestfullAPI的测试用例
UserController.java
@RestController
@RequestMapping("user")
public class UserController {
private List<User> getThreeEmptyUsers() {
List<User> userList = new ArrayList<>();
userList.add(new User());
userList.add(new User());
userList.add(new User());
return userList;
}
@RequestMapping(value = "query1", method = RequestMethod.GET)
public List<User> query() {
return getThreeEmptyUsers();
}
}
UserControllerTest.java
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserControllerTest {
@Autowired
private WebApplicationContext context;
private MockMvc mockMvc;
@Before
public void setup() {
mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
}
@Test
public void whenQuerySuccess() throws Exception {
mockMvc.perform(get("/user/query1")
.contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(status().isOk()) // 返回状态码为200
.andExpect(jsonPath("$.length()").value(3)); // 返回数据的集合长度是3
}
}
jsonPath表达式
常用注解
@RestControlelr 标明此Controller提供RestAPI
@RequestMapping及其变体,映射http请求url到java方法
@RequestParam 映射请求参数到Java方法的参数
@PageableDefault 指定分页参数的默认值
@JsonView 控制json输出内容,使用步骤如下
- 使用接口来声明多个视图
- 在值对象的get方法上指定视图
- 在Controller方法上指定视图
@GetMapping @RequestMapping的变体
传递参数
@PathVariable 映射url片段到java方法的参数 用户详情服务
- 在url声明中使用正则表达式
@RequestBody 映射请求体到java方法的参数
日期类型参数的处理
- 传递时间戳,有利于前后台分离
@Valid注解和BindingResult验证请求参数的合法性并处理校验结果
参数校验
常用的验证注解
自定义消息
- message = ""
自定义校验注解
- 参照代码的MyConstraint
服务异常处理
工具:chrome插件Restlet Client测试Restful接口的插件
Spring Boot中默认的错误处理机制
分析源码:BasicErrorController
如果请求一个不存在的url,app发出的请求返回json格式,浏览器发出的请求返回 页面格式。
依据Content-Type来判断是请求的页面还是json
自定义异常处理
text/html 基于状态码处理
- 配置404 resources/resources/error/404.html
application/json
- 参照代码UserNotExistException
拦截REST服务
Filter 过滤器
自定义过滤器,TimeFilter,加Component注释
第三方过滤器,LogFilter,通过WebConfig添加
拿不到Controller方法
Interceptor 拦截器
TimeInterceptor
拿不到Controller方法的参数
分析源码:DispatcherServlet/doService/doDispatcher/ha.handle(参数的拼装是调用这个方法完成的)
Aspect 切片
when/where/do what
关系
使用REST方式处理文件服务
测试方法
@Test
public void whenUploadSuccess() throws Exception{
String result = mockMvc.perform(fileUpload("/file")
.file(new MockMultipartFile("file", "text.txt", "multipart/form-data", "hello update".getBytes("UTF-8"))))
.andExpect(status().isOk())
.andReturn().getResponse().getContentAsString();
System.out.println(result);
}
文件上传下载
@RestController
@RequestMapping("file")
public class FileController {
@PostMapping
public FileInfo upload(MultipartFile file) throws Exception {
System.out.println("name: " + file.getName());
System.out.println("filename: " + file.getOriginalFilename());
String filePath = System.getProperty("user.home") + File.separator + new Date().getTime() + ".txt";
File localFile = new File(filePath);
file.transferTo(localFile);
return new FileInfo(filePath);
}
@GetMapping("{id}")
public void download(@PathVariable String id, HttpServletRequest request, HttpServletResponse response) throws Exception {
String filePath = System.getProperty("user.home") + File.separator + id + ".txt";
File file = new File(filePath);
if (!file.exists()) {
System.out.println("文件不存在");
return;
}
try (
InputStream is = new FileInputStream(file);
OutputStream os = response.getOutputStream();
) {
response.setContentType("application/x-download");
response.addHeader("Content-Disposition", "attachment;filename=test.txt");
IOUtils.copy(is, os);
os.flush();
}
}
}
使用Spring MVC开发RESTful API的更多相关文章
- 使用Spring MVC开发RESTful API(续)
使用多线程提高REST服务性能 异步处理REST服务,提高服务器吞吐量 使用Runnable异步处理Rest服务 AsyncController.java @RestController @GetMa ...
- Spring Boot开发RESTful接⼝服务及单元测试
Spring Boot开发RESTful接⼝服务及单元测试 常用注解解释说明: @Controller :修饰class,⽤来创建处理http请求的对象 @RestController :Spring ...
- ASP.NET Core Web API 开发-RESTful API实现
ASP.NET Core Web API 开发-RESTful API实现 REST 介绍: 符合REST设计风格的Web API称为RESTful API. 具象状态传输(英文:Representa ...
- 应用Spring MVC发布restful服务是怎样的一种体验
摘要:“约定优于配置”这是一个相当棒的经验,SOAP服务性能差.基于配置.紧耦合,restful服务性能好.基于约定.松耦合,现在我就把使用Spring MVC发布restful服务的 ...
- 用Spring MVC开发简单的Web应用
这个例子是来自于Gary Mak等人写的Spring攻略(第二版)第八章Spring @MVC中的一个例子,在此以学习为目的进行记录. 问题:想用Spring MVC开发一个简单的Web应用, 学习这 ...
- flask开发restful api系列(8)-再谈项目结构
上一章,我们讲到,怎么用蓝图建造一个好的项目,今天我们继续深入.上一章中,我们所有的接口都写在view.py中,如果几十个,还稍微好管理一点,假如上百个,上千个,怎么找?所有接口堆在一起就显得杂乱无章 ...
- flask开发restful api
flask开发restful api 如果有几个原因可以让你爱上flask这个极其灵活的库,我想蓝图绝对应该算上一个,部署蓝图以后,你会发现整个程序结构非常清晰,模块之间相互不影响.蓝图对restfu ...
- 使用Spring boot开发RestFul 风格项目PUT/DELETE方法不起作用
在使用Spring boot 开发restful 风格的项目,put.delete方法不起作用,解决办法. 实体类Student @Data public class Student { privat ...
- 描述怎样通过flask+redis+sqlalchemy等工具,开发restful api
flask开发restful api系列(8)-再谈项目结构 摘要: 进一步介绍flask的项目结构,使整个项目结构一目了然.阅读全文 posted @ 2016-06-06 13:54 月儿弯弯02 ...
随机推荐
- Cookie与HttpSession对象
Cookie与HttpSession对象的作用 维护客户端浏览器与服务端会话状态的两个对象. 由于HTTP协议是一个无状态的协议,因此服务端不会记录当前客户端浏览器的访问状态 有些时候需要服务端能够记 ...
- 用一个文件,实现迷你 Web 框架
当下网络就如同空气一样在我们的周围,它以无数种方式改变着我们的生活,但要说网络的核心技术变化甚微. 随着开源文化的蓬勃发展,诞生了诸多优秀的开源 Web 框架,让我们的开发变得轻松.但同时也让我们不敢 ...
- 《剑指offer》面试题1:赋值运算函数
面试题1:赋值运算函数 题目:如下为类型CMyString的声明,请为该类型添加赋值运算符函数 class CMyString { public: CMyString(char* pData = NU ...
- PC端操作系统、移动端操作系统、嵌入式操作系统
左侧部分已是历史的操作系统,右侧的还是活跃的操作系统.安卓系统Android 是Google开发的基于Linux平台的开源手机操作系统.它包括操作系统.用户界面和应用程序-- 移动电话工作所需的全部软 ...
- pushbutton 移动端弹出列表选择框
pushbutton 移动端弹出列表选择框 移动端从下往上推动画效果端弹出列表选择框,适应所有主流移动端机型,支持Node引入,require引入;如有用得不爽可以随时提意见,谢谢. demo地址: ...
- 使用前端开发工具包WijmoJS - 创建自定义DropDownTree控件(包含源代码)
概述 最近,有客户向我们请求开发一个前端下拉控件,需求是显示了一个列表,其中包含可由用户单独选择的项目控件,该控件将在下拉列表中显示多选TreeView(树形图). 如今WijmoJS已经实现了该控件 ...
- java中求一下2008年5月31日, 往前倒30天是哪天?
题目9: 2008年5月31日, 往前倒30天是哪天? import java.util.*; public class Test { public static void main(Str ...
- js,nodejs如何判断文件是什么编码格式
nodejs编码只支持utf8的编码方式,无论是打开某个文件或者写.js脚本都得以utf8的编码方式保存,不然程序无法运行,读出来的文件是乱码. 如果是在前台,读取文件是通过FileReader或者F ...
- pycharm——import已存在的库居然失败!
问题 明明在cmd中可以import的库,放到pycharm中却找不到. 问题根源 找了一圈,最后得到这个结论. 因为pycharm默认就是这样的... 解决 打开设置,找到解释器 点击右边齿轮图标, ...
- Python 图_系列之基于<链接表>实现无向图最短路径搜索
图的常用存储方式有 2 种: 邻接炬阵 链接表 邻接炬阵的优点和缺点都很明显.优点是简单.易理解,对于大部分图结构而言,都是稀疏的,使用炬阵存储空间浪费就较大. 链接表的存储相比较邻接炬阵,使用起来更 ...