question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Enum value not taken over

See original GitHub issue

Swagger core version 1.5.12

The Java enumeration has the following code:

@XmlType(name = "PickPriority")
@XmlEnum
public enum PickPriority {

    @XmlEnumValue("1")
    VALUE_1("1"),

The following code is being generated: {"name":"PickingPriority"},"enum":["VALUE_1", The value() of the enumeration should be used.

Issue Analytics

  • State:open
  • Created 7 years ago
  • Comments:14 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
JoopBLcommented, Feb 21, 2017

I wrote a custom ObjectMapper but the getContext is never called when refreshing from SwaggerUI. The constructor is called during startup. Any idea’s?

`import javax.ws.rs.ext.ContextResolver; import javax.ws.rs.ext.Provider;

import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule;

@Provider public class EnumObjectMapperProvider implements ContextResolver<ObjectMapper> {

private static final ObjectMapper OBJECTMAPPER = new ObjectMapper();

static {
	JaxbAnnotationModule module = new JaxbAnnotationModule();
	OBJECTMAPPER.registerModule(module);
	OBJECTMAPPER.configure(SerializationFeature.WRITE_ENUMS_USING_TO_STRING, true);
}

@Override
public ObjectMapper getContext(Class<?> type) {
	return OBJECTMAPPER;
}`
0reactions
rwalkerandscommented, Mar 22, 2017

I’ve been adding authentication to my API, and came across an issue with my SwaggerBootstrapper class given above, namely, the enums that are inside swagger-core aren’t serialized correctly.

The enums inside swagger-core (e.g., io.swagger.models.auth.In) are specified using Jackson annotations, and my original SwaggerBootstrapper doesn’t respect those Jackson annotations.

So you get in": "HEADER" instead of in": "header" in your swagger.json.

Please use this version instead:

package <put your package here>;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule;

import io.swagger.converter.ModelConverters;
import io.swagger.jackson.ModelResolver;
import io.swagger.jaxrs.config.BeanConfig;
import io.swagger.models.properties.Property;
import io.swagger.models.properties.StringProperty;
import io.swagger.util.Json;

/** Class to bootstrap the configuration of the Swagger view of the API.
 */
public class SwaggerBootstrapper extends HttpServlet {

    /** Generated UID for serialization. */
    private static final long serialVersionUID = <put a long value here>L;

    /** Initialize the settings of the Swagger view of the API.
     */
    @Override
    public void init(final ServletConfig config) throws ServletException {
        super.init(config);

        // This makes Swagger honor JAXB annotations. Well,
        // not _all_ of them. It seems it doesn't respect
        // @XmlEnumValue.
        ObjectMapper mapper = Json.mapper();
        mapper.registerModule(new JaxbAnnotationModule());

        // The problem is the constructor of Swagger's AbstractModelConverter
        // class, which "overrides" our introspector with Swagger's own.
        // At least, the "override" comes into play at a point we don't
        // want it to, i.e., when values of enums are extracted.

        // So, create a customized ModelResolver that uses the
        // JaxbAnnotationModule to get values of enumerated types.
        // Need to create an instance of an anonymous class that
        // overrides the _addEnumProps() method!
        // (Could also be done as a separate subclass, of course.)
        final AnnotationIntrospector jaxbIntrospector =
                new JaxbAnnotationIntrospector(mapper.getTypeFactory());
        // Also need Jackson's introspector, as it is used for
        // swagger-core's own enums (e.g., io.swagger.models.auth.In).
        final AnnotationIntrospector jacksonIntrospector =
                new JacksonAnnotationIntrospector();
        mapper.setAnnotationIntrospector(
                AnnotationIntrospector.pair(jacksonIntrospector,
                        jaxbIntrospector));

        ModelResolver modelResolver = new ModelResolver(mapper) {
            @Override
            protected void _addEnumProps(final Class<?> propClass,
                    final Property property) {
                final boolean useIndex = _mapper.isEnabled(
                        SerializationFeature.WRITE_ENUMS_USING_INDEX);
                final boolean useToString = _mapper.isEnabled(
                        SerializationFeature.WRITE_ENUMS_USING_TO_STRING);

                @SuppressWarnings("unchecked")
                Class<Enum<?>> enumClass = (Class<Enum<?>>) propClass;
                for (Enum<?> en : enumClass.getEnumConstants()) {
                    String n;
                    if (useIndex) {
                        n = String.valueOf(en.ordinal());
                    } else if (useToString) {
                        n = en.toString();
                    } else {
                        // This is the original code, which gets the "first"
                        // introspector, which is Swagger's, not ours.
//                        n = _intr.findEnumValue(en);
                        // Instead, use the introspector we created above.
                        n = jaxbIntrospector.findEnumValue(en);
                    }
                    if (property instanceof StringProperty) {
                        StringProperty sp = (StringProperty) property;
                        sp._enum(n);
                    }
                }
            }
        };

        // Have Swagger use our custom ModelConverter when generating
        // swagger.json.
        ModelConverters.getInstance().addConverter(modelResolver);

        // Now define the top-level Swagger properties.
        BeanConfig beanConfig = new BeanConfig();
        beanConfig.setTitle("Vocabulary Registry API");
        beanConfig.setVersion("0.1.0");

        <set the reset of the beanConfig properties here>

        // Without scan=true, the top-level properties set in the previous
        // lines don't make their way into the generated swagger.json!
        beanConfig.setScan(true);
    }
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

c++ - Is it allowed for an enum to have an unlisted value?
Now a very tricky thing: the values that can be held by an enum variable depends on whether or not the underlying type...
Read more >
Enum With and Without Values - Learn TypeScript - Educative.io
enum is a type that enforces a limited and defined group of constants. enum must have a name and accepted values. Afterward, you...
Read more >
Enumeration types - C# reference - Microsoft Learn
An enumeration type (or enum type) is a value type defined by a set of named constants of the underlying integral numeric type....
Read more >
Attaching Values to Java Enum - Baeldung
Java provides a valueOf(String) method for all enum types. Thus, we can always get an enum value based on the declared name: assertSame(Element....
Read more >
Enum Types - Java™ Tutorials
An enum type is a special data type that enables for a variable to be a set of predefined constants. The variable must...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found