[alibaba/fastjson]1.2.36(包含)版本以后FastJsonHttpMessageConverter类write方法代码逻辑导致java.lang.IllegalArgumentException

2025-11-11 375 views
0

1.2.35(包含)版本以前,FastJsonHttpMessageConverter类write方法的代码有自己的实现逻辑,最终会调用writeInternal方法,而1.2.36(包含)版本以后的代码默认调用super.write(o,contentType,outputMessage)方法,导致在AbstractHttpMessageConverter类中进行MediaType的检查时由于默认使用的MediaType.ALL中包含*号而抛出异常。 异常信息:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalArgumentException: 'Content-Type' cannot contain wildcard type '*'
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:982)
    org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:61)
    org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
    org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
    org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
    org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
    org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
    org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
    org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
    org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
    org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383)
    org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
    org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
    org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
    org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
    org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)

回答

4

@htyoung

这是Spring HttpHeaders一种保护机制

/**
 * Set the {@linkplain MediaType media type} of the body,
 * as specified by the {@code Content-Type} header.
 */
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());
}

配置一下MediaType就好了

<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
  <property name="supportedMediaTypes">
    <list>
      <value>application/json;charset=UTF-8</value>
    </list>
  </property>
</bean>
2

我知道这是保护机制,但是在正常发送表单请求的时候,如果没有设置Header中的Accept(一般也不会设置),而fastjon是默认支持所有MediaType的,这一点从逻辑上来说其实是和Spring不兼容的

4

@htyoung 不是和Spring不兼容 是spring强制需要用户设置MediaType 这点要清楚

8

既然spring强制要求了,fastjson是不是可以给用户提供一个默认的非MediaType.ALL的选择呢?

2

@htyoung 你觉得默认哪个MediaType会比MediaType.ALL好呢

0

有个疑问,早期版本的fastjson MediaType默认设置的MediaType.APPLICATION_JSON和MediaType.APPLICATION_FORM_URLENCODED,一般来说fastjson也不能进行其它MediaType类型的消息转换,为什么要把默认设置改成MediaType.ALL呢

4

@htyoung 理论上MediaType与JSON格式是无关的 任何MediaType都可以通过Fastjson转换

5

这个问题我今天也遇到了,fastjson-1.2.79,调试了半天发现是这个supportedMediaTypes属性为MediaType.ALL造成,通过你们的一问一答,让我对fastjson有了更深的理解

4

这个问题我今天也遇到了,fastjson-1.2.79,调试了半天发现是这个supportedMediaTypes属性为MediaType.ALL造成,通过你们的一问一答,让我对fastjson有了更深的理解

改吧,不到万不得已别用fastjson了,随随便便改特性,不考虑兼容性,fastjson的坑还不多吗?