前端代码
$.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(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黑名单】