您的位置:首页 > 编程语言 > Java开发

springboot跨域请求,实现跨域jsonp请求服务端数据自动封装

2017-11-04 11:53 761 查看
前端代码

$.ajax({
type:'get',
dataType:'jsonp',
url:'http://www.itblacklist.cn/test/jsonp',
data:{'id':123},
success:function(data){
console.log('success...');
}
});

$.ajax({
type:'get',
url:'http://www.itblacklist.cn/test/test2',
data:{'id':123},
success:function(data){
console.log('success...');
}
});

服务端增加以下类

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.util.StringUtils;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.accept.ContentNegotiationStrategy;
import org.springframework.web.context.request.NativeWebRequest;

public class ContentNegotiationStrategyWrap implements
ContentNegotiationStrategy {
    private static Logger log = LoggerFactory.getLogger(ContentNegotiationStrategyWrap.class);
    private final ContentNegotiationStrategy strategy;
private Set<String> jsonpParameterNames = new LinkedHashSet<String>(Arrays.asList("jsonp", "callback"));
private static final Pattern CALLBACK_PARAM_PATTERN = Pattern.compile("[0-9A-Za-z_\\.]*");

private String getJsonpParameterValue(NativeWebRequest request) {
if (this.jsonpParameterNames != null) {
for (String name : this.jsonpParameterNames) {
String value = request.getParameter(name);
if (StringUtils.isEmpty(value) || !isValidJsonpQueryParam(value))
continue;
return value;
}
}
return null;
}

protected boolean isValidJsonpQueryParam(String value) {
return CALLBACK_PARAM_PATTERN.matcher(value).matches();
}

public ContentNegotiationStrategyWrap(ContentNegotiationStrategy strategy) {
super();
this.strategy = strategy;
}

@Override
public List<MediaType> resolveMediaTypes(NativeWebRequest request) throws HttpMediaTypeNotAcceptableException {
String jsonpParameterValue = getJsonpParameterValue(request);
if (jsonpParameterValue != null) {
List<MediaType> mediaTypes = new ArrayList<>(1);
mediaTypes.add(MediaType.valueOf("application/javascript"));
return mediaTypes;
}
return this.strategy.resolveMediaTypes(request);
}
}

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.accept.ContentNegotiationManager;
import org.springframework.web.accept.ContentNegotiationStrategy;
import org.springframework.web.accept.ServletPathExtensionContentNegotiationStrategy;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor;

@Configuration
public class ResponseBodyProcessor extends WebMvcConfigurerAdapter implements
InitializingBean {
@Autowired
private RequestMappingHandlerAdapter adapter;
@Autowired
private ContentNegotiationManager manager;

@Override
public void afterPropertiesSet() throws Exception {
List<HandlerMethodReturnValueHandler> returnValueHandlers = adapter.getReturnValueHandlers();
List<HandlerMethodReturnValueHandler> handlers = new ArrayList<>(returnValueHandlers);
decorateHandlers(handlers);
adapter.setReturnValueHandlers(handlers);
processContentNegotiationManager();
}

private void processContentNegotiationManager() {
List<ContentNegotiationStrategy> strategies = manager.getStrategies();
for (int i = 0; i < manager.getStrategies().size(); i++) {
if (manager.getStrategies().get(i) instanceof ServletPathExtensionContentNegotiationStrategy) {
strategies.set(i, new ContentNegotiationStrategyWrap(manager.getStrategies().get(i)));
manager = new ContentNegotiationManager(strategies);
break;
}
}
}

private void decorateHandlers(List<HandlerMethodReturnValueHandler> handlers) {
for (HandlerMethodReturnValueHandler handler : handlers) {
if (handler instanceof RequestResponseBodyMethodProcessor) {
ResponseBodyWrapHandler decorator = new ResponseBodyWrapHandler(handler);
int index = handlers.indexOf(handler);
handlers.set(index, decorator);
break;
}
}
}

@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
for (HttpMessageConverter<?> httpMessageConverter : converters) {
if (httpMessageConverter instanceof MappingJackson2HttpMessageConverter) {
MappingJackson2HttpMessageConverter convert = (MappingJackson2HttpMessageConverter) httpMessageConverter;
List<MediaType> medisTypeList = new ArrayList<>(convert.getSupportedMediaTypes());
medisTypeList.add(MediaType.valueOf("application/javascript;charset=UTF-8"));
convert.setSupportedMediaTypes(medisTypeList);
break;
}
}
super.extendMessageConverters(converters);
}
}

import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.regex.Pattern;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.MethodParameter;
import org.springframework.http.converter.json.MappingJacksonValue;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer;

public class ResponseBodyWrapHandler implements HandlerMethodReturnValueHandler {

private static Logger log = LoggerFactory.getLogger(ResponseBodyWrapHandler.class);
private final HandlerMethodReturnValueHandler delegate;
private Set<String> jsonpParameterNames = new LinkedHashSet<String>(Arrays.asList("jsonp", "callback"));
private static final Pattern CALLBACK_PARAM_PATTERN = Pattern.compile("[0-9A-Za-z_\\.]*");

private String getJsonpParameterValue(NativeWebRequest request) {
if (this.jsonpParameterNames != null) {
for (String name : this.jsonpParameterNames) {
String value = request.getParameter(name);
if (StringUtils.isEmpty(value) || !isValidJsonpQueryParam(value))
continue;
return value;
}
}
return null;
}

protected boolean isValidJsonpQueryParam(String value) {
return CALLBACK_PARAM_PATTERN.matcher(value).matches();
}

public ResponseBodyWrapHandler(HandlerMethodReturnValueHandler delegate){
this.delegate=delegate;
}

@Override
public boolean supportsReturnType(Method
4000
Parameter returnType) {
return delegate.supportsReturnType(returnType);
}

@Override
public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
String jsonpParameterValue = getJsonpParameterValue(webRequest);
if (jsonpParameterValue != null) {
if (!(returnValue instanceof MappingJacksonValue)) {
MappingJacksonValue container = new MappingJacksonValue(returnValue);
container.setJsonpFunction(jsonpParameterValue);
returnValue = container;
}
}
delegate.handleReturnValue(returnValue,returnType,mavContainer,webRequest);
}
}

Conroller代码

/**
* 描述: testController
*
* @author <a href="mailto:admin@itblacklist.com">admin</a>
* @createDate 2016-11-28 13:37:55
*/
@RestController
@RequestMapping("/test")
public class TestController {
@RequestMapping("/jsonp")
public String jsonp(Long id) {
return "success"+id;
}

@RequestMapping("/test2")
public String test2(Long id) {
return "success"+id;
}
}

这样dataType:'jsonp'的请求服务端会自动封装成支持jsonp的响应,跨域的jsonp请求和普通的请求对Controller层没有任何影响。

转载请注明来源【IT黑名单
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息