swagger-core icon indicating copy to clipboard operation
swagger-core copied to clipboard

@JsonView ignored for subclasses

Open devopsix opened this issue 3 years ago • 0 comments

I am having a parent class with subclasses. I am using different @JsonView annotations where the classes are used for request bodies and response bodies.

When generating a schema from the parent class for a given @JsonView, the schema generated for the child class contains an incorrect selection of the classes' fields.

public class Demo {

	public interface Input {}

	public interface Output {}

	@JsonTypeInfo(use = NAME)
	@JsonSubTypes({
		@JsonSubTypes.Type(value = A1.class),
	})
	public static abstract class A {
		@JsonView(Input.class)
		public String a_in;
		@JsonView(Output.class)
		public String a_out;
	}

	public static class A1 extends A {
		@JsonView(Input.class)
		public String a1_in;
		@JsonView(Output.class)
		public String a1_out;
	}

	private static final JsonView VIEW_OUTPUT = new JsonView() {
		public Class<? extends Annotation> annotationType() {
			return JsonView.class;
		}
		public Class<?>[] value() {
			return new Class[] {Output.class};
		}
	};

	public static void main(String[] args) {
		ResolvedSchema resolvedSchema = ModelConverters.getInstance()
			.resolveAsResolvedSchema(
				new AnnotatedType(A.class).resolveAsRef(true)
					.jsonViewAnnotation(VIEW_OUTPUT));
		resolvedSchema.referencedSchemas.forEach((name, schema) -> dumpSchema(schema, ""));
	}

	private static void dumpSchema(Schema<?> schema, String indent) {
		if (schema.get$ref() != null) {
			System.out.println(indent + "$ref: " + schema.get$ref());
		}
		if (schema.getName() != null) {
			System.out.println(indent + "Schema: " + schema.getName());
		}
		if (schema.getType() != null) {
			System.out.println(indent + "Type: " + schema.getType());
		}
		if (schema.getAllOf() != null) {
			System.out.println(indent + "All of:");
			schema.getAllOf().forEach((allOfSchema) -> dumpSchema(allOfSchema, indent + "  "));
		}
		if (schema.getProperties() != null) {
			System.out.println(indent + "Properties:");
			schema.getProperties().forEach((propName, propSchema) -> {
				System.out.println(indent + propName);
				dumpSchema(propSchema, indent + "  ");
			});
		}
	}
}

This is the actual output:

Schema: A1
Type: object
All of:
  $ref: #/components/schemas/A_Output
  Type: object
  Properties:
  a_in
    Schema: a_in
    Type: string
  a1_in
    Schema: a1_in
    Type: string
  a1_out
    Schema: a1_out
    Type: string
Schema: A_Output
Type: object
Properties:
a_out
  Schema: a_out
  Type: string

What I would expect instead:

- Schema: A1
+ Schema: A1_Output
Type: object
All of:
  $ref: #/components/schemas/A_Output
  Type: object
  Properties:
-  a_in
-    Schema: a_in
-    Type: string
-  a1_in
-    Schema: a1_in
-    Type: string
  a1_out
    Schema: a1_out
    Type: string
Schema: A_Output
Type: object
Properties:
a_out
  Schema: a_out
  Type: string

I have pushed a minimal reproducible example to GitHub.

swagger-core version: 2.2.2 jackson-core version: 2.13.3 Java, OpenJDK 18.0.2.1

devopsix avatar Aug 26 '22 08:08 devopsix