Tasos
Tasos

Reputation: 1637

Cannot figure how to access request headers in a jaxrs server that is auto-generated by swagger

This is my current dummy POST login function. I want to read the request headers inside public Response loginPost(). Is it possible? I tried for example changing the function arguments but I always get io.swagger.api.impl.LoginApiServiceImpl is not abstract and does not override abstract method loginPost(io.swagger.model.LoginPostRequestBody,javax.ws.rs.core.SecurityContext) in io.swagger.api.LoginApiService

package io.swagger.api.impl;

import io.swagger.api.*;
import io.swagger.model.*;

import io.swagger.model.LoginPost200Response;
import io.swagger.model.LoginPostRequestBody;

import java.util.Map;
import java.util.List;
import io.swagger.api.NotFoundException;

import java.io.InputStream;

import org.glassfish.jersey.media.multipart.FormDataContentDisposition;

import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.validation.constraints.*;

@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaJerseyServerCodegen", date = "2020-01-21T12:31:41.554Z[GMT]")public class LoginApiServiceImpl extends LoginApiService {
    @Override
    public Response loginPost(LoginPostRequestBody body, SecurityContext securityContext) throws NotFoundException {
        // do some magic!
    }
}

Upvotes: 1

Views: 593

Answers (2)

Michiel Leegwater
Michiel Leegwater

Reputation: 1180

The solution by Tasos is correct. However, modifying generated code is not my cup of tea. Therefore I would suggest modifying the Mustache templates: API template and API service template (and the 'Impl' template, which is should follow suit).

I would suggest replacing SecurityContext securityContext in the service with a new container object storing all @Context objects that are needed. E.g.:

// ... snippet from apiService.mustache ...
public abstract class {{classname}}Service {
    public static class Context {
        private final UriInfo uriInfo;
        private final SecurityContext securityContext;
    
        public Context(HttpHeaders httpHeaders, SecurityContext securityContext) {
            this.httpHeaders = httpHeaders;
            this.securityContext = securityContext;
        }
        // ... getters
    }

    {{#operation}}
    public abstract Response {{nickname}}({{#allParams}}{{>serviceQueryParams}}{{>servicePathParams}}{{>serviceHeaderParams}}{{>serviceBodyParams}}{{>serviceFormParams}},{{/allParams}}Context context) throws NotFoundException;
    {{/operation}}
}
{{/operations}}

The api.mustache file can be modified accordingly to fill the Context before calling the delegate method.

    public Response {{nickname}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}},{{/allParams}}@Context SecurityContext securityContext,    
            @Context HttpHeaders httpHeaders) throws NotFoundException {
        var context = new {{classname}}Service.Context(httpHeaders, securityContext);
        return delegate.{{nickname}}({{#allParams}}{{#isFormParam}}{{#isFile}}{{paramName}}Bodypart{{/isFile}}{{/isFormParam}}{{^isFile}}{{paramName}}{{/isFile}}{{^isFormParam}}{{#isFile}}{{paramName}}{{/isFile}}{{/isFormParam}}, {{/allParams}}context);
    }

The approach above allows the implementations that use the generated code to be consistent and require no modification after code generation.

Upvotes: 1

Tasos
Tasos

Reputation: 1637

The http headers cannot be accessed by this auto-generated class. Instead one has to go to src/gen/java/io/swagger/api/myApi.java and do the following

  1. import javax.ws.rs.core.HttpHeaders;
  2. edit the response function at the last part of the file so that it also takes this argument @Context HttpHeaders requestHeaders
  3. change the exception code at the end, the function there also needs to take the above argument (without @Context in this case)

Then update the myApiService.java file in the same folder and of course the myApiServiceImpl.java file in src/main/java/io/swagger/api/impl/ so that they both import and take as argument the javax.ws.rs.core.HttpHeaders. Do not use @Context in these latter cases either.

The general idea is to first change the myApi.java file so that it passes request headers and then update all the files that use the request function (if you can't figure them all out, compiler errors will guide you)

Upvotes: 1

Related Questions