在春天,我有一個端點的控制,像這樣:春讀取請求時身中兩刀
@RequestMapping(method = RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
@ResponseBody
public OutputStuff createStuff(@RequestBody Stuff stuff) {
//my logic here
}
如果這樣做對這個端點的POST,在請求主體的JSON會自動反序列化到我的模型( Stuff
)。問題是,我剛剛獲得了登錄原始JSON的要求,因爲它正在進入!我嘗試了不同的方法。
- 進樣
HttpServletRequest
到createStuff
,看身體有和日誌:
代碼:
@RequestMapping(method = RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
@ResponseBody
public OutputStuff createStuff(@RequestBody Stuff stuff, HttpServletRequest req) {
StringBuilder sb = new StringBuilder();
req.getReader().getLines().forEach(line -> {
sb.append(line);
});
//log sb.toString();
//my logic here
}
這樣做的問題是,到時候我執行此,讀者的InputStream會已經被執行以將JSON反序列化爲Stuff
。所以我會得到一個錯誤,因爲我無法兩次讀取相同的輸入流。
- 使用自定義
HandlerInterceptorAdapter
可以在調用實際處理程序之前記錄原始JSON。
代碼(一部分):
public class RawRequestLoggerInterceptor extends HandlerInterceptorAdapter {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
StringBuilder sb = new StringBuilder();
req.getReader().getLines().forEach(line -> {
sb.append(line);
});
//log sb.toString();
return true;
}
}
本壽的問題是,通過反序列化到stuff
發生的時間,從請求中的InputStream本來已經閱讀!所以我會再次遇到異常。
另一種選擇我考慮過,但還沒有實現,會以某種方式強迫Spring使用我的
HttpServletRequest
自定義實現,將緩存輸入流,並允許它的多個讀取。我不知道這是否可行,我找不到任何文檔或例子!另一種選擇是不是我的終點閱讀
Stuff
,而是讀取請求身體String
,記錄它,然後使用ObjectMapper
或類似的東西,它反序列化Stuff
。我不喜歡這個想法。
有沒有更好的解決方案,我沒有提及和/或我不知道?我會很感激幫助。我正在使用SpringBoot的最新版本。
謝謝,這看起來很有希望,我給它一個去! –
它工作嗎?:-) – Nate
是的,我們確實使用Logging Filter,謝謝:) –