自定义 Json 序列化程序而不是 Jersey 的默认序列化程序?

Customize Json serializer instead of Jersey's default?

我正在使用 Jersey 来实现 RESTful 网络服务。现在我 return 数据的 MediaType 是 JSON.

@GET
@Produces({MediaType.APPLICATION_JSON })
public Response service() {
    return Response
            .ok(entity)
            .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON)
            .build();
}

这里我将CONTENT_TYPE设置为json,我的实体将被Jersey框架转换为json。

现在我想自定义我的 json 回复。

例如:我想删除空元素或更改 Json 对象的键名。 默认 Jersey 的 Json 转换:

{
   "cinter" : {
     "state" : 1,
     "checks" : 10,
   }
}

我想要的:

{
   "cin" : {
     "st" : 1,
     "cs" : 10,
   }
}

我知道我可以使用 Jackson 图书馆的我自己的 ObjectMapper 来根据我的需要定制我的 Json。

但如果我想 JSON 以不同于 Jersey 的默认转换的方式进行转换,这是标准方法吗??

或者我可以更改 Jersey 的 ObjectMapper 中的参数吗??

我应该使用自己的 ObjectMapper 吗?

这是我对您的选择的看法。首先

So for every different response I should configure ObjectMapper differently ?

如果你想像这样在不同的地方使用两个 json 版本

public Response getObject()           // returns {"cinter" : {"state" : 1,"checks" : 10}}
public Response getShortNamesObject() // returns {"cin" : {"st" : 1,"cs" : 10}}

是的,你必须使用多个 ObjectMappers

但是如果你只想在任何地方使用 1 种表示,那么你可能可以使用自定义 mixin 为你设置一次 Jackson 类。无论如何,这里是您可以执行这两个选项的方法:让我们看一下只需要 1 json 版本

的简单案例
public class TestBean {
    private String name;
    private int id;
    //getters and setters
}

public interface TestBeanMixin {
    @JsonProperty("short_field_name")
    String getName();
    @JsonProperty("short_field_id")
    int getId();
}

@Provider
@Priority(1)
public class MixInJacksonJsonProvider extends JacksonJaxbJsonProvider {
    private static final ObjectMapper mapper = createMapper();

    public MixInJacksonJsonProvider() {
        setMapper(mapper);
    }

    private static ObjectMapper createMapper() {
        final ObjectMapper result = new ObjectMapper();
        result.addMixIn(TestBean.class, TestBeanMixin.class);
        return result;
    }
}

此代码将为您在各处的 POJO 字段生成短名称。并为不同的请求实现不同的行为,我们必须像这样添加新的自定义注释:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface MixIn {}

控制器将如下所示:

@Path("test")
public class MyResource {

    @GET 
    @MixIn // <== Here is important part
    @Produces(MediaType.APPLICATION_JSON )
    public Response  getShortName() {
        return Response.ok(demoObj()).build();
    }

    @POST
    @Produces(MediaType.APPLICATION_JSON )
    public Response  postLongName() {
        return Response.ok(demoObj()).build();
    }
}

我们的 MixInJacksonJsonProvider 还会有 2 个 @Override:

    //.. same as before

    @Override
    public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        return super.isReadable(type, genericType, annotations, mediaType) && hasMixInAnnotation(annotations);
    }

    @Override
    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        return super.isWriteable(type, genericType, annotations, mediaType) && hasMixInAnnotation(annotations);
    }
    public static boolean hasMixInAnnotation(Annotation[] annotations){
        for(Annotation annotation: annotations){
            if (annotation instanceof MixIn){
                return true;
            }
        }
        return false;
    }
}

下面是演示代码供您玩:https://github.com/varren/jersey2-jacksonsetup/tree/master/src/main/java/ru/varren