Rest API: Json參數(shù)格式錯誤時顯示Json原文

后臺提供API給前端調(diào)用选调,一般使用HttpMessageConverter把Json字符串轉(zhuǎn)換成對象肩钠,如果存在格式問題則會拋出異常HttpMessageNotReadableException图甜。但是后臺拿不到原始的Json字符串,不方便定位到確切的格式錯誤。 本文介紹一個簡易方法祷膳,可以在出錯時,展示Json原文信息乃戈。

一開始想尋找其他方式褂痰,當(dāng)拋出異常的時候,就從HttpServletRequest讀取body內(nèi)容症虑。但是做不到缩歪,因為在做Json讀取的時候,InputStream已經(jīng)被讀取了谍憔,無法再次獲取到body內(nèi)容匪蝙。所以只能通過自定義MessageConverter的方式。

其實也可以韵卤,把request中inpustream讀取出來保存骗污,再提供一個getInputStream,參見 How to read request.getInputStream() multiple times

自定義MessageConverter

  • Spring4
import com.google.common.io.CharStreams;

public class HttpMessageConverter extends GsonHttpMessageConverter {

    @Override
    public Object read(Type type, Class<?> contextClass, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
        TypeToken<?> token = getTypeToken(type);
        return readTypeToken(token, inputMessage);
    }

    private Object readTypeToken(TypeToken<?> token, HttpInputMessage inputMessage) throws IOException {
        Reader json = new InputStreamReader(inputMessage.getBody(), getCharset(inputMessage.getHeaders()));
        //先獲取Json原始字符串
        final String jsonBody = CharStreams.toString(json);
        try {
            return this.getGson().fromJson(jsonBody, token.getType());
        } catch (JsonParseException ex) {
            //解析失敗沈条,則在異常中輸出Json原始字符串
            throw new HttpMessageNotReadableException(String.format("JSON parse error: %s%n%s", ex.getMessage(), jsonBody), ex);
        }
    }

    private Charset getCharset(HttpHeaders headers) {
        if (headers == null || headers.getContentType() == null || headers.getContentType().getCharset() == null) {
            return DEFAULT_CHARSET;
        }
        return headers.getContentType().getCharset();
    }
}
  • Spring 5
    在Spring 5中實現(xiàn)起來更加簡單
public class HttpMessageConverter extends GsonHttpMessageConverter {
    @Override
    protected Object readInternal(Type resolvedType, Reader reader) throws Exception {
        String jsonBody = CharStreams.toString(reader);
        try {
            return this.getGson().fromJson(jsonBody, resolvedType);
        } catch (JsonParseException ex) {
            //解析失敗需忿,則在異常中輸出Json原始字符串
            throw new JsonParseException(String.format("JSON parse error: %s%n%s", ex.getMessage(), jsonBody), ex);
        }
    }
}

配置自定義MessageConverter

spring-mvc.xml

<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="com.tenmao.HttpMessageConverter" />
    </mvc:message-converters>
</mvc:annotation-driven>

結(jié)果

假設(shè)參數(shù)對象如下:

@Data
public class Person {
    private String name;
    private Integer age;
    private Boolean gender;
    private List<String> hobbies;
}

如果收到錯誤格式的Json消息,則會拋出異常(hobbies應(yīng)該是一個數(shù)組蜡歹,參數(shù)中是字符串basketball)

org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING at line 5 column 14 path $.hobbies
{
    "name": "tenmao",
    "gender": true,
    "age": 28,
    "hobbies": "basketball"
}; nested exception is com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING at line 5 column 14 path $.hobbies

參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末屋厘,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子月而,更是在濱河造成了極大的恐慌汗洒,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件父款,死亡現(xiàn)場離奇詭異溢谤,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)憨攒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進(jìn)店門世杀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人肝集,你說我怎么就攤上這事瞻坝。” “怎么了杏瞻?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵所刀,是天一觀的道長。 經(jīng)常有香客問我捞挥,道長浮创,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任砌函,我火速辦了婚禮蒸矛,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己雏掠,他們只是感情好斩祭,可當(dāng)我...
    茶點故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著乡话,像睡著了一般摧玫。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上绑青,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天诬像,我揣著相機(jī)與錄音,去河邊找鬼闸婴。 笑死坏挠,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的邪乍。 我是一名探鬼主播降狠,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼庇楞!你這毒婦竟也來了榜配?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤吕晌,失蹤者是張志新(化名)和其女友劉穎蛋褥,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體睛驳,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡烙心,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了乏沸。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片淫茵。...
    茶點故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖屎蜓,靈堂內(nèi)的尸體忽然破棺而出痘昌,到底是詐尸還是另有隱情钥勋,我是刑警寧澤炬转,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布,位于F島的核電站算灸,受9級特大地震影響扼劈,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜菲驴,卻給世界環(huán)境...
    茶點故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一荐吵、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦先煎、人聲如沸贼涩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽遥倦。三九已至,卻和暖如春占锯,著一層夾襖步出監(jiān)牢的瞬間袒哥,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工消略, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留堡称,地道東北人。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓艺演,卻偏偏與公主長得像却紧,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子钞艇,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,724評論 2 351

推薦閱讀更多精彩內(nèi)容

  • pyspark.sql模塊 模塊上下文 Spark SQL和DataFrames的重要類: pyspark.sql...
    mpro閱讀 9,448評論 0 13
  • 概要 64學(xué)時 3.5學(xué)分 章節(jié)安排 電子商務(wù)網(wǎng)站概況 HTML5+CSS3 JavaScript Node 電子...
    阿啊阿吖丁閱讀 9,146評論 0 3
  • 六點三十三分啄寡。 我總在這個時候醒來,一連幾日哩照,這極為怪異挺物,也極其巧合。我拉開窗簾飘弧,趴在窗戶上看是否有雪识藤,是否皚皚如...
    炑子是我閱讀 217評論 0 0
  • 先看下hustoj源碼里用到的用戶密碼加密函數(shù)和驗證函數(shù) 滿滿的黑歷史,可以看出最早這個系統(tǒng)居然是明文存密碼的次伶,或...
    蘿卜luob閱讀 548評論 0 0
  • 幸福是會重生的痴昧。 它會改變模樣,以各種各樣的形態(tài)冠王,一次次悄然來到尋求它的人身邊赶撰。 今天聽課到鳳凰的清冷...
    元合閱讀 158評論 0 0