日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring MVC 4.1 支持jsonp

發布時間:2025/3/21 javascript 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring MVC 4.1 支持jsonp 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

使用ResponseBodyAdvice支持jsonp

ResponseBodyAdvice是一個接口,接口描述,

package?org.springframework.web.servlet.mvc.method.annotation;/***?Allows?customizing?the?response?after?the?execution?of?an?{@code?@ResponseBody}*?or?an?{@code?ResponseEntity}?controller?method?but?before?the?body?is?written*?with?an?{@code?HttpMessageConverter}.**?<p>Implementations?may?be?may?be?registered?directly?with*?{@code?RequestMappingHandlerAdapter}?and?{@code?ExceptionHandlerExceptionResolver}*?or?more?likely?annotated?with?{@code?@ControllerAdvice}?in?which?case?they*?will?be?auto-detected?by?both.**?@author?Rossen?Stoyanchev*?@since?4.1*/ public?interface?ResponseBodyAdvice<T>?{/***?Whether?this?component?supports?the?given?controller?method?return?type*?and?the?selected?{@code?HttpMessageConverter}?type.*?@param?returnType?the?return?type*?@param?converterType?the?selected?converter?type*?@return?{@code?true}?if?{@link?#beforeBodyWrite}?should?be?invoked,?{@code?false}?otherwise*/boolean?supports(MethodParameter?returnType,?Class<??extends?HttpMessageConverter<?>>?converterType);/***?Invoked?after?an?{@code?HttpMessageConverter}?is?selected?and?just?before*?its?write?method?is?invoked.*?@param?body?the?body?to?be?written*?@param?returnType?the?return?type?of?the?controller?method*?@param?selectedContentType?the?content?type?selected?through?content?negotiation*?@param?selectedConverterType?the?converter?type?selected?to?write?to?the?response*?@param?request?the?current?request*?@param?response?the?current?response*?@return?the?body?that?was?passed?in?or?a?modified,?possibly?new?instance*/T?beforeBodyWrite(T?body,?MethodParameter?returnType,?MediaType?selectedContentType,Class<??extends?HttpMessageConverter<?>>?selectedConverterType,ServerHttpRequest?request,?ServerHttpResponse?response);}

作用:

Allows customizing the response after the execution of an {@code @ResponseBody} or an {@code ResponseEntity} controller method but before the body is written

with an {@code HttpMessageConverter}.

其中一個方法就是?beforeBodyWrite 在使用相應的HttpMessageConvert 進行write之前會被調用,就是一個切面方法。

和jsonp有關的實現類是AbstractJsonpResponseBodyAdvice,如下是?beforeBodyWrite 方法的實現,

@Override public?final?Object?beforeBodyWrite(Object?body,?MethodParameter?returnType,MediaType?contentType,?Class<??extends?HttpMessageConverter<?>>?converterType,ServerHttpRequest?request,?ServerHttpResponse?response)?{MappingJacksonValue?container?=?getOrCreateContainer(body);beforeBodyWriteInternal(container,?contentType,?returnType,?request,?response);return?container; }

位于AbstractJsonpResponseBodyAdvice的父類中,而beforeBodyWriteInternal是在AbstractJsonpResponseBodyAdvice中實現的?,如下,

@Override protected?void?beforeBodyWriteInternal(MappingJacksonValue?bodyContainer,?MediaType?contentType,MethodParameter?returnType,?ServerHttpRequest?request,?ServerHttpResponse?response)?{HttpServletRequest?servletRequest?=?((ServletServerHttpRequest)?request).getServletRequest();for?(String?name?:?this.jsonpQueryParamNames)?{String?value?=?servletRequest.getParameter(name);if?(value?!=?null)?{MediaType?contentTypeToUse?=?getContentType(contentType,?request,?response);response.getHeaders().setContentType(contentTypeToUse);bodyContainer.setJsonpFunction(value);return;}} }

就是根據callback 請求參數或配置的其他參數來確定返回jsonp協議的數據。

如何實現jsonp?

首先繼承AbstractJsonpResponseBodyAdvice ,如下,

package?com.usoft.web.controller.jsonp;import?org.springframework.web.bind.annotation.ControllerAdvice; import?org.springframework.web.servlet.mvc.method.annotation.AbstractJsonpResponseBodyAdvice;/***?*/ @ControllerAdvice(basePackages?=?"com.usoft.web.controller.jsonp") public?class?JsonpAdvice?extends?AbstractJsonpResponseBodyAdvice?{public?JsonpAdvice()?{super("callback",?"jsonp");} }

?super("callback", "jsonp");的意思就是當請求參數中包含callback 或 jsonp參數時,就會返回jsonp協議的數據。其value就作為回調函數的名稱。

這里必須使用@ControllerAdvice注解標注該類,并且配置對哪些Controller起作用。關于注解@ControllerAdvice?的作用這里不做描述。

Controller實現jsonp,

package?com.usoft.web.controller.jsonp;import?org.springframework.stereotype.Controller; import?org.springframework.web.bind.annotation.RequestMapping; import?org.springframework.web.bind.annotation.ResponseBody;import?com.usoft.web.controller.JsonMapper; import?com.usoft.web.controller.Person;/***?jsonp*/ @Controller public?class?JsonpController?{/***?callback({"id":1,"age":12,"name":"lyx"})*?*?@param?args*/public?static?void?main(String?args[])?{Person?person?=?new?Person(1,?"lyx",?12);System.out.println(JsonMapper.nonNullMapper().toJsonP("callback",person));}@RequestMapping("/jsonp1")public?Person?jsonp1()?{return?new?Person(1,?"lyx",?12);}@RequestMapping("/jsonp2")@ResponseBodypublic?Person?jsonp2()?{return?new?Person(1,?"lyx",?12);}@RequestMapping("/jsonp3")@ResponseBodypublic?String?jsonp3()?{return?JsonMapper.nonNullMapper().toJsonP("callback",new?Person(1,?"lyx",?12));} }

jsonp2 方法就是 一個jsonp協議的調用。http://localhost:8081/jsonp2?callback=test可以直接調用這個方法,并且返回jsonp協議的數據。

通過debug代碼,我們來看一下他是怎么返回jsonp協議的數據的。

正因為我們前面在 該Controller 上配置了?JsonpAdvice 的?ControllerAdvice,在調用?MappingJackson2HttpMessageConverter的write()方法往回寫數據的時候,首先會調用

beforeBodyWrite,具體的代碼如下,

@Override protected?void?beforeBodyWriteInternal(MappingJacksonValue?bodyContainer,?MediaType?contentType,MethodParameter?returnType,?ServerHttpRequest?request,?ServerHttpResponse?response)?{HttpServletRequest?servletRequest?=?((ServletServerHttpRequest)?request).getServletRequest();for?(String?name?:?this.jsonpQueryParamNames)?{String?value?=?servletRequest.getParameter(name);if?(value?!=?null)?{MediaType?contentTypeToUse?=?getContentType(contentType,?request,?response);response.getHeaders().setContentType(contentTypeToUse);bodyContainer.setJsonpFunction(value);return;}} }

當請求參數中含有配置的相應的回調參數時,就會bodyContainer.setJsonpFunction(value);這就標志著 返回的數據時jsonp格式的數據。

然后接下來就到了?MappingJackson2HttpMessageConverter 的write()方法真正寫數據的時候了。看他是怎么寫數據的,相關的代碼如下,

@Override protected?void?writeInternal(Object?object,?HttpOutputMessage?outputMessage)throws?IOException,?HttpMessageNotWritableException?{JsonEncoding?encoding?=?getJsonEncoding(outputMessage.getHeaders().getContentType());JsonGenerator?generator?=?this.objectMapper.getFactory().createGenerator(outputMessage.getBody(),?encoding);try?{writePrefix(generator,?object);Class<?>?serializationView?=?null;Object?value?=?object;if?(value?instanceof?MappingJacksonValue)?{MappingJacksonValue?container?=?(MappingJacksonValue)?object;value?=?container.getValue();serializationView?=?container.getSerializationView();}if?(serializationView?!=?null)?{this.objectMapper.writerWithView(serializationView).writeValue(generator,?value);}else?{this.objectMapper.writeValue(generator,?value);}writeSuffix(generator,?object);generator.flush();}catch?(JsonProcessingException?ex)?{throw?new?HttpMessageNotWritableException("Could?not?write?content:?"?+?ex.getMessage(),?ex);} } @Override protected?void?writePrefix(JsonGenerator?generator,?Object?object)?throws?IOException?{if?(this.jsonPrefix?!=?null)?{generator.writeRaw(this.jsonPrefix);}String?jsonpFunction?=(object?instanceof?MappingJacksonValue???((MappingJacksonValue)?object).getJsonpFunction()?:?null);if?(jsonpFunction?!=?null)?{generator.writeRaw(jsonpFunction?+?"(");} } @Override protected?void?writeSuffix(JsonGenerator?generator,?Object?object)?throws?IOException?{String?jsonpFunction?=(object?instanceof?MappingJacksonValue???((MappingJacksonValue)?object).getJsonpFunction()?:?null);if?(jsonpFunction?!=?null)?{generator.writeRaw(");");} }

代碼非常清晰??次覀僯sonp調用的結果。

http://localhost:8081/jsonp2?callback=test

響應消息如下,

HTTP/1.1 200 OK

Server: Apache-Coyote/1.1

Content-Type: application/javascript

Transfer-Encoding: chunked

Date: Sun, 19 Jul 2015 13:01:02 GMT

?

test({"id":1,"age":12,"name":"lyx"});

轉載于:https://my.oschina.net/thinwonton/blog/1457254

總結

以上是生活随笔為你收集整理的Spring MVC 4.1 支持jsonp的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。