在向服务器发送 JSON 请求时,我经常会收到以下消息:
客户端发送的请求在语法上是错误的 ()。
通常这是控制器没有预料到的错误属性,因为 JSON 映射到的对象不包含它。
查找参数是不必要的耗时 - 有没有办法获取更多信息,甚至可能是异常的堆栈跟踪?我尝试在调试模式下运行,并且使用 Jackson 作为我的 JSON(反)序列化器。
在向服务器发送 JSON 请求时,我经常会收到以下消息:
客户端发送的请求在语法上是错误的 ()。
通常这是控制器没有预料到的错误属性,因为 JSON 映射到的对象不包含它。
查找参数是不必要的耗时 - 有没有办法获取更多信息,甚至可能是异常的堆栈跟踪?我尝试在调试模式下运行,并且使用 Jackson 作为我的 JSON(反)序列化器。
要获取更多信息/堆栈跟踪,请在 log4j.properties 中打开 Spring Web 的调试日志记录
log4j.logger.org.springframework.web=debug
如果您使用的数据来自外部 api,并且如果您想保护控制器免受不需要的不必要元素/属性的影响,则可以在 POJO 类上使用以下注释
@JsonIgnoreProperties(ignoreUnknown = true)
或者你可以全局设置它
//jackson 2.0
jsonObjectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
老案例,我现在已经无关紧要了,但对于其他有类似问题的人,我会添加这个条目。
检查您是否有双引号,而不是单引号。也尝试逃避它们。
我将应用程序curl用于我的测试 json 请求。
我的 JSON 是这样的
{ 'name' : 'somedata', 'town':'some town' }
它就在我眼里爆炸了。
“客户端发送的请求在语法上不正确”是一般错误。所以我把它从单引号改为双引号,不行。然后我尝试在单引号前加一个反斜杠,仍然不行。然后将其更改为双引号前面的反斜杠和presto!
curl -i -H "Accept: application/json" -H "Content-Type: application/json" \
http://localhost:8077/dra/dump.json \
-X PUT -d "{\"name\" : \"My Name\", \"town\":\"My Town\"}"
几天后我遇到了同样的错误,终于启用了@Farm提到的调试日志记录,并且能够看到这个问题的原因。我在 json 中从 jsp 到 spring 控制器发布了一个 Person 对象,如下所示:-
@RequestMapping(value = "/get", method = RequestMethod.POST)
public @ResponseBody
Person getPerson(@RequestBody Person person) {
// System.out.println("inside get::::::::");
System.out.println("city:=" + person.getResidenceAddress().getCity()+" "
+ "name:= " + person.getFullName().getFirstName());
// Person prsn = personService.getPerson(person);
/*
* Person prsn = new Person(); prsn.setId(1); ResponseDecorator rd = new
* ResponseDecorator(prsn, true);
*/return person;
}
// Person Object
class Person{
private Name fullName;
private Address residenceAddress;
private Address mailingAddress;
private Gender gender;
private MaritalStatus maritalStatus;
private Integer creditRating;
}
//Address Object
public class Address {
private String streetNo;
private String streetName;
private String suburb;
private String city;
private String state;
private String country;
private Integer pinCode;
private AddressType addressType;
}
json post from jsp:-
//create JSON
var json = {
"id": id,
"fullName":{"firstName":firstName,"middleName":middleName,"surName": surName},
"residenceAddress":{ "streetNo": streetNo,
"streetName": streetName,
"suburb": suburb,
"city": city,
"state": state,
"country": country,
"pinCode": pincode
}
};
var dataString = JSON.stringify(json);
//alert(dataString);
$.ajax({
headers: {
Accept : "text/plain; charset=utf-8, application/json"},
url: "/myservice/get",
type: 'POST',
dataType: 'json',
//data : "{ }",
data: dataString,
contentType: 'application/json',
mimeType: 'application/json',
success: function(data) {
alert(data);
},
error:function(data,status,er) {
alert("error: "+data+" status: "+status+" er:"+er);
}
});
提交时的错误是 400 Bad request,并且没有其他线索说明它失败的原因。在服务器上启用调试模式时,我可以看到以下错误堆栈跟踪:-
**00:53:42,294 DEBUG RequestResponseBodyMethodProcessor:117 - Reading [com.foo.assignment.model.Person] as "application/json" using [org.springframework.http.converter.json.MappingJacksonHttpMessageConverter@1813fb]
00:53:42,310 DEBUG ServletInvocableHandlerMethod:159 - Error resolving argument [0] [type=com.foo.assignment.model.Person]
HandlerMethod details:
Controller [com.foo.assignment.controller.PersonController]
Method [public com.foo.assignment.model.Person com.foo.assignment.controller.PersonController.getPerson(com.foo.assignment.model.Person)]
org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: No suitable constructor found for type [simple type, class com.foo.assignment.model.Address]: can not instantiate from JSON object (need to add/enable type information?)
at [Source: org.apache.catalina.connector.CoyoteInputStream@f264df; line: 1, column: 98] (through reference chain: com.foo.assignment.model.Person["residenceAddress"]); nested exception is org.codehaus.jackson.map.JsonMappingException: No suitable constructor found for type [simple type, class com.foo.assignment.model.Address]: can not instantiate from JSON object (need to add/enable type information?)
at [Source: org.apache.catalina.connector.CoyoteInputStream@f264df; line: 1, column: 98] (through reference chain: com.foo.assignment.model.Person["residenceAddress"])
at org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.readInternal(MappingJacksonHttpMessageConverter.java:127)
at org.springframework.http.converter.AbstractHttpMessageConverter.read(AbstractHttpMessageConverter.java:153)
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:120)
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:91)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:71)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:74)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:155)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:117)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:900)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:827)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:957)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:620)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:722)
Caused by: org.codehaus.jackson.map.JsonMappingException: No suitable constructor found for type [simple type, class com.foo.assignment.model.Address]: can not instantiate from JSON object (need to add/enable type information?)
at [Source: org.apache.catalina.connector.CoyoteInputStream@f264df; line: 1, column: 98] (through reference chain: com.foo.assignment.model.Person["residenceAddress"])
at org.codehaus.jackson.map.JsonMappingException.from(JsonMappingException.java:163)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObjectUsingNonDefault(BeanDeserializer.java:746)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:683)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:580)
at org.codehaus.jackson.map.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:299)
at org.codehaus.jackson.map.deser.SettableBeanProperty$MethodProperty.deserializeAndSet(SettableBeanProperty.java:414)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:697)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:580)
at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:2732)
at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1923)
at org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.readInternal(MappingJacksonHttpMessageConverter.java:124)
... 37 more
00:53:42,310 DEBUG ExceptionHandlerException**
在 Address 对象中添加默认构造函数解决了该错误。并且使用 Google 插件 Postman(插件https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop?hl=en)确实有助于快速测试我的更改。
问题出在您的 POJO 上,将服务器日志级别保持在调试级别并检查错误。这主要与某些字段和字段类型不匹配有关。
使用嵌套类时也会发生此错误,例如
class One {
some code..
public class NestedOne {
private attr;
public NestedOne() {
// default constructor
}
}
}
然后有
@RequestMapping(value = "/something")
public String someControllerMethod(@RequestBody One.NestedOne nested) {
...
}
然后,杰克逊不将 NestedOne() 识别为默认构造函数并搜索 One.NestedOne() 构造函数。