我有一個控制器方法,添加了@ResponseBody註解java
@GetMapping(value = "/users") @ResponseBody public Map<String, Object> modelAttribute(Model model) { return model.asMap(); }
訪問該方法始終返回404,斷點發現方法有執行。返回錯誤以下:app
看到Message 提示是/WEB-INF/views/model/users.jsp 找不到。原來404 是這個,可是很奇怪不是已經添加了@ResponseBody註解嗎?jsp
爲何還會嘗試去尋找一個jsp視圖呢?this
爲此我斷點DispatcherServlet並一步步跟蹤,其緣由是在 HandlerMethodReturnValueHandlerComposite的 調用selectHandlerspa
尋找 返回值處理器(HandlerMethodReturnValueHandler)時blog
private HandlerMethodReturnValueHandler selectHandler(Object value, MethodParameter returnType) { boolean isAsyncValue = isAsyncReturnValue(value, returnType); for (HandlerMethodReturnValueHandler handler : this.returnValueHandlers) { if (isAsyncValue && !(handler instanceof AsyncHandlerMethodReturnValueHandler)) { continue; } if (handler.supportsReturnType(returnType)) { return handler; } } return null; }
調用 handler.supportsReturnType(returnType) 這一方法經過返回值來匹配對應的handler,優先匹配到的是 ModelMethodProcessor,接口
爲什麼是 ModelMethodProcessor, 查看其supportsReturnType方法:get
public boolean supportsReturnType(MethodParameter returnType) { return Model.class.isAssignableFrom(returnType.getParameterType()); }
其就是經過檢查返回值類型是否Model 接口類型,而ModelMethodProcessor 值處理器 又是跳轉視圖的,因此即便加了@ResponseBody註解依然會it
去尋找視圖。不知道這算不算是一個bug,這個坑千萬注意不要踩。class