springmvc接收参数异常application/json not supported

jackson异常not supported 和 NoSuchMethodError

知兮丶青 异常 · spring
阅读(9434) 2017-11-25
springmvc接收参数异常application/json not supported
springmvc接收参数异常application/json not supported

纲要

1、解决:HTTP媒体类型不支持异常,HttpMediaTypeNotSupportedException: Content type 'application/json;charset=UTF-8' not supported

2、解决:找不到方法异常,NoSuchMethodError: org.codehaus.jackson.map.type.TypeFactory.type(Ljava/lang/reflect/Type;)Lorg/codehaus/jackson/type/JavaType;

3、疑问:jackson-asl 和 jackson-lgpl 有什么不同


背景

今天需要开发公司旧系统,需要写个接口。我采用注解@RequestBody接收传过来的json参数。无奈报错:Content type 'application/json;charset=UTF-8' not supported

@RequestMapping(value = "/api")
@ResponseBody
public User adminindex(ModelMap model, @RequestBody User user, HttpServletRequest request, HttpServletResponse response) {
   return user;
}

项目框架:springmvc 3.0.5

项目已导入:jackson-core-lgpl-1.2.1.jar、jackson-mapper-lgpl-1.2.1.jar



解决异常: 

spring http媒体类型不支持异常。

在被RequestBody注解传入参数自动绑定到对象时,类型是"application/json;charset=UTF-8",

如果spring不被支持或未配置相应的实现的话,就会抛出该异常。

org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json;charset=UTF-8' not supported


方法一:加入配置

<mvc:annotation-driven />


方法二:加入配置

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" >
    <property name="messageConverters">
        <list>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>text/html;charset=UTF-8</value>
                    </list>
                </property>
            </bean>
            <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" >
                <property name="supportedMediaTypes">
                    <list>
                        <value>application/json;charset=UTF-8</value>
                    </list>
                </property>
            </bean>
        </list>
    </property>
</bean>


以上解决了:'application/json;charset=UTF-8' not supported 异常。


注意:

低版本,如果@RequestBody接受的对象里存在泛型的属性。还是会这个报'application/json;charset=UTF-8' not supported错。调试得到以下具体错误:

Unresolved TypeVariable <T> (from class cn.org.rapid_framework.page.PageRequest)

如果业务需要泛型,请选择1.5.1以上版本(含1.5.1版本)。


如:Atest<String> 类里面含 T name 属性。

public JsonResult api(ModelMap model, @RequestBody Atest<String> query, HttpServletRequest request, HttpServletResponse response) {
}
public class Atest<T> {
    private int id;
    private T name;
}




事情的发展总不随人愿。接着报错:

找不到方法

顾名思义,不难得出spring需要使用方法TypeFactory.type(class),而jackson mapper又没有该方法的实现导致的错。那事情就变得简单了,再往下看:

Handler processing failed; nested exception is java.lang.NoSuchMethodError: org.codehaus.jackson.map.type.TypeFactory.type(Ljava/lang/reflect/Type;)Lorg/codehaus/jackson/type/JavaType;


查看jar包 org.springframework.web-3.0.5.RELEASE.jar 的类:

org.springframework.http.converter.json.MappingJacksonHttpMessageConverter

看到:Spring调用TypeFactory的type(Type t)方法。如图所示:

Spring调用TypeFactory.jpg


接着查看jar包 jackson-mapper-lgpl-1.2.1.jar 的类:

org.codehaus.jackson.map.type.TypeFactory,如图所示:

 jackson.map.type.TypeFactory.jpg

惊呆,压根就没有 type(Type t)方法好吗。

到这,只能把项目的jackson包往上的版本换了。

发现,jackson-mapper-asl-1.3.0.jar 已经加入了type(Type t)方法

那么,主要jackson 版本>= 1.3.0 都可兼容spring 3.0.5 MappingJacksonHttpMessageConverter 了。如下图所示:

 1.3.0的TypeFactory.jpg


我这里选择了:

jackson-mapper-asl-1.5.1.jar

jackson-core-asl-1.5.1.jar

因为项目需要泛型属性,替换项目原来的2个包。运行->测试->成功!yes!




最后

有人问:jackson- asl 和 jackson-lgpl 有什么不同?于我看是开源协议不一样。


为你百度到以下资料:

ASL(Apache License, Version 2.0、Apache License, Version 1.1、Apache License, Version 1.0) 

Apache Licence 是著名的非盈利开源组织 Apache 采用的协议.该协议和 BSD 类似,同样鼓励代码共享和尊重原作者的著作权,同样允许代码修改,再发布(作为开源或商业软件)。


LGPL(GNU Lesser General Public License) 

LGPL 是 GPL 的一个为主要为类库使用设计的开源协议。和GPL要求任何使用/修改/衍生之GPL类库的的软件必须采用GPL协议不同。LGPL 允许商业软件通过类库引用(link)方式使用LGPL类库而不需要开源商业软件的代码。这使得采用LGPL协议的开源代码可以被商业软件作为类库引用并 发布和销售。


原创文章,转载请注明出处:https://www.weizhixi.com/article/5.html