SpringBoot 解决 ajax application/octet-stream not supported
SpringBoot 2.1.3.RELEASE
思路
- 搜索引擎查询之后,没有找到和我类似情况的解决方案,但是发现 Request 的解析应该和 HttpMessageConverters 有关
- 定位到了 SpringBoot 关于 HttpMessageConverters 的自动配置类 HttpMessageConvertersAutoConfiguration

- 由于 SpringBoot 默认是 Jackson 做解析,我们直奔 JacksonHttpMessageConvertersConfiguration

- 我们看一下这个构造方法里面是什么

- 可以看到解析协议中并没有支持
application/octet-stream
解决
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 57 58 |
@Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { converters.add(new CustomHttpMessageConverter()); } private class CustomHttpMessageConverter extends AbstractJackson2HttpMessageConverter { @Nullable private String jsonPrefix; public CustomHttpMessageConverter() { this(Jackson2ObjectMapperBuilder.json().build()); } public CustomHttpMessageConverter(ObjectMapper objectMapper) { super(objectMapper, MediaType.APPLICATION_JSON, new MediaType("application", "*+json"), MediaType.APPLICATION_OCTET_STREAM); } /** * Specify a custom prefix to use for this view's JSON output. * Default is none. * * @see #setPrefixJson */ public void setJsonPrefix(String jsonPrefix) { this.jsonPrefix = jsonPrefix; } /** * Indicate whether the JSON output by this view should be prefixed with ")]}', ". Default is false. * <p>Prefixing the JSON string in this manner is used to help prevent JSON Hijacking. * The prefix renders the string syntactically invalid as a script so that it cannot be hijacked. * This prefix should be stripped before parsing the string as JSON. * * @see #setJsonPrefix */ public void setPrefixJson(boolean prefixJson) { this.jsonPrefix = (prefixJson ? ")]}', " : null); } @Override protected void writePrefix(JsonGenerator generator, Object object) throws IOException { if (this.jsonPrefix != null) { generator.writeRaw(this.jsonPrefix); } } } } |
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new CustomHttpMessageConverter());
}
private class CustomHttpMessageConverter extends AbstractJackson2HttpMessageConverter {
@Nullable
private String jsonPrefix;
public CustomHttpMessageConverter() {
this(Jackson2ObjectMapperBuilder.json().build());
}
public CustomHttpMessageConverter(ObjectMapper objectMapper) {
super(objectMapper,
MediaType.APPLICATION_JSON,
new MediaType("application", "*+json"),
MediaType.APPLICATION_OCTET_STREAM);
}
/**
* Specify a custom prefix to use for this view's JSON output.
* Default is none.
*
* @see #setPrefixJson
*/
public void setJsonPrefix(String jsonPrefix) {
this.jsonPrefix = jsonPrefix;
}
/**
* Indicate whether the JSON output by this view should be prefixed with ")]}', ". Default is false.
* <p>Prefixing the JSON string in this manner is used to help prevent JSON Hijacking.
* The prefix renders the string syntactically invalid as a script so that it cannot be hijacked.
* This prefix should be stripped before parsing the string as JSON.
*
* @see #setJsonPrefix
*/
public void setPrefixJson(boolean prefixJson) {
this.jsonPrefix = (prefixJson ? ")]}', " : null);
}
@Override
protected void writePrefix(JsonGenerator generator, Object object) throws IOException {
if (this.jsonPrefix != null) {
generator.writeRaw(this.jsonPrefix);
}
}
}
}
CustomHttpMessageConverter 代码和 MappingJackson2HttpMessageConverter 一致,只不过在构造方法中添加了 MediaType.APPLICATION_OCTET_STREAM
备注
- 修改之后,只可以使用
@RequestBody XXBean data
,使用@RequestBody String data
会报错 - 由于缺乏这部分源码的相关阅读,完全靠感觉解决的这次问题,这么做很不靠谱,有时间还是应该多学习底层源码。
作者:殷天文
链接:https://www.jianshu.com/p/491ee2df3d02