忽略 jax-rs 中传入的 json 元素
Ignoring incoming json elements in jax-rs
我想知道将 @JsonIgnoreProperties(ignoreUnknown = true)
放在 Java REST API 中的什么位置。我有以下 class:
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.map.ObjectMapper;
@JsonIgnoreProperties(ignoreUnknown = true)
public class QueuePayload {
private String message;
private String id;
public String getId() {
return this.id;
}
public String getMessage() {
return this.message;
}
public void setId(String id) {
this.id = id;
}
public void setMessage(String message) {
this.message = message;
}
public String serialize() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(this);
}
}
我在 JAX-RS servlet 中使用的是这样的:
import javax.jms.JMSException;
import javax.naming.NamingException;
import javax.ws.rs.Consumes;
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 javax.ws.rs.core.Response.Status;
@Path("/v1")
@Produces(MediaType.APPLICATION_JSON)
public class ServiceApiV1 {
@GET
public Response getApiRoot() {
String result = "{\"notice\" : \"It is alive!\"}";
return Response.status(Status.OK).entity(result).build();
}
@POST
@Path("/update")
@Consumes(MediaType.APPLICATION_JSON)
public Response update(UpdatePayload message) {
return Response.status(Status.OK).entity(message).build();
}
}
当我 post { "message" : "Test", "id" : "one" }
它就像一个魅力,但是当我 post { "message" : "Test", "id" : "one", "sneaked" : "in" }
我得到:
SRVE0315E: An exception occurred:
com.ibm.ws.webcontainer.webapp.WebAppErrorReport:
javax.servlet.ServletException:
org.codehaus.jackson.map.exc.UnrecognizedPropertyException:
Unrecognized field "sneaked";
(Class test.QueuePayload), not marked as ignorable
at [Source: com.ibm.ws.webcontainer.srt.SRTInputStream@b7328421; line: 1, column: 7] (through reference chain: test.QueuePayload["sneaked"])
虽然 @JsonIgnoreProperties(ignoreUnknown = true)
正是为这个用例设计的。我还尝试在 servlet 和各种排列中不使用 属性。我检查了 this question 并确保在两个 class 中导入了相同的 API 版本。
我错过了什么?
更新
将导入的 classed 更改为代码库(见上文)和 运行 此测试:
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
QueuePayload qp = new QueuePayload();
qp.setPayload("PayLoad");
qp.setQueueId("ID-of-Q");
qp.setStatus("Some Status");
System.out.println(qp.serialize());
ObjectMapper om = new ObjectMapper();
QueuePayload qp2 = om.readValue("{\"payload\":\"PayLoad\",\"queueId\":\"ID-of-Q\",\"newstatus\":\"New Status\"}",
QueuePayload.class);
System.out.println(qp2.serialize());
}
成功了。 servlet 没有
问题似乎是服务器使用 Jackson 1.x (codehaus)。您正在尝试使用 Jackson 2.x 注释 (fasterxml)。他们不互动。您可以通过异常判断它是 codehaus 异常,这意味着实际使用了较旧的 Jackson。
您可以在服务器中尝试找到确切的版本,或者您可以尝试使用随机 1.x 版本(当然在提供的范围内,没有冲突),就像这样一个
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.13</version>
<scope>provided</scope>
</dependency>
然后在模型class(不是资源class)上使用org.codehaus.jackson.annotate.JsonIgnoreProperties
。
我想知道将 @JsonIgnoreProperties(ignoreUnknown = true)
放在 Java REST API 中的什么位置。我有以下 class:
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.map.ObjectMapper;
@JsonIgnoreProperties(ignoreUnknown = true)
public class QueuePayload {
private String message;
private String id;
public String getId() {
return this.id;
}
public String getMessage() {
return this.message;
}
public void setId(String id) {
this.id = id;
}
public void setMessage(String message) {
this.message = message;
}
public String serialize() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(this);
}
}
我在 JAX-RS servlet 中使用的是这样的:
import javax.jms.JMSException;
import javax.naming.NamingException;
import javax.ws.rs.Consumes;
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 javax.ws.rs.core.Response.Status;
@Path("/v1")
@Produces(MediaType.APPLICATION_JSON)
public class ServiceApiV1 {
@GET
public Response getApiRoot() {
String result = "{\"notice\" : \"It is alive!\"}";
return Response.status(Status.OK).entity(result).build();
}
@POST
@Path("/update")
@Consumes(MediaType.APPLICATION_JSON)
public Response update(UpdatePayload message) {
return Response.status(Status.OK).entity(message).build();
}
}
当我 post { "message" : "Test", "id" : "one" }
它就像一个魅力,但是当我 post { "message" : "Test", "id" : "one", "sneaked" : "in" }
我得到:
SRVE0315E: An exception occurred: com.ibm.ws.webcontainer.webapp.WebAppErrorReport: javax.servlet.ServletException: org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "sneaked"; (Class test.QueuePayload), not marked as ignorable at [Source: com.ibm.ws.webcontainer.srt.SRTInputStream@b7328421; line: 1, column: 7] (through reference chain: test.QueuePayload["sneaked"])
虽然 @JsonIgnoreProperties(ignoreUnknown = true)
正是为这个用例设计的。我还尝试在 servlet 和各种排列中不使用 属性。我检查了 this question 并确保在两个 class 中导入了相同的 API 版本。
我错过了什么?
更新
将导入的 classed 更改为代码库(见上文)和 运行 此测试:
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
QueuePayload qp = new QueuePayload();
qp.setPayload("PayLoad");
qp.setQueueId("ID-of-Q");
qp.setStatus("Some Status");
System.out.println(qp.serialize());
ObjectMapper om = new ObjectMapper();
QueuePayload qp2 = om.readValue("{\"payload\":\"PayLoad\",\"queueId\":\"ID-of-Q\",\"newstatus\":\"New Status\"}",
QueuePayload.class);
System.out.println(qp2.serialize());
}
成功了。 servlet 没有
问题似乎是服务器使用 Jackson 1.x (codehaus)。您正在尝试使用 Jackson 2.x 注释 (fasterxml)。他们不互动。您可以通过异常判断它是 codehaus 异常,这意味着实际使用了较旧的 Jackson。
您可以在服务器中尝试找到确切的版本,或者您可以尝试使用随机 1.x 版本(当然在提供的范围内,没有冲突),就像这样一个
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.13</version>
<scope>provided</scope>
</dependency>
然后在模型class(不是资源class)上使用org.codehaus.jackson.annotate.JsonIgnoreProperties
。