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

来源:互联网 发布:mac访客模式 编辑:程序博客网 时间:2024/05/24 05:19

前端代码

$.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 implementsContentNegotiationStrategy {    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;@Configurationpublic class ResponseBodyProcessor extends WebMvcConfigurerAdapter implementsInitializingBean {@Autowired    private RequestMappingHandlerAdapter adapter;@Autowired    private ContentNegotiationManager manager;@Overridepublic 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(MethodParameter 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黑名单】
原创粉丝点击