Java JAX-RS如何序列化嵌入到公共包装器对象中的JSON对象,并在没有包装器的情况下反序列化
我打算将JSON数据发送到我的JAX-RS端点,如下所示:Java JAX-RS如何序列化嵌入到公共包装器对象中的JSON对象,并在没有包装器的情况下反序列化,java,json,jersey,jackson,jax-rs,Java,Json,Jersey,Jackson,Jax Rs,我打算将JSON数据发送到我的JAX-RS端点,如下所示: POST/myendpoint { "field1": "something", "field2": "something else", "field3": 12345 } { "type": "MyEndpoint" "items": [ { "item": { "id": 1, "field1": "something", "field
POST/myendpoint
{
"field1": "something",
"field2": "something else",
"field3": 12345
}
{
"type": "MyEndpoint"
"items": [
{
"item": {
"id": 1,
"field1": "something",
"field2": "something else",
"field3": 12345
},
"link": "https://api.site.com/myendpoint/1"
},
{
"item": {
"id": 2,
"field1": "different",
"field2": "different else",
"field3": 67890
},
"link": "https://api.site.com/myendpoint/2"
}
],
"page_size": 10,
"page": 1,
"total": 2,
"message": ""
}
然后,当我检索一个对象时,我希望它包含在一个公共包装中:
GET/myendpoint
{
"field1": "something",
"field2": "something else",
"field3": 12345
}
{
"type": "MyEndpoint"
"items": [
{
"item": {
"id": 1,
"field1": "something",
"field2": "something else",
"field3": 12345
},
"link": "https://api.site.com/myendpoint/1"
},
{
"item": {
"id": 2,
"field1": "different",
"field2": "different else",
"field3": 67890
},
"link": "https://api.site.com/myendpoint/2"
}
],
"page_size": 10,
"page": 1,
"total": 2,
"message": ""
}
及
GET/myendpoint/2
{
"type": "MyEndpoint"
"items": [
{
"item": {
"id": 2,
"field1": "different",
"field2": "different else",
"field3": 67890
},
"link": "https://api.site.com/myendpoint/2"
}
],
"page_size": 10,
"page": 1,
"total": 1,
"message": ""
}
我开始在泽西岛使用Jackson FasterXML进行自动序列化/反序列化,即:
@Provider
public class JsonObjectMapperProvider implements ContextResolver<ObjectMapper> {
private final ObjectMapper objectMapper;
public JsonObjectMapperProvider() {
objectMapper = new ObjectMapper();
}
@Override
public ObjectMapper getContext(final Class<?> type) {
return objectMapper;
}
}
@Provider
公共类JsonObjectMapperProvider实现ContextResolver{
私有最终ObjectMapper ObjectMapper;
公共JsonObjectMapperProvider(){
objectMapper=新的objectMapper();
}
@凌驾
公共对象映射器getContext(最终类类型){
返回对象映射器;
}
}
然后在资源中:
@POST
@Consumes(MediaType.APPLICATION_JSON)
public void createMyEndpoint(MyEndpoint myEndpoint) {
myEndpointDao.create(myEndpoint);
// ...
}
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<MyEndpoint> createMyEndpoint() {
// I'm not actually sure how to do this one yet!! but I include it for completeness
return myEndpointDao.getAll();
}
@GET
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
public MyEndpoint createMyEndpoint(@PathParam("{id}") id) {
return myEndpointDao.read(id);
}
@POST
@使用(MediaType.APPLICATION_JSON)
public void createMyEndpoint(MyEndpoint MyEndpoint){
创建(myEndpoint);
// ...
}
@得到
@产生(MediaType.APPLICATION_JSON)
公共列表createMyEndpoint(){
//我还不确定该怎么做!!但为了完整起见,我把它包括进去了
返回myEndpointDao.getAll();
}
@得到
@路径(“{id}”)
@产生(MediaType.APPLICATION_JSON)
public MyEndpoint createMyEndpoint(@PathParam(“{id}”)id){
返回myEndpointDao.read(id);
}
这适用于包装中不包含的MyEndpoint对象,但如何包含包装?还是有更好的办法
JSON的模式并不是一成不变的,如果还有其他更有意义的东西,那么我会洗耳恭听。在这里,我写下了一些关于阅读您的问题的建议:
javax.ws.rs.core.Response
Response
对象来序列化您的响应。例如,对于成功响应,请使用:response.ok().entity(yourReturnObject.build()
,这将几乎透明地处理序列化部分(您不需要处理objectMapper)李>
这可能是一个简单的方法示例:
@GET
@Path("/{id}")
@Produces({ "application/json" })
public Response createMyEndpoint(@PathParam("id") String id) {
try {
return Response.ok().entity(myEndpointDao.read(id)).build();
} catch (Exception e) {
Response.status(500).entity(e.getMessage()).build();
}
}
我还建议,为了让你的生活更简单,看一看。哪一版本的jax-rs,2.0?是的jax-rs 2.0,我使用的是Jersey 2.25.1,一开始我完全误解了你的答案;我错误地认为,通过返回响应,我放弃了自动JSON序列化,这让我看不到(您甚至声明)我没有这样做的事实。我继续研究,得出了同样的结论。重新阅读您的答案后,我意识到解决方案一直都在这里,而且我使用包装器POJO这一事实也无关紧要,因为Jackson在使用泛型(例如
MyWrapper=new MyWrapper())时可以无缝地处理这一问题代码>然后返回Response.status(Response.status.CREATED).entity(wrapper.build()代码>。至少现在我很自信,并且确信这是正确的方法,这总是好的:)@Neilos很高兴并满意你发现我的答案是正确的;)