当前位置 主页 > 网站技术 > 代码类 >

    解决fastjson从1.1.41升级到1.2.28后报错问题详解

    栏目:代码类 时间:2020-02-07 18:05

    最近因为fastjson安全漏洞,升级jar包时,踩了一些坑。

    新版本FastJsonHttpMessageConverter初始化,默认设置MediaType为*/*

    背景:

    使用Spring RestTemplate,配置如下:

      <bean  class="org.springframework.web.client.RestTemplate">
        <constructor-arg ref="ky.clientHttpRequestFactory"/>
        <property name="errorHandler">
          <bean class="org.springframework.web.client.DefaultResponseErrorHandler"/>
        </property>
        <property name="messageConverters">
          <list>
            <bean class="org.springframework.http.converter.FormHttpMessageConverter"/>
            <bean class="cn.com.autodx.common.jsonView.ViewAwareJsonMessageConverter">
            </bean>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
              <property name="supportedMediaTypes">
                <list>
                  <value>text/html;charset=UTF-8</value>
                  <value>application/json</value>
                  <value>text/javascript;charset=utf-8</value>
                </list>
              </property>
            </bean>
          </list>
        </property>
      </bean>

    其中ViewAwareJsonMessageConverter继承自FastJsonHttpMessageConverter。

    fastjson从1.1.41升级到1.2.28之后,请求报错:

    json java.lang.IllegalArgumentException: 'Content-Type' cannot contain wildcard type '*'

    原因是在1.1.41中,FastJsonHttpMessageConverter初始化时,设置了MediaType。

      public FastJsonHttpMessageConverter(){
        super(new MediaType("application", "json", UTF8), new MediaType("application", "*+json", UTF8));
      }

    而在1.2.28中,设置的MediaType为‘/',即:

      public FastJsonHttpMessageConverter() {
        super(MediaType.ALL); // */*
      }

    后续在org.springframework.http.converter.AbstractHttpMessageConverter.write过程中,又要判断Content-Type不能含有通配符,这应该是一种保护机制,并强制用户自己配置MediaType。代码如下:

      @Override
      public final void write(final T t, MediaType contentType, HttpOutputMessage outputMessage)
          throws IOException, HttpMessageNotWritableException {
        final HttpHeaders headers = outputMessage.getHeaders();
        if (headers.getContentType() == null) {
          MediaType contentTypeToUse = contentType;
          if (contentType == null || contentType.isWildcardType() || contentType.isWildcardSubtype()) {
            contentTypeToUse = getDefaultContentType(t);
          }
          if (contentTypeToUse != null) {
          //设置Content-Type,不允许含有通配符
            headers.setContentType(contentTypeToUse);
          }
        }
        ......
        if (outputMessage instanceof StreamingHttpOutputMessage) {
          ......
        }else {
        //自定义MessageConverter的write操作
          writeInternal(t, outputMessage);
          outputMessage.getBody().flush();
        }
      }
      public void setContentType(MediaType mediaType) {
        Assert.isTrue(!mediaType.isWildcardType(), "'Content-Type' cannot contain wildcard type '*'");
        Assert.isTrue(!mediaType.isWildcardSubtype(), "'Content-Type' cannot contain wildcard subtype '*'");
        set(CONTENT_TYPE, mediaType.toString());
      }