我的端点无法理解传入的JSON。
这里是端点:
import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.hibernate.Query;
import org.hibernate.Session;
import org.json.JSONObject;
...
@POST
@Path("/{department}/{team}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response handleJSON(JSONObject json , @PathParam("department") String department, @PathParam("team") String team){
MyObj myObj = new MyObj();
myObj.setDepartment(department);
myObj.setTeam(team);
myObj.setPlatform(json.optString("platform"));
saveObj(myObj);
return Response.ok(true).build();
}
我正在使用邮递员发布包含“平台”键/值的JSON,标题为:Content-Type
为application/json
但是我得到这个例外:com.owlike.genson.JsonBindingException: Could not deserialize to type class org.json.JSONObject
看起来问题出在以下方面:Illegal character at row 0 and column 1 expected { but read '-' !
但是我很确定邮递员应该发送有效的JSON ...
这里有更多的堆栈跟踪:
09-Jul-2014 10:30:00.017 SEVERE [http-nio-8080-exec-4] com.sun.jersey.spi.container.ContainerResponse.logException Mapped exception to response: 500 (Internal Server Error)
javax.ws.rs.WebApplicationException: com.owlike.genson.JsonBindingException: Could not deserialize to type class org.json.JSONObject
at com.owlike.genson.ext.jaxrs.GensonJsonConverter.readFrom(GensonJsonConverter.java:127)
at com.sun.jersey.spi.container.ContainerRequest.getEntity(ContainerRequest.java:474)
at com.sun.jersey.server.impl.model.method.dispatch.EntityParamDispatchProvider$EntityInjectable.getValue(EntityParamDispatchProvider.java:123)
at com.sun.jersey.server.impl.inject.InjectableValuesProvider.getInjectableValues(InjectableValuesProvider.java:46)
at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$EntityParamInInvoker.getParams(AbstractResourceMethodDispatchProvider.java:153)
at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:203)
at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75)
at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:288)
at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108)
at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1469)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1400)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1349)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1339)
at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:699)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:503)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:136)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:526)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1078)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:655)
at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:222)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1566)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1523)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:744)
Caused by: com.owlike.genson.JsonBindingException: Could not deserialize to type class org.json.JSONObject
at com.owlike.genson.Genson.deserialize(Genson.java:391)
at com.owlike.genson.ext.jaxrs.GensonJsonConverter.readFrom(GensonJsonConverter.java:125)
... 41 more
Caused by: com.owlike.genson.stream.JsonStreamException: Illegal character at row 0 and column 1 expected { but read '-' !
at com.owlike.genson.stream.JsonReader.newWrongTokenException(JsonReader.java:949)
at com.owlike.genson.stream.JsonReader.begin(JsonReader.java:425)
at com.owlike.genson.stream.JsonReader.beginObject(JsonReader.java:157)
at com.owlike.genson.reflect.BeanDescriptor.deserialize(BeanDescriptor.java:101)
at com.owlike.genson.reflect.BeanDescriptor.deserialize(BeanDescriptor.java:90)
at com.owlike.genson.convert.BeanViewConverter.deserialize(BeanViewConverter.java:102)
at com.owlike.genson.convert.NullConverter$NullConverterWrapper.deserialize(NullConverter.java:56)
at com.owlike.genson.Genson.deserialize(Genson.java:389)
... 42 more
这可能不是理想的解决方案,但我确实认为它可以工作。
希望您已经有了Jackson JSON依赖项...
您可以在这里找到它:http://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core
我会尝试以下代码:
@POST
@Path("/{department}/{team}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response handleJSON(String json, @PathParam("department") String department, @PathParam("team") String team){
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readValue(json, JsonNode.class);
MyObj myObj = new MyObj();
myObj.setDepartment(department);
myObj.setTeam(team);
if (node.get("platform") != null) {
myObj.setPlatform(node.get("platform").textValue());
}
saveObj(myObj);
return Response.ok(true).build();
}
[请注意,我正在要求您的WS Framework将JSON作为字符串传递给我,然后自行处理。也许它不是理想的,但应该可以工作。
干杯!
我不知道您使用的是哪个JSON序列化器,但很可能是Jettison或Jackson。据我所知,他们不支持直接转换org.json.JSONObject
的实例。更常见的方法是只使用自定义Java Bean:
public class Foo implements Serializable {
private String platform;
// getters + setters
}
@POST
@Path("/{department}/{team}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response handleJson(Foo foo, @PathParam("department") String department, @PathParam("team") String team) {
...
myObj.setPlatform(foo.getPlatform());
...
}
[Foo
应该用@XmlRootElement注释,如果您使用的是Jettison。
如果您不希望为每个实体创建自定义Bean,则可以使用Object
,Map
或String
作为参数并自行进行序列化:
@POST
@Path("/{department}/{team}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response handleJson(String json, @PathParam("department") String department, @PathParam("team") String team) {
...
JSONObject jsonObject = new JSONObject(json);
myObj.setPlatform(json.optString("platform"));
...
}
最后的解决方案是实现处理MessageBodyReader的JSONObject
。简单的例子:
@Provider
public class JsonObjectReader implements MessageBodyReader<JSONObject> {
@Override
public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return type == JSONObject.class && MediaType.APPLICATION_JSON_TYPE.equals(mediaType);
}
@Override
public JSONObject readFrom(Class<JSONObject> type, Type genericType,
Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
throws IOException, WebApplicationException {
return new JSONObject(IOUtils.toString(entityStream));
}
}
您应该先检查请求的发送方式。它可能是作为转义字符串而不是原始JSON发送的。
就我而言,这就是我使用通用REST客户端以纯JSON字符串形式发送请求时发生的情况,因为我的客户端不知道对象定义。
[为防止这种情况,您可以在客户端中发送[org.codehaus.jettison.json
)JSONObject
而不是仅发送String
(它具有接受JSON字符串的构造函数),但这将取决于您的依赖项。就我而言,我使用的是Jersey 1.19。
请注意,根据类路径的不同(在我的情况下,Jersey 1.19和Genson一起使用,如果您还想将响应读取为JSON字符串,则可能还需要手动读取响应输入流。