Java postForEntity无法生成正确的JSON表示……我真是束手无策
我不熟悉SpringMVC REST。我花了几个小时在谷歌上搜索并尝试不同的方法来解决这个问题。 为什么这段代码不生成带双引号的JSONJava 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
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 +
'}';
}
}