@Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception { response.setHeader("Content-Type", "text/json;charset=UTF-8"); CMessage cmsg = CMessage.getInstance(request, response); cmsg.setTimes(getTimes()); response.setHeader("CMessage", cmsg.toString()); }
原本是想經過 攔截器 統一處理,給reponse設置一個自定義的Header。 後來發現一直沒有生效。瀏覽器里老是看不到自定義的header信息。 後來發現 沒有用到spring @ResponseBody這個註解的方法就有。java
跟了一下源碼 web
@Override public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws IOException, HttpMediaTypeNotAcceptableException,HttpMessageNotWritableException{ mavContainer.setRequestHandled(true); ServletServerHttpRequest inputMessage = createInputMessage(webRequest); ServletServerHttpResponse outputMessage = createOutputMessage(webRequest); // Try even with null return value. ResponseBodyAdvice could get involved. writeWithMessageConverters(returnValue, returnType, inputMessage, outputMessage); }
在用到@ResponseBody這個玩意的時候,它把 response 和 request都作了一下處理。並在這裏調用write方法 。 spring
public void write(Object t, Type type, MediaType contentType, HttpOutputMessage outputMessage ) throws IOException, HttpMessageNotWritableException { HttpHeaders headers = outputMessage.getHeaders(); if (headers.getContentType() == null) { if (contentType == null || contentType.isWildcardType() || contentType.isWildcardSubtype()) { contentType = getDefaultContentType(t); } if (contentType != null) { headers.setContentType(contentType); } } if (headers.getContentLength() == -1) { Long contentLength = getContentLength(t, headers.getContentType()); if (contentLength != null) { headers.setContentLength(contentLength); } } writeInternal(t, outputMessage); outputMessage.getBody().flush(); }
在這裏 它已經給你寫出去了。並flush了。 因此致使了在postHandler裏的攔截無效了json
個人作法是 寫個類實現 ResponseBodyAdvice。 這個裏面有個 beforeBodyWrite方法 。 它先於write執行。 在這個裏面 不少人都是用它來處理 body。由於這個方法的參數 只有它本身的ServerHttpRequest request, ServerHttpResponse response。 沒有提供設置 cookies 或者 header的方法。瀏覽器
ServerHttpResponse 裏面沒有。 但它的實現類ServletServerHttpResponse 這個裏面有HttpServletResponse 。因而就有了下面這個代碼:cookie
public SMessage beforeBodyWrite(SMessage body, MethodParameter returnType, MediaType selectedContentType,Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,ServerHttpResponse response) { HttpServletRequest req = ((ServletServerHttpRequest) request).getServletRequest(); HttpServletResponse res = ((ServletServerHttpResponse) response).getServletResponse(); res.setHeader("Content-Type", "text/json;charset=UTF-8"); try { CMessage cmsg = (CMessage)req.getAttribute("CMessage"); cmsg.setTimes(getTimes()); res.setHeader("CMessage", cmsg.toString()); }catch (Exception e) { e.printStackTrace(); } return body; }
這樣就解決了 上面說的問題了。ide