原理: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方式的更多相关文章

  1. 浏览器同源策略,跨域请求jsonp

    浏览器的同源策略 浏览器安全的基石是"同源政策"(same-origin policy) 含义: 1995年,同源政策由 Netscape 公司引入浏览器.目前,所有浏览器都实行这 ...

  2. AJAX 跨域请求 - JSONP获取JSON数据

    Asynchronous JavaScript and XML (Ajax ) 是驱动新一代 Web 站点(流行术语为 Web 2.0 站点)的关键技术.Ajax 允许在不干扰 Web 应用程序的显示 ...

  3. jquery跨域请求jsonp

    服务端PHP代码  header('Content-Type:application/json; charset=utf-8'); $arr = array('a'=>1, 'b'=>2, ...

  4. 跨域请求 & jsonp

    0 什么是跨域请求 在一个域名下请求另外一个域名下的资源,就是跨域请求.example 1:比如:我当前的域名是http://che.pingan.com.我现在要去请求http://www.cnbl ...

  5. 关于laravel框架的跨域请求/jsonp请求的理解

    最近刚接触laravel框架,首先要写一个跨域的单点登录.被跨域的问题卡了两三天,主要是因为对跨域这快不了解,就在刚才有点茅塞顿开的感觉,我做一下大概整理,主要给一些刚接触摸不着头脑的看,哪里写得不对 ...

  6. 【转】AJAX 跨域请求 - JSONP获取JSON数据

    来源:http://justcoding.iteye.com/blog/1366102/ Asynchronous JavaScript and XML (Ajax ) 是驱动新一代 Web 站点(流 ...

  7. ajax跨域请求のJSONP

    简单说了一下,JSON是一种基于文本的数据交换方式,或者叫做数据描述格式. JSON的优点: 1.基于纯文本,跨平台传递极其简单: 2.Javascript原生支持,后台语言几乎全部支持: 3.轻量级 ...

  8. Ajax的跨域请求——JSONP的使用

    一.什么叫跨域 域当然是别的服务器 (说白点就是去别服务器上取东西) 只要协议.域名.端口有任何一个不同,都被当作是不同的域. 总而言之,同源策略规定,浏览器的ajax只能访问跟它的HTML页面同源( ...

  9. 循序渐进Python3(十一) --6--  Ajax 实现跨域请求 jsonp 和 cors

    Ajax操作如何实现跨域请求?       Ajax (XMLHttpRequest)请求受到同源策略的限制.       Ajax通过XMLHttpRequest能够与远程的服务器进行信息交互,另外 ...

随机推荐

  1. 架构模式之REST架构

    直至今日,分布式系统(Distributed System)已经取得了大规模的应用,特别是Web的发展,已经给软件开发带来了翻天覆地的变化,这一点已经毋庸置疑了. 构建分布式系统常用的技术通常就是使用 ...

  2. -webkit-min-device-pixel-ratio的常见值对照

    -webkit-min-device-pixel-ratio为1.0 所有非Retina的Mac 所有非Retina的iOS设备 Acer Iconia A500 Samsung Galaxy Tab ...

  3. uniGUI试用笔记(十四)TUniTreeView的CheckBox

    TUniTreeView目前版本没有封装CheckBox功能,所以需要手工处理,幸好0.99版提供部分代码了,修改过程如下: 1.uniGUIAbstractClasses.pas单元中修改基类TUn ...

  4. netty 编/解码处理

    1.LineBasedFrameDecoder 1.先找到结束符索引 private static int findEndOfLine(final ByteBuf buffer) { final in ...

  5. [CS231n-CNN] Backpropagation(反向传播算法)

    课程主页:http://cs231n.stanford.edu/ 上节讲到loss function: 引出了求导数使得loss function减小. -Back Propagation :梯度下降 ...

  6. Apk去签名校验详解

    某些apk为了防止重打包,使用了签名校验.所以在破解的时候我们需要破解签名校验.在定位签名校验位置时常用的关键词有sign,signature,checkSign,signCheck,getPacka ...

  7. CSS 布局属性(display,float,clear,visibility,overflow,overflow-x,overflow-y)

    display:none | inline | block | list-item | inline-block | table | inline-table | table-caption | ta ...

  8. C# 类型基础

    引言 本文之初的目的是讲述设计模式中的 Prototype(原型)模式,但是如果想较清楚地弄明白这个模式,需要了解对象克隆(Object Clone),Clone其实也就是对象复制.复制又分为了浅度复 ...

  9. iOS-给UIView添加点击事件

    一.当遇到一些UIView 或者 UIView的子类时,比如点击UIImageView要放大图片等. 二.步骤: 1.首先要确保打开控件的用户交互,userInteractionEnabled设置成Y ...

  10. SQL Server里强制参数化的痛苦

    几天前,我写了篇SQL Server里简单参数化的痛苦.今天我想继续这个话题,谈下SQL Server里强制参数化(Forced Parameterization). 强制参数化(Forced Par ...