Spring Boot系列(二) Spring Boot 之 REST
Rest (Representational Stat Transer) 是一种软件架构风格.
基础理论
架构特性
- 性能
- 可伸缩
- 简化的统一接口
- 按需修改
- 组件通信透明
- 可移植
- 可靠性
架构约束
- C/S 结构
- 无状态: Stateless
- 可缓存
- 分层系统
- 按需编码
- 统一接口: URI , 自描述消息(MIME),超媒体作为应用状态引擎(HATEOAS)
WEB MVC
MVC 中 URL 与 HTTP 方法的联系
URL 和 HTTP 方法存在联系. 不同方法对应的不同状态, 比如: https://api.exaple.com/resources/ 使用GET方法为查询, PUT为替换文件, POST为创建,DELETE 为删除.
其中GET请求为安全方法, 多次请求结果一致. POST 为非幂等请求, 多次提交会创建多个, DELETE,PUT为幂等请求. 幂等性是服务端的实现, 符合幂等性的方法实现更安全.
MVC 中的媒体类型MIME
通过请求头中的Accept获取媒体类型
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
下面的方法用来添加默认的消息转化器:
org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.addDefaultHttpMessageConverters()
对于json, 可以找到转化器名称为MappingJackson2HttpMessageConverter, 其中(可能是父类)定义的 read() 和 write() 方法用来读写数据.
同时也要注意canRead() 和 canWrite() 方法, 在相关的processor中, 通过遍历MessageConverters的List并调用can*方法来确定是否应用消息转化器, 找到第一个匹配的就停止遍历了. 因此消息转化器的顺序至关重要.
自定义MessageConverter
- 扩展
AbstractHttpMessageConverter抽象类, 并实现其中方法
public class PropertiesPersonHttpMessageConverter extends AbstractHttpMessageConverter<Person> {
public PropertiesPersonHttpMessageConverter(){
super(MediaType.valueOf("application/properties+person"));
setDefaultCharset(Charset.forName("UTF-8"));
}
@Override
protected boolean supports(Class<?> aClass) {
return aClass.isAssignableFrom(Person.class);
}
@Override
protected Person readInternal(Class<? extends Person> aClass, HttpInputMessage httpInputMessage) throws IOException, HttpMessageNotReadableException {
InputStream inputStream = httpInputMessage.getBody();
Properties properties = new Properties();
properties.load(new InputStreamReader(inputStream,getDefaultCharset()));
Person person = new Person(Integer.valueOf(properties.get("person.id").toString()) ,properties.get("person.name").toString());
return person;
}
@Override
protected void writeInternal(Person person, HttpOutputMessage httpOutputMessage) throws IOException, HttpMessageNotWritableException {
OutputStream outputStream = httpOutputMessage.getBody();
Properties properties = new Properties();
properties.setProperty("person.id",String.valueOf(person.getId()) );
properties.setProperty("person.name",person.getName());
properties.store(new OutputStreamWriter(outputStream,getDefaultCharset()),"person to properties");
}
}
- 添加配置并将自定义的消息转化器添加到列表实现接口
WebMvcConfigurer实现方法extendMessageConverters()
@Configuration
public class MyConfig implements WebMvcConfigurer {
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new MappingJackson2XmlHttpMessageConverter());
converters.add(new PropertiesPersonHttpMessageConverter());
}
}
- 在controller的方法上添加
@PostMapping(produces="application/my+format)这个produers对应header的Accept. 是我们自定义的MIME格式.
@PostMapping(value="/persontoproperties",
produces = "application/properties+person",
consumes = "application/json"
)
public Person person2Properties(@RequestBody(required = false) Person person){
return person==null?new Person(0,"default"):person;
}
Spring Boot系列(二) Spring Boot 之 REST的更多相关文章
- Spring Boot系列二 Spring @Async异步线程池用法总结
1. TaskExecutor Spring异步线程池的接口类,其实质是java.util.concurrent.Executor Spring 已经实现的异常线程池: 1. SimpleAsyncT ...
- Spring框架系列(2) - Spring简单例子引入Spring要点
上文中我们简单介绍了Spring和Spring Framework的组件,那么这些Spring Framework组件是如何配合工作的呢?本文主要承接上文,向你展示Spring Framework组件 ...
- Spring框架系列(8) - Spring IOC实现原理详解之Bean实例化(生命周期,循环依赖等)
上文,我们看了IOC设计要点和设计结构:以及Spring如何实现将资源配置(以xml配置为例)通过加载,解析,生成BeanDefination并注册到IoC容器中的:容器中存放的是Bean的定义即Be ...
- Spring框架系列(6) - Spring IOC实现原理详解之IOC体系结构设计
在对IoC有了初步的认知后,我们开始对IOC的实现原理进行深入理解.本文将帮助你站在设计者的角度去看IOC最顶层的结构设计.@pdai Spring框架系列(6) - Spring IOC实现原理详解 ...
- Spring框架系列(7) - Spring IOC实现原理详解之IOC初始化流程
上文,我们看了IOC设计要点和设计结构:紧接着这篇,我们可以看下源码的实现了:Spring如何实现将资源配置(以xml配置为例)通过加载,解析,生成BeanDefination并注册到IoC容器中的. ...
- Spring框架系列(9) - Spring AOP实现原理详解之AOP切面的实现
前文,我们分析了Spring IOC的初始化过程和Bean的生命周期等,而Spring AOP也是基于IOC的Bean加载来实现的.本文主要介绍Spring AOP原理解析的切面实现过程(将切面类的所 ...
- Spring框架系列(10) - Spring AOP实现原理详解之AOP代理的创建
上文我们介绍了Spring AOP原理解析的切面实现过程(将切面类的所有切面方法根据使用的注解生成对应Advice,并将Advice连同切入点匹配器和切面类等信息一并封装到Advisor).本文在此基 ...
- Spring框架系列(11) - Spring AOP实现原理详解之Cglib代理实现
我们在前文中已经介绍了SpringAOP的切面实现和创建动态代理的过程,那么动态代理是如何工作的呢?本文主要介绍Cglib动态代理的案例和SpringAOP实现的原理.@pdai Spring框架系列 ...
- Spring框架系列(12) - Spring AOP实现原理详解之JDK代理实现
上文我们学习了SpringAOP Cglib动态代理的实现,本文主要是SpringAOP JDK动态代理的案例和实现部分.@pdai Spring框架系列(12) - Spring AOP实现原理详解 ...
随机推荐
- CentOS7.x搭建时间同步服务器
关于chrony Chrony是一个开源的自由软件,像CentOS7或基于RHEL 7操作系统,已经是默认服务,默认配置文件在 /etc/chrony.conf 它能保持系统时间与时间服务器(NTP) ...
- Matrix Completion with Noise
目录 引 恢复1 核范数与SDP 稳定恢复 Candes E J, Plan Y. Matrix Completion With Noise[J]. arXiv: Information Theory ...
- C# NetStream
标题:NetStream 关注点:Read.Write 正文: int size = Read(buf, 0, buf.length); 这里一次会读入length个字节,如果小于这个数量,后面的就是 ...
- [转]html5监听任何App自带返回键javascript事件
1.前言 如今h5新特性.新标签.新规范等有很多,而且正在不断完善中,各大浏览器商对它们的支持,也是相当给力.作为前端程序员,我觉得我们还是有必要积极关注并勇敢地加以实践.接下来我将和各位分享一个特别 ...
- 4月18日 MySQL学习
正式开始了数据库的学习 昨天下好的MySQL 今天正式开始学习的,介绍了多种数据库软件,当然 学习的这个是开源的 免费的. DBMS(数据库管理系统)这就是我们学习的数据库的软件 数据库分为关系型数据 ...
- Flask 构建微电影视频网站(五)
基于角色的访问控制 权限管理 class AuthForm(FlaskForm): name = StringField( label='权限', validators=[ DataRequired( ...
- 【集训队作业2018】取名字太难了 任意模数FFT
题目大意 求多项式 \(\prod_{i=1}^n(x+i)\) 的系数在模 \(p\) 意义下的分布,对 \(998244353\) 取模. \(p\) 为质数. \(n\leq {10}^{18} ...
- python并发编程之多进程基础知识点
1.操作系统 位于硬件与应用软件之间,本质也是一种软件,由系统内核和系统接口组成 和进程之间的关系是: 进程只能由操作系统创建 和普通软件区别: 操作系统是真正的控制硬件 应用程序实际在调用操作系统提 ...
- Java复习总结——String
概览 String被声明为final,因此它不可被继承. public final class String implements java.io.Serializable, Comparable&l ...
- P1177 【模板】快速排序(学完归并和堆排之后的二更)
P1177 [模板]快速排序 不用说,连题目上都标了是一道模板,那今天就来对能用到的许多排序方式进行一个总结: 选择排序 选择排序(Selection sort)是一种简单直观的排序算法.它的工作原理 ...