package org.springboot.sample.config.jsonp;
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.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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;
/**
* 对 ServletPathExtensionContentNegotiationStrategy 进行包装
*
* @author 单红宇(365384722)
* @myblog http://blog.csdn.net/catoop/
* @create 2016年2月29日
*/
public class ContentNegotiationStrategyWrap implements ContentNegotiationStrategy {
protected final Log logger = LogFactory.getLog(getClass());
private final ContentNegotiationStrategy strategy;
private Set<String> jsonpParameterNames = new LinkedHashSet<String>(Arrays.asList("jsonp", "callback"));
/**
* Pattern for validating jsonp callback parameter values.
*/
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)) {
continue;
}
if (!isValidJsonpQueryParam(value)) {
if (logger.isDebugEnabled()) {
logger.debug("Ignoring invalid jsonp parameter value: " + 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 {
// JSONP 响应类型处理 ---- BEGIN
String jsonpParameterValue = getJsonpParameterValue(request);
if (jsonpParameterValue != null) {
List<MediaType> mediaTypes = new ArrayList<>(1);
mediaTypes.add(MediaType.valueOf("application/javascript"));
return mediaTypes;
}
// JSONP 响应类型处理 ---- END
return this.strategy.resolveMediaTypes(request);
}
}