Json通过使用spring mvc和jackson进行多参数

时间:2014-12-02 14:38:09

标签: json spring spring-mvc jackson

我创建了一个小的json示例...所有工作都很好,我只是无法将复杂的多参数发送到服务方法。只有一个参数它可以工作......目前我不确定我的json调用是错误的还是我的source / config中的某些内容是错误的。

首先是我的lib-Dependencies:

  • org.springframework.spring-webmvc 4.0.6.RELEASE
  • org.springframework.spring-context 4.0.0.RELEASE
  • com.fasterxml.jackson.core.jackson-databind 2.2.3

这是我的spring-config:

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->

     <!-- Configure to plugin JSON as request and response in method handler -->
    <annotation-driven>
        <message-converters>

        <beans:bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            <beans:property name="objectMapper">
                <beans:bean class="com.test.webservice.EnvironmentObjectMapper" />
            </beans:property>
        </beans:bean>

        </message-converters>
    </annotation-driven>

    <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
    <resources mapping="/resources/**" location="/resources/" />

    <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
    <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <beans:property name="prefix" value="/WEB-INF/views/" />
        <beans:property name="suffix" value=".jsp" />
    </beans:bean>

    <!-- only components from this package can be wired by spring --> 
    <context:component-scan base-package="com.test.*" />

</beans:beans>

这是使用过的ObjectMapper:

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

public class EnvironmentObjectMapper extends ObjectMapper{

    /**
     * 
     */
    private static final long serialVersionUID = -4831947927759735004L;

    public EnvironmentObjectMapper() {
        this.setVisibilityChecker(
                getSerializationConfig().
                getDefaultVisibilityChecker().
                withFieldVisibility(JsonAutoDetect.Visibility.ANY).
                withGetterVisibility(JsonAutoDetect.Visibility.NONE).
                withSetterVisibility(JsonAutoDetect.Visibility.NONE).
                withCreatorVisibility(JsonAutoDetect.Visibility.NONE).
                withIsGetterVisibility(JsonAutoDetect.Visibility.NONE));
        this.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
    }

}

这是一个简单测试代码:

@RequestMapping(value = "/rest/test1", method = RequestMethod.POST)
    public void test(@RequestBody String name, @RequestBody String name2){
        System.out.println("Test - name: "+ name + " name2: " + name2);
    }

要调用此方法,我使用Firefox RESTClient。标题设置为Content-Type:application / json

正文设置为:{“name”:“karl”,“name2:”fritz“}

我收到了这个回复:

    Status Code: 400 Bad Request
    Cache-Control: must-revalidate,no-cache,no-store
    Content-Length: 1379
    Content-Type: text/html;charset=ISO-8859-1
    Server: Jetty(7.2.0.v20101020)

并在服务器上:

15:32:30.588 [qtp1879112077-17] DEBUG o.s.web.servlet.DispatcherServlet - DispatcherServlet with name 'appServlet' processing POST request for [/rest/test1]
15:32:30.588 [qtp1879112077-17] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Looking up handler method for path /rest/test1
15:32:30.588 [qtp1879112077-17] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Returning handler method [public void com.test.webservice.JustAServiceController.test(java.lang.String,java.lang.String)]
15:32:30.588 [qtp1879112077-17] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'justAServiceController'
15:32:30.588 [qtp1879112077-17] DEBUG o.s.w.s.m.m.a.RequestResponseBodyMethodProcessor - Reading [class java.lang.String] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@3d467064]
15:32:30.588 [qtp1879112077-17] DEBUG o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver - Resolving exception from handler [public void com.test.webservice.JustAServiceController.test(java.lang.String,java.lang.String)]: org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Can not deserialize instance of java.lang.String out of START_OBJECT token
 at [Source: org.eclipse.jetty.server.HttpInput@309efc1f; line: 1, column: 1]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token
 at [Source: org.eclipse.jetty.server.HttpInput@309efc1f; line: 1, column: 1]
15:32:30.588 [qtp1879112077-17] DEBUG o.s.w.s.m.a.ResponseStatusExceptionResolver - Resolving exception from handler [public void com.test.webservice.JustAServiceController.test(java.lang.String,java.lang.String)]: org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Can not deserialize instance of java.lang.String out of START_OBJECT token
 at [Source: org.eclipse.jetty.server.HttpInput@309efc1f; line: 1, column: 1]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token
 at [Source: org.eclipse.jetty.server.HttpInput@309efc1f; line: 1, column: 1]
15:32:30.588 [qtp1879112077-17] DEBUG o.s.w.s.m.s.DefaultHandlerExceptionResolver - Resolving exception from handler [public void com.test.webservice.JustAServiceController.test(java.lang.String,java.lang.String)]: org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Can not deserialize instance of java.lang.String out of START_OBJECT token
 at [Source: org.eclipse.jetty.server.HttpInput@309efc1f; line: 1, column: 1]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token
 at [Source: org.eclipse.jetty.server.HttpInput@309efc1f; line: 1, column: 1]
15:32:30.588 [qtp1879112077-17] DEBUG o.s.web.servlet.DispatcherServlet - Null ModelAndView returned to DispatcherServlet with name 'appServlet': assuming HandlerAdapter completed request handling
15:32:30.588 [qtp1879112077-17] DEBUG o.s.web.servlet.DispatcherServlet - Successfully completed request

我尝试了很多不同的变体来将参数设置到请求体中。但没有任何效果。有谁知道我做错了什么?非常感谢你提前。

1 个答案:

答案 0 :(得分:0)

您不能拥有多个@RequestBody注释。 @RequestBody带注释的参数应该保存请求的整个主体并绑定到一个对象。

您应该使用不同的方法,例如

  • 介绍一个封装您的字符串的包装器对象,并更改您的签名。例如

包装对象

  
class MyWrapper{
    String name, name2;
    //ToDo: Create constructors

      String getname(){
         return name; 
      }
      String getName2(){
         return name2;
      } 
    //ToDo: create Setters
}
  

您的测试代码

   @RequestMapping(value = "/rest/test1", method = RequestMethod.POST)
    public void test(@RequestBody MyWrapper wrapper){
            System.out.println("Test - name: "+ wrapper.getName() + " name2: " + wrapper.getName2());
     }

其他选项是使用URI路径传递数据,或定义自定义注释(更复杂),请参阅Passing multiple variables in @RequestBody to a Spring MVC controller using Ajax