上一篇我們提到了使用jsonp來解決getjson的跨域訪問問題,服務器需要對數據進行一次封裝,實際上jersey已經實現了這個功能,具體用法也很簡單,加上@JSONP
標識就行。
對上一篇的服務器代碼進行修改:
@GET
@JSONP(queryParam = "jsoncallback")
@Path("/test")
@Produces("application/json;charset=utf8")
public String go(){
return info;
}
其中queryparam給出了封裝時使用的函數名,在客戶端提交數據請求時,url地址就是****?jsoncallback=?
。
OK,這樣就搞定了,當然了,如果需要更進一步的操作,比如說對輸出的內容進行深度加工,那麼可以參考jersey的實現,源代碼在這裏:JsonWithPaddingInterceptor.java。
比如說同樣的功能,自己來實現。看上邊的源碼,是用攔截器實現的,把源碼修改下:
@javax.ws.rs.ext.Provider
public class JsonWithPaddingInterceptor implements WriterInterceptor {
private static final Map<String, Set<String>> JAVASCRIPT_TYPES;
static {
JAVASCRIPT_TYPES = new HashMap<>(2);
JAVASCRIPT_TYPES.put("application", Arrays.asList("x-javascript", "ecmascript", "javascript")
.stream().collect(Collectors.toSet()));
JAVASCRIPT_TYPES.put("text", Arrays.asList("javascript", "x-javascript", "ecmascript", "jscript")
.stream().collect(Collectors.toSet()));
}
@Inject
private Provider<ContainerRequest> containerRequestProvider;
/***實現具體操作的函數****/
@Override
public void aroundWriteTo(final WriterInterceptorContext context) throws IOException, WebApplicationException {
String callbackname = getCallbackName();
if (callbackname!=null) {
context.setMediaType(MediaType.APPLICATION_JSON_TYPE);
context.getOutputStream().write(callbackname.getBytes(MessageUtils.getCharset(context.getMediaType())));
context.getOutputStream().write('(');
}
//這裏可以添加自己感興趣的東西
context.proceed();
if (callbackname!=null) {
context.getOutputStream().write(')');
}
}
/**
* Returns a JavaScript callback name to wrap the JSON entity into. The callback name is determined from the url
* @return a JavaScript callback name.
*/
private String getCallbackName() {
final ContainerRequest containerRequest = containerRequestProvider.get();
final UriInfo uriInfo = containerRequest.getUriInfo();
final MultivaluedMap<String, String> queryParameters = uriInfo.getQueryParameters();
if(queryParameters.get("jsoncallback")!=null)
return queryParameters.getFirst("jsoncallback");
return null;
}
}
對源碼改動不大,刪除了點兒東西,功能也僅僅是進行了數據封裝。
攔截器的代碼完成,下一步需要在web.xml裏註冊。
<servlet>
……
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider, ***.JsonWithPaddingInterceptor</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
在<init-param>
的jersey.config.server.provider.classnames
裏已經有了一個provider,再把攔截器的類加進去就行了。