在與前端開發人員合作過程中,經常遇到跨域名通路的問題,通常我們是通過jsonp調用方式來解決。jsop百科:http://baike.baidu.com/link?url=JKlwoETqx2uuKeoRwlk_y6HZ9FZxXTARLwm7QFOmuqex5p6-Ch5GQpSM5juf614F8hYaP2N3wDkU26slwvtnOa
如:請求 http://xxxx?&callback=exec , 那麼傳回的jsonp格式為 exec({"code":0, "message":"success"}); 。 其實對于格式的重新封裝并不複雜,但是對于某個請求既要支援json傳回也要支援jsop傳回怎麼做,那我們就得做個判斷, if(request.getParameter("callback") != null), 如果存在就傳回jsonp, 不存在就傳回json。
在使用springmvc的場景下,如何利用springmvc來傳回jsonp格式,有很多方式可以實作。 這裡介紹一種比較簡單但比較通用的處理方式。前提是你使用的springmvc是4.1版本及以上。主要是要繼承類AbstractJsonpResponseBodyAdvice, 并加入@ControllerAdvice 這個注解,basePackages 辨別要被處理的controller。
實作代碼如下:
1 @ControllerAdvice(basePackages = "xxx.controller")
2 public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice {
3
4 private final String[] jsonpQueryParamNames;
5
6 public JsonpAdvice() {
7 super("callback", "jsonp");
8 this.jsonpQueryParamNames = new String[]{"callback"};
9 }
10
11 @Override
12 protected void beforeBodyWriteInternal(MappingJacksonValue bodyContainer, MediaType contentType,
13 MethodParameter returnType, ServerHttpRequest request, ServerHttpResponse response) {
14
15 HttpServletRequest servletRequest = ((ServletServerHttpRequest) request).getServletRequest();
16
17 //如果不存在callback這個請求參數,直接傳回,不需要處理為jsonp
18 if (ObjectUtils.isEmpty(servletRequest.getParameter("callback"))) {
19 return;
20 }
21 //按設定的請求參數(JsonAdvice構造方法中的this.jsonpQueryParamNames = new String[]{"callback"};),處理傳回結果為jsonp格式
22 for (String name : this.jsonpQueryParamNames) {
23 String value = servletRequest.getParameter(name);
24 if (value != null) {
25 MediaType contentTypeToUse = getContentType(contentType, request, response);
26 response.getHeaders().setContentType(contentTypeToUse);
27 bodyContainer.setJsonpFunction(value);
28 return;
29 }
30 }
31 }
32 }