Spring MVC:不反序列化JSON请求体

Rya*_*son 31 java json spring-mvc

我正在开发一个Spring MVC项目,我需要完成的任务之一要求我在POST请求中通过用户发送一串JSON数据.我知道Spring会使用Jackson将JSON反序列化为对象,但如果我尝试类似以下内容:

@RequestMapping(value = "/test", method = RequestMethod.POST)
public void doSomething(@RequestBody String json) {
    // do something
}
Run Code Online (Sandbox Code Playgroud)

我只是回到HTTP 400 Bad Request("客户端发送的请求在语法上是不正确的.").

如何将客户端发送的原始JSON作为字符串?

dig*_*oel 51

当Spring MVC找到与URL路径匹配的请求映射但参数(或标题或某些内容)与处理程序方法所期望的不匹配时,您通常会看到此类错误.

如果您使用@RequestBody注释,那么我相信Spring MVC期望将POST请求的整个主体映射到Object.我猜你的身体不仅仅是一个字符串,而是一些完整的JSON对象.

如果你有一个你期望的JSON对象的java模型,那么你可以用你的doSomething声明中的String参数替换它,例如

public void doSomething(@RequestBody MyObject myobj) {

如果您没有与JSON匹配的Java对象,那么您可以尝试通过将String类型替换为a 来使其工作,Map<String, Object>并查看是否使您更接近工作解决方案.

您还可以打开Spring MVC中的调试日志记录,以获取有关它为什么是错误请求的更多信息.

编辑: 根据您在评论中的要求,您可以简单地将HttpServletRequest注入您的方法并自己阅读正文.

public void doSomething(HttpServletRequest request) {
  String jsonBody = IOUtils.toString( request.getInputStream());
  // do stuff
}
Run Code Online (Sandbox Code Playgroud)


小智 6

我们有一种情况,我们想要一些控制器方法将POST主体映射到bean,以及我们只想要原始String的其他方法.要使用@RequestBody 注释完成此操作,您需要配置多个消息转换器,例如......

<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
  <property name="useDefaultSuffixPattern" value="false"/>
</bean>

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name="messageConverters">
        <list>
            <ref bean="jsonConverter" />
            <ref bean="marshallingConverter" />
            <ref bean="stringHttpMessageConverter" />
        </list>
    </property>
</bean>

<bean id="jsonConverter"
      class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
    <property name="supportedMediaTypes" value="application/json" />
</bean>

<bean id="marshallingConverter"
      class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
    <constructor-arg ref="jaxb2Marshaller" />
    <property name="supportedMediaTypes" value="application/xml"/>
</bean>

<bean id="stringHttpMessageConverter"
      class="org.springframework.http.converter.StringHttpMessageConverter">
    <property name="supportedMediaTypes" value="text/plain"/>
</bean>
Run Code Online (Sandbox Code Playgroud)

然后,对各种方法的请求必须指定具有适当值的" content-type "标头.对于请求主体映射到JAXB bean的那些方法,请指定" application/xml".对于请求体是String的那些,使用" text/plain".