2014-09-06 831 views
0

我是Spring MVC REST的新手。我花了数小时搜索并尝试不同的方法来解决这个问题。 这段代码为什么不用双引号产生JSON?postForEntity不会产生正确的JSON表示...在我的智慧结尾

  List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();    
     MappingJackson2HttpMessageConverter mappingJacksonHttpMessageConverter = new MappingJackson2HttpMessageConverter(); 
     ObjectMapper objectMapper = new ObjectMapper(); 
     objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); 
     objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); 
     mappingJacksonHttpMessageConverter.setObjectMapper(objectMapper); 
     mappingJacksonHttpMessageConverter.setPrettyPrint(true);      
     converters.add(mappingJacksonHttpMessageConverter);    
     template.setMessageConverters(converters); 

     ResponseEntity<EAApplication> response = template.postForEntity(
      LOCAL_URI, 
      requestEntity, EAApplication.class); 

产生下面的JSON没有双引号,所以服务器发送400错误的请求。

{ applications: 
[ { submissionDate: '2014-09-05T08:28:17', 
    firstName: 'Mickey', 
    lastName: 'Mouse', 
    email: '[email protected]', 
    dietaryRestrictions: 'Cheese only', 
    restSkillLevel: 'Novice', 
    jsonSchemaSkillLevel: 'Expert', 
    restStandardFamiliarity: true, 
    slimFamiliarity: true, 
    odataLibFamiliarity: true } ] } 
+0

我们可以看到你的'requestEntity'吗? – 2014-09-06 17:24:30

回答

0

你的客户端代码工作得很好。 400错误请求可能是由于您的控制器端可能无法处理内容的错误。

上面粘贴的JSON没有双引号,因为有些编辑器或程序为了提高可读性而渲染JSON。通过postForEntity序列化后的原始字符串实际上是使用双引号生成JSON。

下面提到的代码正在工作,我通过编写测试来测试它。

package com.test.rest.controller; 

import com.fasterxml.jackson.annotation.JsonInclude; 
import ........  

public class TestAppController { 

@Test 
public void testController() throws Exception { 

    Server mockServer = new Server(9190); 
    startMockServer("query-rs-main.xml", "query-rs", mockServer); 

    EAApplication requestEntity = new EAApplication(); 
    Application application = new Application(); 
    application.setDietaryRestrictions("Cheese only"); 
    application.setFirstName("Mickey"); 
    application.setLastName("Mouse"); 
    application.setEmail("[email protected]"); 
    application.setJsonSchemaSkillLevel("Expert"); 
    application.setRestSkillLevel("Novice"); 
    application.setSubmissionDate(new Date()); 
    application.setOdataLibFamiliarity(true); 
    application.setRestStandardFamiliarity(true); 

    List<Application> list = new ArrayList<>(); 
    list.add(application); 

    requestEntity.setApplications(list); 

    RestTemplate template = new RestTemplate(); 

    List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>(); 
    MappingJackson2HttpMessageConverter mappingJacksonHttpMessageConverter = new MappingJackson2HttpMessageConverter(); 
    ObjectMapper objectMapper = new ObjectMapper(); 
    objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); 
    objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); 
    mappingJacksonHttpMessageConverter.setObjectMapper(objectMapper); 
    mappingJacksonHttpMessageConverter.setPrettyPrint(true); 
    converters.add(mappingJacksonHttpMessageConverter); 
    template.setMessageConverters(converters); 

    ResponseEntity<EAApplication> response = template.postForEntity(
      "http://localhost:9190/query-rs/eaapps", 
      requestEntity, EAApplication.class); 

    mockServer.stop(); 

} 

public static void startMockServer(final String mainAppContextConfig, final String contextRoot, Server server) throws Exception { 
    final DispatcherServlet servlet = new DispatcherServlet(); 
    servlet.setContextConfigLocation("classpath:" + mainAppContextConfig); 
    final ServletHolder servletHolder = new ServletHolder(servlet); 

    final ServletContextHandler context = new ServletContextHandler(); 
    context.setErrorHandler(null); 
    context.setContextPath("/" + contextRoot); 
    context.addServlet(servletHolder, "/*"); 

    server.setHandler(context); 
    server.start(); 
} 


} 

控制器在服务器端 -

package com.yt.nss.rest.query.mock.controller; 


import org.springframework.http.HttpStatus; 
import .... 

@Controller 
@RequestMapping("/eaapps") 
public class EAApplicationsController { 


@RequestMapping(method = RequestMethod.POST) 
public ResponseEntity<Object> submitMessage(final @RequestBody EAApplication eaApplication) { 

    System.out.println(eaApplication); 
    return new ResponseEntity<Object>(null, HttpStatus.OK); 
} 

}用于传递JSON

@XmlRootElement 
public class EAApplication { 
private List<Application> applications; 

public List<Application> getApplications() { 
    return applications; 
} 

public void setApplications(List<Application> applications) { 
    this.applications = applications; 
} 

@Override 
public String toString() { 
    return "EAApplication{" + 
      "applications=" + applications + 
      '}'; 
} 
} 

当我运行在客户端和服务器

EAApplication类或POJO中,调用已成功完成控制器,并且控制器方法上的EAApplication对象完全为p opulated。

我建议你看看你的控制器和弹簧mvc配置在服务器端或张贴在这里。

+0

你是说你的模拟服务器也收到JSON而没有引用字段名称,就像我的一样吗?模拟服务器能够正确解析它吗?你说:“通过postForEntity序列化后的原始字符串实际上是用双引号生成JSON。” - 我在代码中没有看到。不幸的是,我没有访问服务器端代码。 – solvetech 2014-09-07 15:08:55

+0

是的。 Mock服务器能够使用客户端发送的所有值将JSON解析回对象中。 – 2014-09-07 16:59:19

+0

您可以通过查看输出来确认它,在配置中打开“漂亮打印”后,字节数组看起来像这样。 [123,13,10,32,32,34,97,112,112,108,...]这里的第五个元素是34(双引号),后面是'应用程序'。您可以在com.fasterxml.jackson.databind.ser.BeanSerializer.serialize方法中放置断点并检查变量jgen._outputBuffer。您也可以使用tcpdump来查看传出到服务器的TCP数据包。 – 2014-09-07 17:08:01

相关问题