Spring Boot系列(二) Spring Boot 之 REST

Rest (Representational Stat Transer) 是一種軟件架構風格.html

基礎理論

架構特性

  • 性能
  • 可伸縮
  • 簡化的統一接口
  • 按需修改
  • 組件通訊透明
  • 可移植
  • 可靠性

架構約束

  • C/S 結構
  • 無狀態: Stateless
  • 可緩存
  • 分層系統
  • 按需編碼
  • 統一接口: URI , 自描述消息(MIME),超媒體做爲應用狀態引擎(HATEOAS)

WEB MVC

MVC 中 URL 與 HTTP 方法的聯繫

URL 和 HTTP 方法存在聯繫. 不一樣方法對應的不一樣狀態, 好比: https://api.exaple.com/resources/ 使用GET方法爲查詢, PUT爲替換文件, POST爲建立,DELETE 爲刪除.java

其中GET請求爲安全方法, 屢次請求結果一致. POST 爲非冪等請求, 屢次提交會建立多個, DELETE,PUT爲冪等請求. 冪等性是服務端的實現, 符合冪等性的方法實現更安全.web

MVC 中的媒體類型MIME

經過請求頭中的Accept獲取媒體類型spring

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3json

下面的方法用來添加默認的消息轉化器:api

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;
}
相關文章
相關標籤/搜索