美文网首页Spring 开发Springboot
SpringBoot 解决 application/octet-

SpringBoot 解决 application/octet-

作者: 殷天文 | 来源:发表于2019-05-13 16:31 被阅读22次

    前端为了兼容IE8和跨域做了很多操作(我也不懂),之后发现了一个问题,IE8下所有的ajax请求都是 application/octet-stream,这造成后端Controller中参数为@RequestBody XXBean data的方法全部报错 application/octet-stream not supported

    版本

    SpringBoot 2.1.3.RELEASE

    思路

    • 搜索引擎查询之后,没有找到和我类似情况的解决方案,但是发现 Request 的解析应该和 HttpMessageConverters 有关

    • 定位到了 SpringBoot 关于 HttpMessageConverters 的自动配置类 HttpMessageConvertersAutoConfiguration

    image.png
    • 由于 SpringBoot 默认是 Jackson 做解析,我们直奔 JacksonHttpMessageConvertersConfiguration
    image.png
    • 我们看一下这个构造方法里面是什么
    image.png
    • 可以看到解析协议中并没有支持 application/octet-stream

    解决

    @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);
                }
            }
    
        }
    
    }
    
    

    CustomHttpMessageConverter 代码和 MappingJackson2HttpMessageConverter 一致,只不过在构造方法中添加了 MediaType.APPLICATION_OCTET_STREAM

    备注

    • 修改之后,只可以使用 @RequestBody XXBean data,使用 @RequestBody String data 会报错
    • 由于缺乏这部分源码的相关阅读,完全靠感觉解决的这次问题,这么做很不靠谱,有时间还是应该多学习底层源码。

    相关文章

      网友评论

        本文标题:SpringBoot 解决 application/octet-

        本文链接:https://www.haomeiwen.com/subject/tjxlaqtx.html