1. 程式人生 > >java中的訊息轉換器--HttpMessageConverter

java中的訊息轉換器--HttpMessageConverter

目錄:

  • HTTP請求響應模型;
  • 基於javax-servlet-api的請求、響應處理介面;
  • 基於SpringMVC的請求、響應介面;

HTTP請求響應模型

一般情況下,我們使用的最簡單的HTTP請求響應模型就是B/S模型了。


1、客戶端發出http請求,http請求中包含著請求引數,傳送到指定的HTTP Server;

2、HTTP Server接受 http 請求,並解析http請求,將http 請求中的請求引數暴露出來;

3、處理業務邏輯;

4、封裝http響應報文,響應客戶端;

本文從原始的servlet-api和springMVC框架兩個角度分析http引數解析及http響應報文的解析與封裝過程。

基於javax-servlet-api的請求、響應處理介面

解析http請求時,可以使用javax.servlet.ServletRequest中的getInputStream()方法:

public ServletInputStream getInputStream() throws IOException;

來得到一個ServletInputStream。這個ServletInputStream中,可以讀取到一個原始請求報文的所有內容。

封裝http響應時,可以使用javax.servlet.ServletResponse中的getOutputStream()方法:
public ServletOutputStream getOutputStream() throws IOException;

來得到一個ServletOutputStream,這個ServletOutputSteam,繼承自java中的OutputStream,可以讓你輸出Http的響應報文內容。

ServletRequest和ServletResponse介面關係:
其中,ServletInputStream和ServletOutputStream類圖關係:


讓我們嘗試著像SpringMVC的設計者一樣來思考一下。我們知道,Http請求和響應報文字質上都是一串字串,當請求報文來到java世界,它會被封裝成為一個ServletInputStream的輸入流,供我們讀取報文。響應報文則是通過一個ServletOutputStream的輸出流,來輸出響應報文。

我們從流中,只能讀取到原始的字串報文,同樣,我們往輸出流中,也只能寫原始的字元。而在java世界中,處理業務邏輯,都是以一個個有業務意義的物件為處理維度的,那麼在報文到達SpringMVC和從SpringMVC出去,都存在一個字串到java物件的阻抗問題。這一過程,不可能由開發者手工轉換。我們知道,在Struts2中,採用了OGNL來應對這個問題,而在SpringMVC中,它是HttpMessageConverter機制。-- 引用自《

基於SpringMVC的請求、響應介面

在SpringMVC中,不再是通過原始的輸入輸出流來獲取http請求或http響應。而是通過訊息轉換器,按照一定規則從http請求中提取訊息至方法形參中的內部物件中,或將內部物件按照一定規則寫入到響應報文中。

在SpringMVC中,獲取http請求的報文頭部和報文body是基於HttpMessage介面的,同樣先看介面關係圖:


有了獲取HttpMessage的方法,SpringMVC在HttpMessageConverter訊息轉換器中將HttpMessage作為方法引數來解析HttpMessage訊息。看圖:


可見,在HttpMessageConverter介面及其子類中,都是使用HttpMessage作為引數,而在HttpMessageConverter解析器的不同的實現方法中,實現了對Http請求響應的不同的解析。舉個栗子:

<!-- 啟動註解 -->
    <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="<strong><span style="color:#ff6666;">org.springframework.http.converter.StringHttpMessageConverter</span></strong>">
                <property name="supportedMediaTypes">
                    <list>
                        <value>text/plain;charset=UTF-8</value>
                        <value>text/html;charset=UTF-8</value>
                    </list>
                </property>
            </bean>
            <bean class="<strong><span style="color:#ff6666;">com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter</span></strong>">
                <property name="supportedMediaTypes">
                    <list>
                        <value>text/html;charset=UTF-8</value>
                        <value>application/json</value>
                    </list>
                </property>
                <property name="features">
                    <array>
                        <value>WriteNullBooleanAsFalse</value>
                        <value>WriteMapNullValue</value>
                        <value>WriteNullStringAsEmpty</value>
                    </array>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>


這裡就是用不同的解析器,一個是“StringHttpMessageConverter”,一個是“FastJsonHttpMEssageConverter”,他們都是HttpMessageConverter的實現。

需要注意一點的是,在SpringMVC中,可以使用@RequestBody和@ResponseBody兩個註解,分別完成請求報文到物件和物件到響應報文的轉換,實現機制就是上面說的過程。舉個用例:

@RequestMapping(value="/string", method=RequestMethod.POST)
public @ResponseBody String readString(@RequestBody String string) {
    return "Read string '" + string + "'";
}
在SpringMVC進入readString方法前,會根據@RequestBody註解選擇適當的HttpMessageConverter實現類來將請求引數解析到string變數中,具體來說是使用了StringHttpMessageConverter類,它的canRead()方法返回true,然後它的read()方法會從請求中讀出請求引數,繫結到readString()方法的string變數中。
當SpringMVC執行readString方法後,由於返回值標識了@ResponseBody,SpringMVC將使用StringHttpMessageConverter的write()方法,將結果作為String值寫入響應報文,當然,此時canWrite()方法返回true。

用圖來說明一下這個過程:



相關推薦

java訊息轉換--HttpMessageConverter

目錄: HTTP請求響應模型;基於javax-servlet-api的請求、響應處理介面;基於SpringMVC的請求、響應介面; HTTP請求響應模型 一般情況下,我們使用的最簡單的HTTP請求響應模型就是B/S模型了。 1、客戶端發出http請求,http請求中包

SpringMVC原始碼剖析5:訊息轉換HttpMessageConverter與@ResponseBody註解

轉自 SpringMVC關於json、xml自動轉換的原理研究[附帶原始碼分析] 本系列文章首發於我的個人部落格:https://h2pl.github.io/ 歡迎閱覽我的CSDN專欄:Spring原始碼解析 https://blog.csdn.net/column/details/21851.html 部

HttpMessageConverter訊息轉換

版權宣告:本文為博主原創文章,無需授權即可轉載,甚至無需保留以上版權宣告,轉載時請務必註明作者。 https://blog.csdn.net/weixin_43453386/article/details/83615829 HttpMessageConverter訊息轉換器

JavaEE開發之SpringMVC的自定義訊息轉換與檔案上傳

上篇部落格我們詳細的聊了《》,本篇部落格依然是JavaEE開發中的內容,我們就來聊一下SpringMVC中的自定義訊息轉發器(HttpMessageConverter)和SpringMVC中的檔案上傳。訊息轉發器在日常開發中是比較常用的,其可以靈活的將使用者發過來的訊息按照自定義的格式進行解析,然後將解析的資

Spring Boot專案如何定製HTTP訊息轉換

在構建RESTful資料服務過程中,我們定義了controller、repositories,並用一些註解修飾它們,但是到現在為止我們還沒執行過物件的轉換——將java實體物件轉換成HTTP的資料輸出流。 Spring Boot底層通過HttpMessageConverters和Jackson庫將Java實體

java xml轉換為json對象

xml轉換 serial () hid cti mave tostring code ace 1、前提須要jar包: json-lib-2.4-jdk15.jar 和 xom-1.2.5.jar ,maven 倉庫: net.sf.jso

Java叠代Iterator的使用

兩種 適合 討論 沒有 entryset 當前 import 是否 set Java集合類中Map接口下的相關類並沒有像Collection接口的相關類一樣實現get()方法,因此在要實現遍歷輸出的場景中沒法直接用get()方法來取得對象中的數據,但Java本身提供了另一種

SpringMVC源碼剖析(五)-消息轉換HttpMessageConverter

var blog tro 20px 請求參數 wrap -i reat return SpringMVC源碼剖析(五)-消息轉換器HttpMessageConverter目錄[-]概述Http請求的抽象HttpInputMessageHttpOutputMessageHtt

JAVAString轉換資料型別原來這麼簡單

String型別的資料轉為byte陣列: String str=""qwertyuiop; byte [] bytes=str.getBytes(); byte位元組型別轉為String型別資料: String str=""qwertyuiop; byte [] byte

Excel匯入時間格式在Java轉換

我們從Excel中獲取的時間格式日期(例如 2018-05-01)實際在Java中獲取的值為4000多的一個數值,這個數值是距離1900-01-01的天數; //時間轉換 Calendar c = new GregorianCalendar(1900,0,-1); Date date= DateU

Java型別轉換問題整理...

Java中型別轉換是經常遇到的問題,這裡用來更新和總結型別轉換的方法和問題,以便日後回顧: Java裡基本資料型別有哪幾種?分別佔多大記憶體?在64位JVM裡呢? 思路:8大基本資料型別,佔位長固定與系統無關。 答:8種,按長度大小依次是: byte = 8 bit ; boo

java的攔截(登入)

題目要點: 如果登入了就跳轉到首頁,如果沒有登入直接訪問首頁的話,就攔截無法訪問,登入了就可以訪問主頁。 登入介面: <%--   Created by IntelliJ IDEA.   User: Smile   Date: 2018/11/12 &

spring boot 自定義訊息轉換

需求分析:在請求返回中,想統一返回的資料格式。在controller層中通過aop中的環繞通知實現了這個功能。但是在轉換的過程中,提示沒有自定義的格式轉換器。所有我們需要自己實現這個轉換器。 實現方式:通過繼承 AbstractHttpMessageConverter這個類來實現功能。 pu

自定義一個自己的訊息轉換

1.自定義個訊息轉換器,支援自己定義的content-type型別.首先準備好測試的controller類; @PostMapping("/") public Object test(@RequestBody UserInfo userInfo) { return

JavaDate轉換大全,返回yyyy-MM-dd的Date型別

/** * 獲取現在時間,這個好用 * * @return返回長時間格式 yyyy-MM-dd HH:mm:ss */ public static Date getSqlDate() { Date sqlDate = new java.sql

java時間轉換】,當MM變成了mm,當DD變成了dd,會發生什麼事?

記自己一次無知的寫法,導致專案產生一個異常。下面拿出例項: 我負責接收介面傳遞過來的引數,做相應的轉換,出入資料庫中,一個時間的通過字串的形式傳遞過來,這個時間是24小時制,我的轉化如下: JSO

javaTimer定時的使用

本博文只是簡單介紹一下Timer的使用方法。適用於初學者進行參考,希望大家多多指點。廢話不多說,直接上正題。 1、瞭解一下Timer類提供的方法 介紹幾個常用的方法: cancel() 終止此計時器,丟棄所有當前已安排的任務。 schedule(TimerTask t

Java迭代是什麼?

  可迭代是Java集合框架下的所有集合類的一種共性,也就是把集合中的所有元素遍歷一遍。迭代的過程需要依賴一個迭代器物件,那麼什麼是迭代器呢?    迭代器(Iterator)模式,又叫做遊標模式,它

Java迭代Iterator的使用Collection介面(list和set)和Map介面

Java集合類中Map介面下的相關類並沒有像Collection介面的相關類一樣實現get()方法,因此在要實現遍歷輸出的場景中沒法直接用get()方法來取得物件中的資料,但Java本身提供了另一種遍歷資料的方法,即用Iterator迭代器,雖然Iterator可以用來遍歷讀取資料,但它本質上不是一種方法,它

JavaJMX管理的作用,專案有什麼具體使用?

作者:wuxinliulei 連結:https://www.zhihu.com/question/36688387/answer/68667704 來源:知乎 著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。   JMX是一種JAVA的正式規範,它主要目的是讓程式有