LengendaryMango
LengendaryMango

Reputation: 21

Integrated Swagger and previously working code breaks: cannot deserialize from Object value (no delegate- or property-based Creator

I successfully integrated swagger to several spring boot services.
Had to allow the endpoints to bypass authentication by adding in respective @EnableWebSecurity class that extends WebSecurityConfigurerAdapter (this had worked for other services fine) :

 
 @Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Order(1)
public class AppSecurityConfig extends WebSecurityConfigurerAdapter {

...

@Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
                .antMatcher("/**")
       
       ...
                .antMatchers("/actuator/**").permitAll()
                .antMatchers("/v2/api-docs", "/configuration/**", "/webjars/**","/swagger*/**") // ADDED THIS for swagger 
                .permitAll()  // ADDED THIS for swagger 
                .antMatchers("/challenge").permitAll()
                .antMatchers("/token").permitAll()  // ENDPOINT with complaint now, that was previously ok.
               .anyRequest()
                .authenticated()
                .and()
                .cors();
    }
    ...
    }

For a specific one, however, once I added the relevant swagger code & dependencies, it seems to have broken and complains on what was working initially.

this is endpoint with the complaint :

@PostMapping("/token")
    public ResponseDto token(@Valid @RequestBody TokenRequest request) {
        try {
            return service.generateJwtFromCode(request.getId(), request.getCode());
        }
        ...
        catch (Exception exception) {..
        }
        }

nested exception is on no constructor found for this class:

@AllArgsConstructor
public class TokenRequest {

    @NotEmpty
    @JsonProperty
    private final String id;

    @NotEmpty
    @Getter
    private final String code;

    public UUID getId() {
        return UUID.fromString(id);
    }
  

}

Could not resolve parameter [0] in responseDTO  Controller.token(Service.TokenRequest): Type definition error: [simple type, class TokenRequest]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `service.TokenRequest` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (PushbackInputStream); line: 1, column: 2]
 o.s.web.servlet.DispatcherServlet        : Failed to complete request: org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, class service.TokenRequest]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `service.TokenRequest` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (PushbackInputStream); line: 1, column: 2]
o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in …

Not sure what it has to do with swagger integration. If i remove swagger integration code, it works fine with the same code, and doesn't complain about the type-conversion failure.

For resolving this, I also took someone's suggestion of
upgrading dependency for com.fasterxml.jackson.core and rebuilding the code. But still no success.

  compileOnly 'com.fasterxml.jackson.core:jackson-databind:2.11.2'

Things I have tried but didn't resolve:

  1. Added a default/empty constructor (for most others with similar problem it worked by that, for me it complaint thereafter on

error: variable id might not have been initialized
    }

  1. Added this to the tokenRequest class:

@Value
@AllArgsConstructor(onConstructor = @__(@JsonCreator(mode = JsonCreator.Mode.PROPERTIES))

Had a different error:

c.j.MappingJackson2HttpMessageConverter : Failed to evaluate Jackson deserialization for type [[simple type, class TokenRequest]]
InvalidDefinitionException: Invalid type definition for type `TokenRequest`: More than one argument (#0 and #1) left as delegating for Creator [constructor for TokenRequest, annotations: {interface com.fasterxml.jackson.annotation.JsonCreator=@com.fasterxml.jackson.annotation.JsonCreator(mode=DELEGATING)}]: only one allowed
    at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:62)...

Upvotes: 1

Views: 515

Answers (1)

LengendaryMango
LengendaryMango

Reputation: 21

Solution was to add a default constructor AND also remove final variables.

@AllArgsConstructor
public class TokenRequest {

    @NotEmpty
    @JsonProperty
    private String id;  // code fixed issue

    @NotEmpty
    @Getter
    private String code;  // code fixed issue

    public TokenRequest(){}  // code fixed issue
    
    public UUID getId() {
        return UUID.fromString(id);
    }
  


}

Upvotes: 1

Related Questions