I am triing to document a rest service with swagger. After build and deploy I get a json, that is lacking the tags (in my case "tags" : ["databases"] is missing) and completely ignores the annotations on the parameters of the webservice interface methods (only the parameters, other documetation is provided correctly). Instead of listing the parameters it contains this:
"parameters" : [{
"in" : "body",
"name" : "body",
"required" : false,
"schema" : {
"type" : "string"
}
}
]
Most likely it has someting to do with the configuration or the process of loading the webapplication, since after a reload of the webapplication with the tomcat manager webapp it sends the correct json.
EDIT: Simply stopping and restarting the application has the same effect. In addion the json after a reload or restart is not deterministic (random). This implies the problem should be with the classloader.
I am using apache tomcat version 8.0.33, the resteasy version is 3.0.14.Final and the swagger is:
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-jaxrs</artifactId>
<version>1.5.8</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.5.8</version>
</dependency>
The application class looks like:
#ApplicationPath("/")
public class ServiceApplication extends Application {
final Set<Object> singletons = new HashSet<Object>();
public ServiceApplication() throws IOException {
final InputStream inStream = getClass().getClassLoader()
.getResourceAsStream("swagger.properties");
final Properties props = new Properties();
props.load(inStream);
final BeanConfig beanConfig = new BeanConfig();
beanConfig.setVersion("1.0.0");
beanConfig.setHost(props.getProperty("host"));
beanConfig.setBasePath("/rest-service");
beanConfig.setResourcePackage("com.example.package");
beanConfig.setScan(true);
final CorsFilter filter = new CorsFilter();
filter.getAllowedOrigins().add("*");
singletons.add(filter);
}
#Override
public Set<Class<?>> getClasses() {
final Set<Class<?>> resources = new HashSet<Class<?>>();
// add WS classes
resources.add(DatabasesImpl.class);
// add provider classes
resources.add(ExcMapper1.class);
resources.add(ExcMapper2.class);
resources.add(ResponseInterceptor.class);
// add swagger classes
resources.add(io.swagger.jaxrs.listing.ApiListingResource.class);
resources.add(io.swagger.jaxrs.listing.SwaggerSerializers.class);
return resources;
}
#Override
public Set<Object> getSingletons() {
return singletons;
}
}
The annotations on the webservice:
#SwaggerDefinition(info = #io.swagger.annotations.Info(description = "<DESCRIPTION>",//
version = "0.0.2-SNAPSHOT", title = "Search", termsOfService = "<TOS>",//
contact = #io.swagger.annotations.Contact(name = "<CONTACT_NAME>", email = "<CONTACT_EMAIL>", url = "<CONTACT_URL>"),//
license = #io.swagger.annotations.License(name = "<LICENCE_NAME>", url = "<LICENCE_URL>")), consumes = {}, produces = { MediaType.APPLICATION_XML },//
schemes = { SwaggerDefinition.Scheme.HTTP, SwaggerDefinition.Scheme.HTTPS },//
externalDocs = #io.swagger.annotations.ExternalDocs(value = "<EXTERNAL_DOCS>", url = "<EXTERNAL_DOCS_URL>"))
#Api(value = "/databases")
#Path("/databases/")
public interface Databases {
#ApiOperation(value = "Searches the database")
#ApiResponses(value = { #ApiResponse(code = 200, message = "Success"),
#ApiResponse(code = 404, message = "Database not found") })
#GET
#Path("{database}/search")
#Produces(MediaType.APPLICATION_XML)
public Response searchExport(
#ApiParam(value = "the database name", required = true, defaultValue = "default") #PathParam("database") #Nonnull final String database,
#ApiParam(value = "query string defaults to match all", defaultValue = "title:foo") #QueryParam("q") #DefaultValue("*:*") final String query,
#ApiParam(value = "starting element index defaults to 0") #QueryParam("start") #DefaultValue("0") final int start,
#ApiParam(value = "number of elements to return defaults to 10") #QueryParam("rows") #DefaultValue("10") final int rows,
#ApiParam(value = "sorting field") #QueryParam("sort") #DefaultValue("title") final String sort,
#ApiParam(value = "sorting order defaults to ascending") #QueryParam("sortOrder") #DefaultValue("ascending") final SortDirection sortOrder)
throws ParseException;
Related
Using wsdl2java tool to generate client classes, I can't seem to able to force to wrap Web Service response in a return type - the return type is always void and OUT parameters wrapped in Holders are generated. Auth.java auto-generated client interface looks like this:
#WebService(targetNamespace = "http://xml.kamsoft.pl/ws/auth", name = "Auth")
#XmlSeeAlso({pl.kamsoft.xml.ws.common.ObjectFactory.class, pl.kamsoft.xml.ws.kaas.login_types.ObjectFactory.class})
#SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
public interface Auth {
// [...] - `logout`, `changePassword`, `changePasswordLog` methods
#WebMethod(action = "login")
public void login(
#WebParam(partName = "request", name = "login", targetNamespace = "http://xml.kamsoft.pl/ws/kaas/login_types")
pl.kamsoft.xml.ws.kaas.login_types.LoginRequest request,
#WebParam(partName = "response", mode = WebParam.Mode.OUT, name = "loginReturn", targetNamespace = "http://xml.kamsoft.pl/ws/kaas/login_types")
jakarta.xml.ws.Holder<java.lang.String> response,
#WebParam(partName = "session", mode = WebParam.Mode.OUT, name = "session", targetNamespace = "http://xml.kamsoft.pl/ws/common", header = true)
jakarta.xml.ws.Holder<pl.kamsoft.xml.ws.common.Session> session,
#WebParam(partName = "token", mode = WebParam.Mode.OUT, name = "authToken", targetNamespace = "http://xml.kamsoft.pl/ws/common", header = true)
jakarta.xml.ws.Holder<pl.kamsoft.xml.ws.common.AuthToken> token
) throws pl.kamsoft.wsdl.common.AuthenticationExceptionMsg, pl.kamsoft.wsdl.common.ServerExceptionMsg, PassExpiredExceptionMsg, pl.kamsoft.wsdl.common.AuthTokenExceptionMsg, pl.kamsoft.wsdl.common.InputExceptionMsg, pl.kamsoft.wsdl.common.AuthorizationExceptionMsg;
}
Minimal example (build.gradle.kts file with Gradle configuration):
plugins {
java
id("com.yupzip.wsdl2java") version "3.0.0"
}
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(17))
}
}
repositories {
mavenCentral()
}
dependencies {
implementation("org.apache.cxf:cxf-rt-frontend-jaxws:4.0.0")
implementation("org.apache.cxf:cxf-rt-transports-http-hc5:4.0.0")
wsdl2java("com.sun.xml.bind:jaxb-impl:4.0.1")
wsdl2java("org.apache.cxf.xjc-utils:cxf-xjc-runtime:4.0.0")
wsdl2java("jakarta.xml.ws:jakarta.xml.ws-api:4.0.0")
wsdl2java("com.sun.xml.ws:rt:4.0.0")
wsdl2java("org.jvnet.jaxb2_commons:jaxb2-namespace-prefix:2.0")
wsdl2java("codes.rafael.jaxb2_commons:jaxb2-basics-runtime:3.0.0")
wsdl2java("codes.rafael.jaxb2_commons:jaxb2-basics:3.0.0")
}
wsdl2java {
wsdlDir = file("$projectDir/src/main/resources/")
includeJava8XmlDependencies = false
cxfVersion = "4.0.0"
cxfPluginVersion = "4.0.0"
wsdlsToGenerate = listOf(
listOf(
"-wsdlLocation", "https://ewus.nfz.gov.pl/ws-broker-server-ewus-auth-test/services/Auth?wsdl",
"-autoNameResolution",
"https://ewus.nfz.gov.pl/ws-broker-server-ewus-auth-test/services/Auth?wsdl",
)
)
}
How can I force wsdl2java tool to generate LoginResponse class of which instance would be returned on Auth#login invocation?
I've tried to include binding file (bindings.xml):
<bindings
wsdlLocation="https://ewus.nfz.gov.pl/ws-broker-server-ewus-auth-test/services/Auth?wsdl"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns="http://java.sun.com/xml/ns/jaxws">
<enableWrapperStyle>false</enableWrapperStyle>
</bindings>
but neither setting enableWrapperStyle to false or true did change anything. Here is how my configuration looked like (build.gradle.kts):
wsdl2java {
wsdlDir = file("$projectDir/src/main/resources/")
includeJava8XmlDependencies = false
cxfVersion = "4.0.0"
cxfPluginVersion = "4.0.0"
wsdlsToGenerate = listOf(
listOf(
"-b", "$projectDir/src/main/resources/wsdl/bindings.xml",
"-wsdlLocation", "https://ewus.nfz.gov.pl/ws-broker-server-ewus-auth-test/services/Auth?wsdl",
"-autoNameResolution",
"https://ewus.nfz.gov.pl/ws-broker-server-ewus-auth-test/services/Auth?wsdl",
)
)
}
Can the fact that both session and token are declared as wsdlsoap:header have impact on the resulting generated Java code?
I have been developing new APIs in Springboot 3 and it has been more a headache than something good, but finally I'm able to do something. Issue is that I was able to add Swagger to it, with OpenAPI from Spring-doc release 2. but the configuration file is not reading my properties. Also I have troubles trying to set up my bearer authentication....
This is my actual swagger: Swagger + spring-doc
And third issue related to this is... I keep can't make the swagger to read the default responses... even I configured like in the old versions, but I couldn't make it work...
For properties, I have tried to add them before the config class, and ad a Bean in methods.
For bearer, I was following Baeldung JWT Swagger guide, but It confuses me a little, tried to run but didnt work.
This is my OpenApiConfig class (commented lines are because they are not compatible with tag declaration):
package info.peluka.csaread.config;
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.info.Contact;
import io.swagger.v3.oas.annotations.info.Info;
import io.swagger.v3.oas.annotations.info.License;
import io.swagger.v3.oas.annotations.servers.Server;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
#Configuration
#OpenAPIDefinition(
info =#Info(
title = "${module-name}",
version = "${api-version}",
contact = #Contact(
name = "Joseph", email = "CSA_Read_API#peluka.info", url = "https://www.peluka.info"
),
license = #License(
name = "Apache 2.0", url = "https://www.apache.org/licenses/LICENSE-2.0"
),
description = "${module-description}"
),
servers = #Server(
url = "${api.server.url}",
description = "Production"
)
)
public class OpenApiConfig {
private final String moduleName;
private final String apiVersion;
private final String moduleDescription;
public OpenApiConfig(
#Value("${module-name}") String moduleName,
#Value("${api-version}") String apiVersion,
#Value("${module-description}") String moduleDescription) {
this.moduleName = moduleName;
this.apiVersion = apiVersion;
this.moduleDescription = moduleDescription;
}
/**
* Configure the OpenAPI components.
*
* #return Returns fully configure OpenAPI object
* #see OpenAPI
*/
#Bean
public OpenAPI customizeOpenAPI() {
//#formatter:off
final String securitySchemeName = "bearerAuth";
return new OpenAPI()
.addSecurityItem(new SecurityRequirement()
.addList(securitySchemeName))
.components(new Components()
.addSecuritySchemes(securitySchemeName, new SecurityScheme()
.name(securitySchemeName)
.type(SecurityScheme.Type.HTTP)
.scheme("bearer")
.description(
"Provide the JWT token. JWT token can be obtained from the /token endpoint. If need to create an user, contact Griffith.")
.bearerFormat("JWT")));
//#formatter:on
}
// #Bean
// public OpenAPI customOpenAPI(#Value("${application-description}")
// String appDesciption,
// #Value("${application-version}")
// String appVersion) {
// return new OpenAPI()
// .info(new Info()
// .title("CSA Read API - Swagger")
// .version(appVersion)
// .description(appDesciption)
// .termsOfService("http://swagger.io/terms/")
// .license(new License().
// name("Apache 2.0").
// url("http://springdoc.org")));
// }
// #Bean
// public OpenAPI customOpenAPI() {
// final String securitySchemeName = "bearerAuth";
// return new OpenAPI()
// .addSecurityItem(new SecurityRequirement().addList(securitySchemeName))
// .components(
// new Components()
// .addSecuritySchemes(securitySchemeName,
// new SecurityScheme()
// .name(securitySchemeName)
// .type(SecurityScheme.Type.HTTP)
// .scheme("bearer")
// .bearerFormat("JWT")
// )
// )
// .info(new Info().title(moduleName).version(apiVersion).description(moduleDescription));
// }
}
Inside my controller, I have this (It's just a code block of two endpoints) :
(...)
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
(...)
#RestController
#RequestMapping("/csa/api")
#Tag(name = "Users & Clan Controller", description = "This Endpoint manages Users and CSA Members")
public class ClanController extends Helper {
(...)
#PostMapping("/token")
#Operation(summary = "Request a token", description = "Return a new token" )
#ApiResponses(value = {
#ApiResponse(responseCode = "200", description = TOKEN_GENERATED_SUCCESSFULLY, content = #Content),
#ApiResponse(responseCode = "400", description = EMAIL_OR_PASSWORD_WRONG, content = #Content),
#ApiResponse(responseCode = "500", description = INTERNAL_SERVER_ERROR, content = #Content) })
public ResponseEntity<Object> token(#RequestParam("email") String email, #RequestParam("password") String password) {
try {
if(!isValidEmail(email))
return ResponseHandler.generateResponse(EMAIL_OR_PASSWORD_WRONG, HttpStatus.BAD_REQUEST, EMPTY);
var optionalUsers = usersRepository.findByEmailAndPassword(email, password);
if (!optionalUsers.isPresent())
return ResponseHandler.generateResponse(EMAIL_OR_PASSWORD_WRONG, HttpStatus.BAD_REQUEST, EMPTY);
var token = getJWTToken(email);
optionalUsers.get().setToken(token);
optionalUsers.get().setLastLogin(LocalDate.now());
usersRepository.save(optionalUsers.get());
return ResponseHandler.generateResponse(TOKEN_GENERATED_SUCCESSFULLY, HttpStatus.OK, new Token(token));
} catch (Exception e){
return ResponseHandler.generateResponse(INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR, e.getMessage());
}
}
#PostMapping("/updatePW")
#Operation(summary = "Update user password", description = "Return successful if all validations were OK." )
#ApiResponses(value = {
#ApiResponse(responseCode = "201", description = PASSWORD_CHANGED_SUCCESSFULLY, content = #Content),
#ApiResponse(responseCode = "400", description = EMAIL_OR_PASSWORD_WRONG, content = #Content),
#ApiResponse(responseCode = "406", description = NEW_PASSWORD_ERROR, content = #Content),
#ApiResponse(responseCode = "500", description = INTERNAL_SERVER_ERROR, content = #Content) })
#SecurityRequirement(name = "Bearer Authentication")
public ResponseEntity<Object> updatePassword(#RequestBody OldUser oldUser){
Users userSaved;
try {
if(!isValidEmail(oldUser.getEmail()))
return ResponseHandler.generateResponse(EMAIL_OR_PASSWORD_WRONG, HttpStatus.BAD_REQUEST, oldUser);
if(!oldUser.getNewPassword().isEmpty() && !isValidPassword(oldUser))
return ResponseHandler.generateResponse(NEW_PASSWORD_ERROR, HttpStatus.NOT_ACCEPTABLE, oldUser);
var init = usersRepository.findAll();
var user = usersRepository.findByEmailAndPassword(oldUser.getEmail(), oldUser.getOldPassword());
if(!user.isPresent())
return ResponseHandler.generateResponse(EMAIL_OR_PASSWORD_WRONG, HttpStatus.BAD_REQUEST, oldUser);
user.get().setPassword(oldUser.getNewPassword());
if(!oldUser.getNewPassword().isEmpty()){
userSaved = usersRepository.save(user.get());
} else {
userSaved = usersRepository.save(new Users(user.get()));
}
emailService.sendMail(userSaved, EMAIL_CHANGE_PASSWORD);
return ResponseHandler.generateResponse(PASSWORD_CHANGED_SUCCESSFULLY, HttpStatus.CREATED, userSaved);
} catch (Exception exception) {
return ResponseHandler.generateResponse(INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR, exception.getMessage());
}
}
As you can see in the first image.... For some reasons my "tags" of spring-doc are not working. I have no descriptions, error responses, any definition at all.
I'm working with SpringBoot 3.0.0 and spring-doc version 2.0.0, I have in my pom the following related imported artifacts to spring-doc: springdoc-openapi-starter-webmvc-ui, springdoc-openapi-starter-common, springdoc-openapi-starter-webflux-ui
I'm using also Java 17, and recently I started to use Dockerfile (This is the only way I have to make Swagger works without asking me credentials)
Please, any help with this will be very useful. I have been trying to figure out what to do for several weeks now, and the final users need Swagger implemented for easier access....
PS1: The response of api has this format:
{
"data": {
"name": "TEST NAME",
"email": "TEST.EMAIL#EMAIL.io",
"password": "TEST_PASSWORD",
"dateCreated": "2022-12-13",
"dateModified": "2022-12-13",
"lastLogin": "2022-12-13",
"token": "Bearer TOKEN",
"active": true
},
"message": "User Created Successfully",
"status": 201
}
Basically is:
{
"data" : Object
"message" : String
"status" : Int
}
Where data is the object created in most of cases. Message, just a typo message. status, HTTP Code with the status of operation...
I was trying to inject a global header to my suite of requests. While studying the solution I found the annotation #ApiImplicitParam that has #Target(value=METHOD)
example:
#DeleteMapping(value = "/token/{version}", produces = "application/json; charset=UTF-8")
#ApiOperation(value = "delete actual token", produces = "application/json", response = Application.class)
#ApiImplicitParams(
{
#ApiImplicitParam(name = "My-custom-header", required = true, paramType = "header",
dataType = "string", value = "custom header", defaultValue = "GOOD")
}
)
public Application deleteAuthenticationToken(
#ApiParam(required = true, value = "version", defaultValue = "v1") #PathVariable("version") String version,
HttpServletRequest request) {
here the docs
https://docs.swagger.io/swagger-core/current/apidocs/io/swagger/annotations/ApiImplicitParam.html
This means that this annotation can't be set to the resource and being automatically applied to all the methods.
I need that every call has this custom header, is there a way of doing it globally?
EDIT1: I added a HeaderParam in the swagger config but it doesn't work
private void inizializeSwagger(){
BeanConfig beanConfig = new BeanConfig();
beanConfig.setVersion(PropertiesConfig.getConfig().getString(PropertiesConst.P_SWAGGER_API_VERSION));
beanConfig.setSchemes(PropertiesConfig.getConfig().getStringArray(PropertiesConst.P_SWAGGER_PROTOCOL));
beanConfig.setHost(PropertiesConfig.getConfig().getString(PropertiesConst.P_SWAGGER_HOST));
beanConfig.setResourcePackage(PropertiesConfig.getConfig().getString(PropertiesConst.P_SWAGGER_RESOURCES_PACKAGE));
Swagger swagger = new Swagger();
swagger.securityDefinition("basic", new BasicAuthDefinition());
Parameter globalOperationParameter = new HeaderParameter();
globalOperationParameter.setName("System");
globalOperationParameter.setRequired(Boolean.TRUE);
globalOperationParameter.setDescription("definition of the calling system");
swagger.parameter("System", globalOperationParameter);
new SwaggerContextService().updateSwagger(swagger);
beanConfig.setScan(true);
}
EDIT2:
It adds the parameters but SwaggerUI 2.0 doesn't show it
EDIT3:
I had to change the swaggerUI library implementation:
in the cycle of // operations (row 4695) I added the following
for(name in spec.parameters) {
var actualParam = spec.parameters[name];
if(actualParam.in === 'header') {
parameters.unshift({"name":actualParam.name,
"in":actualParam.in,
"description":actualParam.description,
"required":actualParam.required,
"type":"string",
"default":""})
}
}
In other words I added the params I needed in the cycling operation.
I leave this ticket opened for better and cleaner solutions
I am trying to use swagger with java.
Using NSwag studio I am able to generate all my endpoints except one that returns a list of objects.
Here is my action in controller:
#ApiOperation(value = "getAll", nickname = "getAll", responseContainer = "List", response = DiakEntity.class)
#GetMapping("/api/diakok")
#ResponseBody
#PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_CLIENT')")
public List<DiakEntity> GetDiakok() throws Exception
{
ServiceObjectResponse<List<DiakEntity>> request = _diakService.getAll();
if(!request.getIsSuccess())
{
throw new Exception(request.getMessage());
}
return request.getObject();
}
I am using swagger-annotations 1.5.23, springfox-swagger-ui 2.9.2, springfox-swagger2 2.9.2.
If I test from Postman it works.
Also tried like this:
#ApiOperation(value = "getAll", nickname = "getAll")
#ApiResponse(code = 200, responseContainer="List", response=DiakEntity.class, message = "Gets all diak objects")
#GetMapping("/api/diakok")
#ResponseBody
#PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_CLIENT')")
public ResponseEntity<List<DiakEntity>> GetDiakok() throws Exception
{
ServiceObjectResponse<List<DiakEntity>> request = _diakService.getAll();
if(!request.getIsSuccess())
{
throw new Exception(request.getMessage());
}
return new ResponseEntity<>(request.getObject(), HttpStatus.OK);
}
thnx
Please try with the following annotation for swagger.
#ApiOperation(value = "getAll", nickname = "getAll")
#ApiResponse(code = 200, responseContainer="List", response=DiakEntity.class)
At the end I changed my action as below, and it started to work
#ApiOperation(value = "all", nickname = "all")
#PostMapping("/api/diak/all")
#ResponseBody
#PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_CLIENT')")
public List<DiakEntity> GetAll(#RequestBody #Valid RequestDiakByName data) throws Exception
{
ServiceObjectResponse<List<DiakEntity>> request = _diakService.getAll();
if(!request.getIsSuccess())
{
throw new Exception(request.getMessage());
}
return request.getObject();
}
I have the below code in Swagger,
#Path("/v1")
#ApiOperation(value = "POST - Some Value", nickname = "post-funtion", consumes = "application/json", produces = "text/html; charset=UTF-8", tags = {
"Some Controller" })
#ApiImplicitParams({
#ApiImplicitParam(name = "Authorization", paramType = "header", dataType = "string", format = "JWT", required = false, value = "A User Service JWT"),
#ApiImplicitParam(name = "Request", value = "Request Object", paramType = "body", dataType = "org.pkg.SomeRequest", required = true) })
#ApiResponses({
#ApiResponse(code = 200, message = "Value Added", response = SomeResponse.class) })
private Object retrieveByName(Request request, Response response)
{
return new RetrieveByNameRqstHandler(catalogService, request, response).handle();
}
The code is supposed to automatically generate default json request depending upon the datatype which in this case is "org.pkg.SomeRequest" but there is nothing generated. On the contrary if I change the "org.pkg.SomeRequest" with "org.pkg.SomeResponse" there is a default JSON generated for this. Can anybody help me please?
Consider both classes SomeRequest,SomeResponse have the same code.
This is the image where I use "org.pkg.SomeRequest" in the dataType
This is the image where I use "org.pkg.SomeResponse" in the dataType
According to this GitHub issue on Swagger core project, if you add the annotation #ApiImplicitParam should resolve your problem.
#ApiImplicitParams({
#ApiImplicitParam(
required = true,
dataType = "com.example.SomeObjectDto",
paramType = "body"
)
})
But normally if you just add the class on your method signature it'll work.
private Object retrieveByName(SomeObjectDto someObjectDto) {
someCode();
}
Also SomeObjectDto class should contain "get" methods for your variables like.
class SomeObjectDto {
private String info;
getInfo(){
return info;
}
}
Will produce the following JSon.
{ info: "string" }
ApiImplicitParam can map a parameter to a correct type, but the type must be detected by swagger, so must be a valid reference.
The only way I could make this working is by using additionalModels method.
Example in spring-boot:
configure swagger
import springfox.documentation.spring.web.plugins.Docket;
import com.fasterxml.classmate.TypeResolver;
...
#Bean
public Docket api(TypeResolver typeResolver) {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("your-group-rest-api")
.select()
.apis(RequestHandlerSelectors.basePackage("your.package"))
.paths(PathSelectors.any())
.build()
.additionalModels(typeResolver.resolve(YourModel.class))
.apiInfo(apiInfo());
}
controller
#ApiOperation...
#ApiImplicitParams(
#ApiImplicitParam(dataType = "YourModel", name = "requestJson", paramType = "body"))
#ApiResponses...
#RequestMapping...
public void yourMethod(#RequestBody String requestJson,...)
Of course, you could have an InputStream parameter for the request and map that to your model.