Java 如何创建自定义的Jackson注释以在序列化时附加属性

Java 如何创建自定义的Jackson注释以在序列化时附加属性,java,spring-boot,jackson,Java,Spring Boot,Jackson,我想创建一个自定义注释,如下所示: @JacksonAnnotationsInside @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) //... Other Jackson annotations... @interface SelfLink { Class<? extends Entity> type(); String uri

我想创建一个自定义注释,如下所示:

@JacksonAnnotationsInside
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE})
//... Other Jackson annotations...
@interface SelfLink {
    
    Class<? extends Entity> type();
    
    String uriTemplate() default "";

}
自定义的Jackson注释将用于附加额外字段。我试图在
SelfLink
注释上使用
@JsonSerialize(using=SelfLinkSerializer.class)
来定义序列化程序:

@JsonComponent
class SelfLinkSerializer extends StdSerializer<Object> {

    private Gson gson = new Gson();
    private Mirror mirror = new Mirror();

    @Autowired
    private LinkResolver linkResolver;

    @SuppressWarnings("unused")
    private SelfLinkSerializer() {
        this(Object.class, 
            new LinkResolver() {
                @Override
                public <T extends Entity> String resolve(Class<? extends Entity> type, T instance) {
                    return "always-null";
                }
            }
        );
    }

    SelfLinkSerializer(Class<Object> t, LinkResolver linkResolver) {
        super(t);
        this.linkResolver = linkResolver;
    }

    @Autowired
    public SelfLinkSerializer(LinkResolver linkResolver) {
        this(Object.class, linkResolver);
    }

    @Override
    public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        gen.writeStartObject();
    
        this.serializeContentWithoutThisSerializer(value, gen, provider);
    
        gen.writeEndObject();
    }

    private void serializeContentWithoutThisSerializer(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        String jsonContent = this.serializeContentViaGson(value, gen, provider); 
    
        gen.writeRaw(jsonContent);
    }

    private String serializeContentViaGson(Object value, JsonGenerator gen, SerializerProvider provider) {
        JsonElement jsonElement = this.gson.toJsonTree(value);
    
        SelfLink selfLink = this.mirror.on(value.getClass()).reflect().annotation(SelfLink.class).atClass();
        if(selfLink != null) {
            Class<? extends Entity> type = selfLink.type();
            String link = value instanceof Entity ? this.linkResolver.resolve(type, (Entity) value) : null; 
        
            jsonElement.getAsJsonObject().addProperty("link", link);
        }
        String json = this.gson.toJson(jsonElement);
        String trimmed = CharMatcher.is('{').trimFrom(json);
        trimmed = CharMatcher.is('}').trimTrailingFrom(trimmed);
        return trimmed;
    }

}
@JsonComponent
类SelfLinkSerializer扩展了StdSerializer{
private Gson Gson=new Gson();
私有镜像镜像=新镜像();
@自动连线
专用链接解析程序链接解析程序;
@抑制警告(“未使用”)
私有SelfLinkSerializer(){
这个(Object.class,
新链接解析程序(){
@凌驾

公共字符串解析(ClassI可能没有完全理解您的问题。因此我不知道它是否适用于您:您可以通过扩展JsonSerializer和JsonDeserializer类并覆盖序列化/反序列化方法来创建自定义Jackson序列化器/反序列化器。您好@OnurBaştürk,我已经创建了一个序列化器。问题是如何序列化object(创建JSON的字符串表示形式),并在附加我的链接属性之后。如果我尝试使用
JsonGenerator.writeObject(Object pojo)
,它将进入无限循环,而不是讽刺地导致堆栈溢出。```gen.writeStartObject();gen.writeObject(value);/…write-link属性gen.writeEndObject()“``我可以用什么代替gen.writeObject(value)来序列化
value
的内容而不得到无限递归?
@JsonComponent
class SelfLinkSerializer extends StdSerializer<Object> {

    private Gson gson = new Gson();
    private Mirror mirror = new Mirror();

    @Autowired
    private LinkResolver linkResolver;

    @SuppressWarnings("unused")
    private SelfLinkSerializer() {
        this(Object.class, 
            new LinkResolver() {
                @Override
                public <T extends Entity> String resolve(Class<? extends Entity> type, T instance) {
                    return "always-null";
                }
            }
        );
    }

    SelfLinkSerializer(Class<Object> t, LinkResolver linkResolver) {
        super(t);
        this.linkResolver = linkResolver;
    }

    @Autowired
    public SelfLinkSerializer(LinkResolver linkResolver) {
        this(Object.class, linkResolver);
    }

    @Override
    public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        gen.writeStartObject();
    
        this.serializeContentWithoutThisSerializer(value, gen, provider);
    
        gen.writeEndObject();
    }

    private void serializeContentWithoutThisSerializer(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        String jsonContent = this.serializeContentViaGson(value, gen, provider); 
    
        gen.writeRaw(jsonContent);
    }

    private String serializeContentViaGson(Object value, JsonGenerator gen, SerializerProvider provider) {
        JsonElement jsonElement = this.gson.toJsonTree(value);
    
        SelfLink selfLink = this.mirror.on(value.getClass()).reflect().annotation(SelfLink.class).atClass();
        if(selfLink != null) {
            Class<? extends Entity> type = selfLink.type();
            String link = value instanceof Entity ? this.linkResolver.resolve(type, (Entity) value) : null; 
        
            jsonElement.getAsJsonObject().addProperty("link", link);
        }
        String json = this.gson.toJson(jsonElement);
        String trimmed = CharMatcher.is('{').trimFrom(json);
        trimmed = CharMatcher.is('}').trimTrailingFrom(trimmed);
        return trimmed;
    }

}