自定义JsonMessageConverter使后台实现Jsonp功能

Jsonp需要返回什么格式的数据

当前端需要跨域调用后台数据的时候,除了在后台配置Access-Control-Allow-Origin,还可以用jsonp实现
使用jsonp方式调用后台时,后台会接受一个callback参数,然后返回的时候,只需将返回的结果和callback组装成一个函数调用就可以了
例如:
callback(resultJson)

自定义JsonMessageConverter

这里我使用的是fastjson,此时用到了RequestContext,封装request和response的对象,参考:封装request,response使之可以全局访问
代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
public class JsonMessageConverter extends FastJsonHttpMessageConverter {

private static final Logger logger = LoggerFactory.getLogger(JsonMessageConverter.class);
private static String CALLBACK_REGEXP = "[^0-9a-zA-Z_\\.]";
private static int CALLBACK_MAX_LENGTH = 128;
private static Pattern PATTERN = Pattern.compile(CALLBACK_REGEXP);
private static String CHAR_SET = "UTF-8";


@Override
protected void writeInternal(Object obj, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {

OutputStream out = outputMessage.getBody();
String text;

String callback = RequestContext.getStr("callback");
RequestContext.getResponse().setCharacterEncoding(CHAR_SET);
RequestContext.getResponse().setHeader("Cache-Control", "no-cache");

if (StringUtils.isNotBlank(callback)) {
callback = StringEscapeUtils.escapeHtml4(callbackFilter(callback));
RequestContext.getResponse().setHeader("Content-Type", "application/javascript");
text = callback + "(" + getJson(obj) + ");";
} else {
RequestContext.getResponse().setHeader("Content-Type", "application/json");
text = getJson(obj);
}

byte[] bytes = text.getBytes(getCharset());
out.write(bytes);
}
private String getJson(Object obj) {
return JSON.toJSONString(obj, getFeatures());
}
public static String callbackFilter(String callback) {
if (StringUtils.isEmpty(callback)) {
return StringUtils.EMPTY;
}

String filterCallback = callback;

if (StringUtils.length(filterCallback) > CALLBACK_MAX_LENGTH) {
filterCallback = filterCallback.substring(0, CALLBACK_MAX_LENGTH);
}

Matcher m = PATTERN.matcher(filterCallback);

filterCallback = m.replaceAll("");

if (!StringUtils.equals(callback, filterCallback)) {
logger.error("callback was filter, callback:" + callback + ",filterCallcack:" + filterCallback);
}

return filterCallback;
}
}

此时就已经支持jsonp了,而且对代码没有任何入侵。

坚持原创技术分享,您的支持将鼓励我继续创作!
显示 Gitment 评论