实现跨域请求jsonp方式
原理:http://madong.net.cn/index.php/2012/12/368/
调用端:
$.getJSON("http://192.168.220.85:8001/esb/autocredit/test?callback=?",function(data){
alert(data);
});
服务端:(基于spring mvc @RestController 或 @ResponseBody注解)
更改源码:ServletInvocableHandlerMethod.java
主要添加:
---------------------------------------------
String parameter = webRequest.getParameter("callback");
if (parameter != null) {
returnValue = parameter + "(" + returnValue.toString() + ")";
}
---------------------------------------------
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.servlet.mvc.method.annotation;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;
import org.springframework.http.HttpStatus;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite;
import org.springframework.web.method.support.InvocableHandlerMethod;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.View;
import org.springframework.web.util.NestedServletException;
/**
* Extends {@link InvocableHandlerMethod} with the ability to handle return
* values through a registered {@link HandlerMethodReturnValueHandler} and also
* supports setting the response status based on a method-level
* {@code @ResponseStatus} annotation.
*
* <p>
* A {@code null} return value (including void) may be interpreted as the end of
* request processing in combination with a {@code @ResponseStatus} annotation,
* a not-modified check condition (see
* {@link ServletWebRequest#checkNotModified(long)}), or a method argument that
* provides access to the response stream.
*
* @author Rossen Stoyanchev
* @since 3.1
*/
public class ServletInvocableHandlerMethod extends InvocableHandlerMethod {
private HttpStatus responseStatus;
private String responseReason;
private HandlerMethodReturnValueHandlerComposite returnValueHandlers;
/**
* Creates an instance from the given handler and method.
*/
public ServletInvocableHandlerMethod(Object handler, Method method) {
super(handler, method);
initResponseStatus();
}
/**
* Create an instance from a {@code HandlerMethod}.
*/
public ServletInvocableHandlerMethod(HandlerMethod handlerMethod) {
super(handlerMethod);
initResponseStatus();
}
private void initResponseStatus() {
ResponseStatus annot = getMethodAnnotation(ResponseStatus.class);
if (annot != null) {
this.responseStatus = annot.value();
this.responseReason = annot.reason();
}
}
/**
* Register {@link HandlerMethodReturnValueHandler} instances to use to
* handle return values.
*/
public void setHandlerMethodReturnValueHandlers(HandlerMethodReturnValueHandlerComposite returnValueHandlers) {
this.returnValueHandlers = returnValueHandlers;
}
/**
* Invokes the method and handles the return value through a registered
* {@link HandlerMethodReturnValueHandler}.
*
* @param webRequest
* the current request
* @param mavContainer
* the ModelAndViewContainer for this request
* @param providedArgs
* "given" arguments matched by type, not resolved
*/
public final void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {
Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
// 为实现跨域请求 添加实现 add by x
String parameter = webRequest.getParameter("callback");
if (parameter != null) {
returnValue = parameter + "(" + returnValue.toString() + ")";
}
// 为实现跨域请求 添加实现 add by x
setResponseStatus(webRequest);
if (returnValue == null) {
if (isRequestNotModified(webRequest) || hasResponseStatus() || mavContainer.isRequestHandled()) {
mavContainer.setRequestHandled(true);
return;
}
} else if (StringUtils.hasText(this.responseReason)) {
mavContainer.setRequestHandled(true);
return;
}
mavContainer.setRequestHandled(false);
try {
this.returnValueHandlers.handleReturnValue(returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
} catch (Exception ex) {
if (logger.isTraceEnabled()) {
logger.trace(getReturnValueHandlingErrorMessage("Error handling return value", returnValue), ex);
}
throw ex;
}
}
/**
* Set the response status according to the {@link ResponseStatus}
* annotation.
*/
private void setResponseStatus(ServletWebRequest webRequest) throws IOException {
if (this.responseStatus == null) {
return;
}
if (StringUtils.hasText(this.responseReason)) {
webRequest.getResponse().sendError(this.responseStatus.value(), this.responseReason);
} else {
webRequest.getResponse().setStatus(this.responseStatus.value());
}
// to be picked up by the RedirectView
webRequest.getRequest().setAttribute(View.RESPONSE_STATUS_ATTRIBUTE, this.responseStatus);
}
/**
* Does the given request qualify as "not modified"?
*
* @see ServletWebRequest#checkNotModified(long)
* @see ServletWebRequest#checkNotModified(String)
*/
private boolean isRequestNotModified(ServletWebRequest webRequest) {
return webRequest.isNotModified();
}
/**
* Does this method have the response status instruction?
*/
private boolean hasResponseStatus() {
return responseStatus != null;
}
private String getReturnValueHandlingErrorMessage(String message, Object returnValue) {
StringBuilder sb = new StringBuilder(message);
if (returnValue != null) {
sb.append(" [type=" + returnValue.getClass().getName() + "] ");
}
sb.append("[value=" + returnValue + "]");
return getDetailedErrorMessage(sb.toString());
}
/**
* Create a ServletInvocableHandlerMethod that will return the given value
* from an async operation instead of invoking the controller method again.
* The async result value is then either processed as if the controller
* method returned it or an exception is raised if the async result value
* itself is an Exception.
*/
ServletInvocableHandlerMethod wrapConcurrentResult(final Object result) {
return new CallableHandlerMethod(new Callable<Object>() {
@Override
public Object call() throws Exception {
if (result instanceof Exception) {
throw (Exception) result;
} else if (result instanceof Throwable) {
throw new NestedServletException("Async processing failed", (Throwable) result);
}
return result;
}
});
}
/**
* A sub-class of {@link HandlerMethod} that invokes the given
* {@link Callable} instead of the target controller method. This is useful
* for resuming processing with the result of an async operation. The goal
* is to process the value returned from the Callable as if it was returned
* by the target controller method, i.e. taking into consideration both
* method and type-level controller annotations (e.g. {@code @ResponseBody},
* {@code @ResponseStatus}, etc).
*/
private class CallableHandlerMethod extends ServletInvocableHandlerMethod {
public CallableHandlerMethod(Callable<?> callable) {
super(callable, ClassUtils.getMethod(callable.getClass(), "call"));
this.setHandlerMethodReturnValueHandlers(ServletInvocableHandlerMethod.this.returnValueHandlers);
}
/**
* Bridge to type-level annotations of the target controller method.
*/
@Override
public Class<?> getBeanType() {
return ServletInvocableHandlerMethod.this.getBeanType();
}
/**
* Bridge to method-level annotations of the target controller method.
*/
@Override
public <A extends Annotation> A getMethodAnnotation(Class<A> annotationType) {
return ServletInvocableHandlerMethod.this.getMethodAnnotation(annotationType);
}
}
}
实现跨域请求jsonp方式的更多相关文章
- 浏览器同源策略,跨域请求jsonp
浏览器的同源策略 浏览器安全的基石是"同源政策"(same-origin policy) 含义: 1995年,同源政策由 Netscape 公司引入浏览器.目前,所有浏览器都实行这 ...
- AJAX 跨域请求 - JSONP获取JSON数据
Asynchronous JavaScript and XML (Ajax ) 是驱动新一代 Web 站点(流行术语为 Web 2.0 站点)的关键技术.Ajax 允许在不干扰 Web 应用程序的显示 ...
- jquery跨域请求jsonp
服务端PHP代码 header('Content-Type:application/json; charset=utf-8'); $arr = array('a'=>1, 'b'=>2, ...
- 跨域请求 & jsonp
0 什么是跨域请求 在一个域名下请求另外一个域名下的资源,就是跨域请求.example 1:比如:我当前的域名是http://che.pingan.com.我现在要去请求http://www.cnbl ...
- 关于laravel框架的跨域请求/jsonp请求的理解
最近刚接触laravel框架,首先要写一个跨域的单点登录.被跨域的问题卡了两三天,主要是因为对跨域这快不了解,就在刚才有点茅塞顿开的感觉,我做一下大概整理,主要给一些刚接触摸不着头脑的看,哪里写得不对 ...
- 【转】AJAX 跨域请求 - JSONP获取JSON数据
来源:http://justcoding.iteye.com/blog/1366102/ Asynchronous JavaScript and XML (Ajax ) 是驱动新一代 Web 站点(流 ...
- ajax跨域请求のJSONP
简单说了一下,JSON是一种基于文本的数据交换方式,或者叫做数据描述格式. JSON的优点: 1.基于纯文本,跨平台传递极其简单: 2.Javascript原生支持,后台语言几乎全部支持: 3.轻量级 ...
- Ajax的跨域请求——JSONP的使用
一.什么叫跨域 域当然是别的服务器 (说白点就是去别服务器上取东西) 只要协议.域名.端口有任何一个不同,都被当作是不同的域. 总而言之,同源策略规定,浏览器的ajax只能访问跟它的HTML页面同源( ...
- 循序渐进Python3(十一) --6-- Ajax 实现跨域请求 jsonp 和 cors
Ajax操作如何实现跨域请求? Ajax (XMLHttpRequest)请求受到同源策略的限制. Ajax通过XMLHttpRequest能够与远程的服务器进行信息交互,另外 ...
随机推荐
- npoi与memcached中的ICSharpCode.SharpZipLib版本冲突的解决方案
项目中一直使用NPOI与memcached,一直相安无事,但是最近升级了npoi到最新版本,发生了ICSharpCode.SharpZipLib的版本冲突问题. 因为此前一直使用的是NPOI的1.x的 ...
- 20+功能强大的jQuery/CSS3图片特效插件
以下是分享的20几个不错的图片特效插件,基于jQuery和CSS3. 1.jQuery图片下滑切换播放效果 这是一款基于jQuery的焦点图插件,这款焦点图的特点是有向下滑动的动画效果,滑到底部时,有 ...
- JSONP跨域请求数据报错 “Unexpected token :”的解决办法
原文 http://www.cnphp6.com/archives/65409 Jquery使用ajax方法实现jsonp跨域请求数据的时候报错 “Uncaught SyntaxError: Une ...
- C8051 SMBus 原理
一.SMBus总线 SMBus串行I/O接口完全符合系统管理总线规范 1.1 版.它是一个双线的双向串行总线,与I2C串行总线兼容.系统控制器对总线的读写操作都是以字节为单位的,由SMBus接口自 ...
- 将在本地创建的Git仓库push到Git@OSC
引用自:http://my.oschina.net/flan/blog/162189 在使用git 处理对android的修改的过程之中总结的.但不完善 Git push $ git push ori ...
- JavaScript高级之词法作用域和作用域链
主要内容: 分析JavaScript的词法作用域的含义 解析变量的作用域链 变量名提升时什么 一.关于块级作用域 说到JavaScript的变量作用域,与咱们平时使用的类C语言不同. ...
- Android代码优化——使用Android lint工具
作为移动应用开发者,我们总希望发布的apk文件越小越好,不希望资源文件没有用到的图片资源也被打包进apk,不希望应用中使用了高于minSdk的api,也不希望AndroidManifest文件存在异常 ...
- 路由器换大Flash
使用winhex自建编程器固件(我的是TP-WR941N V6) 1:使用winhex新建一个8M,16M的文件,编辑-全选,填充选块,填充十六进制数值 FF : 2:打开4M的原厂编程器固件(或者自 ...
- MFC ADO连接Oracle12c数据库 客户端环境搭建
ADO连接方式一:Provider=MSDAORA.1; 环境配置如下: 去官网下载ODAC121024Xcopy_32bit.zip安装 安装方式如下: (1)解压文件 (2)用命令行CD到该文件的 ...
- SpringMVC Controller 返回值的可选类型
spring mvc 支持如下的返回方式:ModelAndView, Model, ModelMap, Map,View, String, void. ModelAndView @RequestMap ...