Java postForEntity无法生成正确的JSON表示……我真是束手无策

Java postForEntity无法生成正确的JSON表示……我真是束手无策,java,json,spring,rest,spring-mvc,Java,Json,Spring,Rest,Spring Mvc,我不熟悉SpringMVC REST。我花了几个小时在谷歌上搜索并尝试不同的方法来解决这个问题。 为什么这段代码不生成带双引号的JSON List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>(); MappingJackson2HttpMessageConverter mapp

我不熟悉SpringMVC REST。我花了几个小时在谷歌上搜索并尝试不同的方法来解决这个问题。 为什么这段代码不生成带双引号的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);

您的客户端代码工作得非常好。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("mm@disney.com");
    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();
}


}
包com.test.rest.controller;
导入com.fasterxml.jackson.annotation.JsonInclude;
进口。。。。。。。。
公共类测试控制器{
@试验
public void testController()引发异常{
服务器mockServer=新服务器(9190);
startMockServer(“query rs main.xml”、“query rs”、mockServer);
EAApplication requestEntity=新的EAApplication();
应用程序=新应用程序();
申请。设置饮食限制(“仅限奶酪”);
应用程序。setFirstName(“Mickey”);
application.setLastName(“鼠标”);
application.setEmail(“mm@disney.com");
application.setJsonSchemaSkillLevel(“专家”);
application.setRestSkillLevel(“新手”);
申请。setSubmissionDate(新日期());
应用。setOdataLibFamiliarity(真);
application.setrest标准熟悉度(true);
列表=新的ArrayList();
列表。添加(应用程序);
requestEntity.setApplications(列表);
RestTemplate=新的RestTemplate();
列表>();
MappingJackson2HttpMessageConverter mappingJacksonHttpMessageConverter=新MappingJackson2HttpMessageConverter();
ObjectMapper ObjectMapper=新的ObjectMapper();
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES,true);
mappingJacksonHttpMessageConverter.setObjectMapper(objectMapper);
mappingJacksonHttpMessageConverter.setPrettyPrint(true);
添加(映射JacksonHttpMessageConverter);
模板.setMessageConverters(转换器);
ResponseEntity response=template.postForEntity(
"http://localhost:9190/query-rs/eaapps“,
requestEntity,EAApplication.class);
mockServer.stop();
}
公共静态void startMockServer(最终字符串mainAppContextConfig,最终字符串contextRoot,服务器服务器)引发异常{
最终DispatcherServlet=新DispatcherServlet();
setContextConfigLocation(“类路径:+mainAppContextConfig”);
最终ServletHolder ServletHolder=新ServletHolder(servlet);
最终ServletContextHandler上下文=新的ServletContextHandler();
setErrorHandler(null);
setContextPath(“/”+contextRoot);
addServlet(servletHolder,“/*”);
setHandler(上下文);
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);
}
package com.yt.nss.rest.query.mock.controller;
导入org.springframework.http.HttpStatus;
进口。。。。
@控制器
@请求映射(“/eaapps”)
公共类应用程序控制器{
@RequestMapping(method=RequestMethod.POST)
公共响应提交消息(final@RequestBody EAApplication){
System.out.println(eaApplication);
返回新的ResponseEntity(null,HttpStatus.OK);
}
}

用于传输JSON的EAApplication类或POJO

@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 +
            '}';
}
}
@XmlRootElement
公共类应用程序{
私人名单申请;
公共列表getApplications(){
退货申请;
}
公共应用程序(列出应用程序){
这是应用程序=应用程序;
}
@凌驾
公共字符串toString(){
返回“EAApplication{”+
“应用程序=”+应用程序+
'}';
}
}
当我运行客户端和服务器时,成功地调用了控制器,并且完全填充了控制器方法上的EAApplication对象


我建议您查看服务器端的控制器和spring mvc配置,或将其发布在此处。

我们可以看到您的
requestEntity
?您是说您的模拟服务器也接收到了JSON,但字段名周围没有引号,即与我的完全相同?模拟服务器能够正确解析它吗?您说过“通过postForEntity序列化后的原始字符串实际上是生成带有双引号的JSON。”-我在您的代码中没有看到这一点。不幸的是,我无法访问服务器端代码。是的。模拟服务器能够将JSON解析回包含客户端发送的所有值的对象中。您可以通过查看输出来确认它,字节数组在您的配置中打开“漂亮打印”后看起来是这样的。[123,13,10,32,32,34,97,112,112,108,…]这里第5个元素是34(双引号),后面是“应用程序”。您可以在com.fasterxml.jackson.databind.ser.BeanSerializer.serialize方法中放置断点,并检查变量jgen.\u outputBuffer。您还可以通过使用tcpdump查看发送到服务器的TCP数据包来确认这一点。您是对的,400个错误的请求并不是因为我所怀疑的缺少引号。服务器正在正确分析它,但抱怨枚举值不正确。感谢您的及时帮助,并为我指明了正确的方向。当做
@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 +
            '}';
}
}