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

  1. 扩展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");
}
}
  1. 添加配置并将自定义的消息转化器添加到列表实现接口WebMvcConfigurer 实现方法 extendMessageConverters()
@Configuration
public class MyConfig implements WebMvcConfigurer { @Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new MappingJackson2XmlHttpMessageConverter());
converters.add(new PropertiesPersonHttpMessageConverter());
} }
  1. 在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的更多相关文章

  1. Spring Boot系列二 Spring @Async异步线程池用法总结

    1. TaskExecutor Spring异步线程池的接口类,其实质是java.util.concurrent.Executor Spring 已经实现的异常线程池: 1. SimpleAsyncT ...

  2. Spring框架系列(2) - Spring简单例子引入Spring要点

    上文中我们简单介绍了Spring和Spring Framework的组件,那么这些Spring Framework组件是如何配合工作的呢?本文主要承接上文,向你展示Spring Framework组件 ...

  3. Spring框架系列(8) - Spring IOC实现原理详解之Bean实例化(生命周期,循环依赖等)

    上文,我们看了IOC设计要点和设计结构:以及Spring如何实现将资源配置(以xml配置为例)通过加载,解析,生成BeanDefination并注册到IoC容器中的:容器中存放的是Bean的定义即Be ...

  4. Spring框架系列(6) - Spring IOC实现原理详解之IOC体系结构设计

    在对IoC有了初步的认知后,我们开始对IOC的实现原理进行深入理解.本文将帮助你站在设计者的角度去看IOC最顶层的结构设计.@pdai Spring框架系列(6) - Spring IOC实现原理详解 ...

  5. Spring框架系列(7) - Spring IOC实现原理详解之IOC初始化流程

    上文,我们看了IOC设计要点和设计结构:紧接着这篇,我们可以看下源码的实现了:Spring如何实现将资源配置(以xml配置为例)通过加载,解析,生成BeanDefination并注册到IoC容器中的. ...

  6. Spring框架系列(9) - Spring AOP实现原理详解之AOP切面的实现

    前文,我们分析了Spring IOC的初始化过程和Bean的生命周期等,而Spring AOP也是基于IOC的Bean加载来实现的.本文主要介绍Spring AOP原理解析的切面实现过程(将切面类的所 ...

  7. Spring框架系列(10) - Spring AOP实现原理详解之AOP代理的创建

    上文我们介绍了Spring AOP原理解析的切面实现过程(将切面类的所有切面方法根据使用的注解生成对应Advice,并将Advice连同切入点匹配器和切面类等信息一并封装到Advisor).本文在此基 ...

  8. Spring框架系列(11) - Spring AOP实现原理详解之Cglib代理实现

    我们在前文中已经介绍了SpringAOP的切面实现和创建动态代理的过程,那么动态代理是如何工作的呢?本文主要介绍Cglib动态代理的案例和SpringAOP实现的原理.@pdai Spring框架系列 ...

  9. Spring框架系列(12) - Spring AOP实现原理详解之JDK代理实现

    上文我们学习了SpringAOP Cglib动态代理的实现,本文主要是SpringAOP JDK动态代理的案例和实现部分.@pdai Spring框架系列(12) - Spring AOP实现原理详解 ...

随机推荐

  1. 在Winform开发框架中对附件文件进行集中归档处理

    在我们Winform开发中,往往需要涉及到附件的统一管理,因此我倾向于把它们独立出来作为一个附件管理模块,这样各个模块都可以使用这个附件管理模块,更好的实现模块重用的目的.在涉及附件管理的场景中,一个 ...

  2. ansible 模块 分享

    A a10_server 管理A10 Networks AX / SoftAX / Thunder / vThunder设备 a10_service_group 管理A10网络设备的服务组 a10_v ...

  3. js 时间格式,加减

    Date.prototype.Format = function (fmt) { //author: rixiao var o = { "M+": this.getMonth() ...

  4. knnsearch

    转载:https://blog.csdn.net/bushixiaofan/article/details/27700299 K近邻算法是找到K个最近的邻居. IDX = knnsearch(X,Y) ...

  5. BZOJ5507 GXOI/GZOI2019旧词 (树链剖分+线段树)

    https://www.cnblogs.com/Gloid/p/9412357.html差分一下是一样的问题.感觉几年没写过树剖了. #include<iostream> #include ...

  6. loj2880「JOISC 2014 Day3」稻草人

    题目链接:bzoj4237 ​ loj2880 考虑\(cdq\)分治,按\(x\)坐标排序,于是问题变成统计左下角在\([l,mid]\),右上角在\([mid+1,r]\)的矩形数量 我们先考虑固 ...

  7. List根据对象的两个字段进行排序,并且有一个倒序

    用java8 的lambda 表达式 list.sort(Comparator.comparing(Live::getId) .thenComparing(Live::getAppId, Compar ...

  8. vue stylus 格式化问题

    IDE是vscode 安装了.vetur插件 由于stylus可以仅用缩进不用写大括号之类的,所以十分方便, 但有个问题,按alt shift F 格式化时,vetur这个插件会默认添加上正常css的 ...

  9. Multi-View 3D Reconstruction with Geometry and Shading——Part-1

    From PhDTheses Multi-View 3D Reconstruction with Geometry and Shading 计算机视觉的主要任务就是利用图像信息能智能理解周围的世界. ...

  10. css控制table间距

    border-collapse: separate;border-spacing: 20px 30px; /* 水平间距 垂直间距 */