Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/samples-java-client-jdk11.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ jobs:
- samples/client/petstore/java/microprofile-rest-client-3.0-jackson-mutiny
- samples/client/petstore/java/microprofile-rest-client-3.0-jackson-with-xml
- samples/client/petstore/java/microprofile-rest-client-3.0-mutiny
- samples/client/petstore/java/microprofile-rest-client-3.0-jspecify
- samples/client/petstore/java/microprofile-rest-client-with-useSingleRequestParameter
- samples/client/petstore/java/microprofile-oneof-interface
- samples/client/petstore/java/apache-httpclient
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/samples-jdk17.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ on:
- samples/server/petstore/java-helidon-server/v3/se/**
- samples/server/petstore/jaxrs-spec-sealed/**
- samples/server/petstore/jaxrs-spec/quarkus-security/**
- samples/server/petstore/jaxrs-spec-quarkus-jspecify/**
pull_request:
paths:
# clients
Expand All @@ -48,6 +49,7 @@ on:
- samples/server/petstore/java-helidon-server/v3/se/**
- samples/server/petstore/jaxrs-spec-sealed/**
- samples/server/petstore/jaxrs-spec/quarkus-security/**
- samples/server/petstore/jaxrs-spec-quarkus-jspecify/**
jobs:
build:
name: Build with JDK17
Expand Down Expand Up @@ -78,6 +80,7 @@ jobs:
- samples/server/petstore/java-helidon-server/v3/se
- samples/server/petstore/jaxrs-spec-sealed
- samples/server/petstore/jaxrs-spec/quarkus-security
- samples/server/petstore/jaxrs-spec-quarkus-jspecify
steps:
- uses: actions/checkout@v7
- uses: actions/setup-java@v6.0.0
Expand Down
17 changes: 17 additions & 0 deletions bin/configs/java-microprofile-rest-client-3.0-jspecify.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
generatorName: java
outputDir: samples/client/petstore/java/microprofile-rest-client-3.0-jspecify
library: microprofile
inputSpec: modules/openapi-generator/src/test/resources/3_0/java/jspecify.yaml
templateDir: modules/openapi-generator/src/main/resources/Java
validateSpec: false
additionalProperties:
serializationLibrary: jackson
artifactId: microprofile-rest-client-3-jspecify
configKey: petstore
microprofileRestClientVersion: "3.0"
hideGenerationTimestamp: true
useReflectionEqualsHashCode: true
openApiNullable: "false"
useJspecify: true
typeMappings:
BigDecimal: java.math.BigDecimal
16 changes: 16 additions & 0 deletions bin/configs/jaxrs-spec-quarkus-jspecify.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
generatorName: jaxrs-spec
outputDir: samples/server/petstore/jaxrs-spec-quarkus-jspecify
inputSpec: modules/openapi-generator/src/test/resources/3_0/java/jspecify.yaml
templateDir: modules/openapi-generator/src/main/resources/JavaJaxRS/spec
validateSpec: false
additionalProperties:
artifactId: jaxrs-spec-quarkus-jspecify
library: "quarkus"
hideGenerationTimestamp: "true"
interfaceOnly: "true"
useJakartaEe: "true"
useJspecify: "true"
openApiNullable: "false"
dateLibrary: "java8"
typeMappings:
BigDecimal: java.math.BigDecimal
2 changes: 1 addition & 1 deletion docs/generators/java-microprofile.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useGzipFeature|Send gzip-encoded requests| |false|
|useJackson3|Use Jackson 3 instead of Jackson 2. Supported for 'native', 'apache-httpclient', and 'jersey3' libraries (requires Java 17+) and for Spring 'resttemplate', 'webclient', and 'restclient' libraries (require useSpringBoot4=true).| |false|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useJspecify|Use Jspecify for null checks. Only supported for [native, restclient, resttemplate, webclient]| |false|
|useJspecify|Use Jspecify for null checks. Only supported for [microprofile, native, restclient, resttemplate, webclient]| |false|
|useOneOfDiscriminatorLookup|Use the discriminator's mapping in oneOf to speed up the model lookup. IMPORTANT: Validation (e.g. one and only one match in oneOf's schemas) will be skipped. Only jersey2, jersey3, native, okhttp-gson support this option.| |false|
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
|usePlayWS|Use Play! Async HTTP client (Play WS API)| |false|
Expand Down
2 changes: 1 addition & 1 deletion docs/generators/java.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useGzipFeature|Send gzip-encoded requests| |false|
|useJackson3|Use Jackson 3 instead of Jackson 2. Supported for 'native', 'apache-httpclient', and 'jersey3' libraries (requires Java 17+) and for Spring 'resttemplate', 'webclient', and 'restclient' libraries (require useSpringBoot4=true).| |false|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useJspecify|Use Jspecify for null checks. Only supported for [native, restclient, resttemplate, webclient]| |false|
|useJspecify|Use Jspecify for null checks. Only supported for [microprofile, native, restclient, resttemplate, webclient]| |false|
|useOneOfDiscriminatorLookup|Use the discriminator's mapping in oneOf to speed up the model lookup. IMPORTANT: Validation (e.g. one and only one match in oneOf's schemas) will be skipped. Only jersey2, jersey3, native, okhttp-gson support this option.| |false|
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
|usePlayWS|Use Play! Async HTTP client (Play WS API)| |false|
Expand Down
1 change: 1 addition & 0 deletions docs/generators/jaxrs-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useEnumCaseInsensitive|Use `equalsIgnoreCase` when String for enum comparison| |false|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useJakartaSecurityAnnotations|Whether to generate Jakarta security annotations (@RolesAllowed, @PermitAll). Requires useJakartaEe=true. Currently only supported when library is set to quarkus.| |false|
|useJspecify|Use JSpecify for null checks: @NullMarked package-info and @Nullable on optional properties and parameters.| |false|
|useMicroProfileOpenAPIAnnotations|Whether to generate Microprofile OpenAPI annotations. Only valid when library is set to quarkus.| |false|
|useMutiny|Whether to use Smallrye Mutiny instead of CompletionStage for asynchronous computation. Only valid when library is set to quarkus.| |false|
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen

@Setter protected int maxAttemptsForRetry = 1;
@Setter protected long waitTimeMillis = 10l;
private final Set<String> JSPECIFY_SUPPORTED_LIBRARIES = new TreeSet<>(Arrays.asList(RESTCLIENT, WEBCLIENT, NATIVE, RESTTEMPLATE));
private final Set<String> JSPECIFY_SUPPORTED_LIBRARIES = new TreeSet<>(Arrays.asList(MICROPROFILE, RESTCLIENT, WEBCLIENT, NATIVE, RESTTEMPLATE));

private static class MpRestClientVersion {
public final String rootPackage;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ public JavaJAXRSCXFCDIServerCodegen() {
embeddedTemplateDir = templateDir = JAXRS_TEMPLATE_DIRECTORY_NAME + File.separator + "cxf-cdi";

removeOption(JavaJAXRSSpecServerCodegen.GENERATE_JSON_CREATOR);
// jspecify support lives in the JavaJaxRS/spec templates; this generator uses its own
// cxf-cdi template directory, so the option would be advertised but have no effect.
removeOption(USE_JSPECIFY);
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
}

@Override
Expand All @@ -73,6 +76,13 @@ public String getName() {

@Override
public void processOpts() {
// Force jspecify off before super.processOpts(), which is where applyJspecify() runs.
// removeOption() only hides the option from the advertised CLI list; the flag can still
// arrive through additionalProperties (a config file, or -p useJspecify=true) and would
// then emit imports and package-info for templates this generator does not have.
additionalProperties.remove(USE_JSPECIFY);
setUseJspecify(false);

super.processOpts();

supportingFiles.clear(); // Don't need extra files provided by AbstractJAX-RS & Java Codegen
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ public JavaJAXRSSpecServerCodegen() {
cliOptions.add(CliOption.newBoolean(GENERATE_JSON_CREATOR, "Whether to generate @JsonCreator constructor for required properties.", generateJsonCreator));
cliOptions.add(CliOption.newBoolean(USE_ENUM_CASE_INSENSITIVE, "Use `equalsIgnoreCase` when String for enum comparison", useEnumCaseInsensitive));
cliOptions.add(CliOption.newBoolean(USE_SEALED, "Whether to generate sealed model interfaces and classes.", useSealed));
cliOptions.add(CliOption.newBoolean(USE_JSPECIFY, "Use JSpecify for null checks: @NullMarked package-info and @Nullable on optional properties and parameters.", useJspecify));
}

@Override
Expand Down Expand Up @@ -255,6 +256,11 @@ public void processOpts() {
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")
.doNotOverwrite());

// after the clear() above, which would otherwise drop the @NullMarked package-info files
if (useJspecify) {
applyJspecify();
}

if ((!interfaceOnly) || generateRootResources) {
supportingFiles.add(new SupportingFile("RestResourceRoot.mustache",
(sourceFolder + '/' + invokerPackage).replace(".", "/"), "RestResourceRoot.java")
Expand Down Expand Up @@ -348,6 +354,10 @@ public CodegenModel fromModel(String name, Schema model) {
codegenModel.imports.remove("JsonProperty");
codegenModel.imports.remove("JsonTypeName");
}
if (useJspecify) {
codegenModel.imports.add("Nullable");
}

return codegenModel;
}

Expand Down Expand Up @@ -481,6 +491,18 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation
if (QUARKUS_LIBRARY.equals(getLibrary()) && useJakartaSecurityAnnotations) {
jakartaSecurityAnnotationProcessor.applyTo(op, operation, openAPI);
}
if (useJspecify) {
addNullableImportForOperation(op);
}
return op;
}

@Override
protected void applyJspecify() {
super.applyJspecify();
// nullable_var_annotations.mustache emits @{{javaxPackage}}.annotation.Nullable; the lambda
// finds that and re-injects a bare @Nullable in type-use position, so tell it what to look for.
jSpecifyNullableLambda.setNullableAnnotation("@" + additionalProperties.get(JAVAX_PACKAGE) + ".annotation.Nullable");
}

}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{{#isBodyParam}}{{#useBeanValidation}}@Valid {{/useBeanValidation}}{{{dataType}}} {{paramName}}{{/isBodyParam}}
{{#isBodyParam}}{{#useBeanValidation}}@Valid {{/useBeanValidation}}{{#useJspecify}}{{>nullable_var_annotations}}{{/useJspecify}}{{>nullableDataType}} {{paramName}}{{/isBodyParam}}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{{#isCookieParam}}@CookieParam("{{baseName}}") {{#useBeanValidation}}{{>beanValidationCookieParams}}{{/useBeanValidation}} {{{dataType}}} {{paramName}}{{/isCookieParam}}
{{#isCookieParam}}@CookieParam("{{baseName}}") {{#useBeanValidation}}{{>beanValidationCookieParams}}{{/useBeanValidation}} {{#useJspecify}}{{>nullable_var_annotations}}{{/useJspecify}}{{>nullableDataType}} {{paramName}}{{/isCookieParam}}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{{#isFormParam}}{{^isFile}}{{#required}}{{#useBeanValidation}}@NotNull {{/useBeanValidation}}{{/required}}@FormParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/isFile}}{{#isFile}} {{#required}}{{#useBeanValidation}}@NotNull {{/useBeanValidation}}{{/required}}@FormParam("{{baseName}}") {{^isArray}}File{{/isArray}}{{#isArray}}List<File>{{/isArray}} {{paramName}}Detail{{/isFile}}{{/isFormParam}}
{{#isFormParam}}{{^isFile}}{{#required}}{{#useBeanValidation}}@NotNull {{/useBeanValidation}}{{/required}}@FormParam("{{baseName}}") {{#useJspecify}}{{>nullable_var_annotations}}{{/useJspecify}}{{>nullableDataType}} {{paramName}}{{/isFile}}{{#isFile}} {{#required}}{{#useBeanValidation}}@NotNull {{/useBeanValidation}}{{/required}}@FormParam("{{baseName}}") {{#useJspecify}}{{>nullable_var_annotations}}{{/useJspecify}}{{#lambda.jSpecifyDatatype}}{{^isArray}}File{{/isArray}}{{#isArray}}List<File>{{/isArray}}{{/lambda.jSpecifyDatatype}} {{paramName}}Detail{{/isFile}}{{/isFormParam}}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{{#isHeaderParam}}@HeaderParam("{{baseName}}") {{#useBeanValidation}}{{>beanValidationHeaderParams}}{{/useBeanValidation}} {{{dataType}}} {{paramName}}{{/isHeaderParam}}
{{#isHeaderParam}}@HeaderParam("{{baseName}}") {{#useBeanValidation}}{{>beanValidationHeaderParams}}{{/useBeanValidation}} {{#useJspecify}}{{>nullable_var_annotations}}{{/useJspecify}}{{>nullableDataType}} {{paramName}}{{/isHeaderParam}}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{{#isPathParam}}@PathParam("{{baseName}}"){{#useBeanValidation}}{{>beanValidationPathParams}}{{/useBeanValidation}} {{{dataType}}} {{paramName}}{{/isPathParam}}
{{#isPathParam}}@PathParam("{{baseName}}"){{#useBeanValidation}}{{>beanValidationPathParams}}{{/useBeanValidation}} {{#useJspecify}}{{>nullable_var_annotations}}{{/useJspecify}}{{>nullableDataType}} {{paramName}}{{/isPathParam}}
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ public {{>sealed}}class {{classname}} {{#parent}}extends {{{.}}}{{/parent}}{{#ve
{{{.}}}
{{/vendorExtensions.x-field-extra-annotation}}
{{#isContainer}}
protected {{{datatypeWithEnum}}} {{name}}{{#required}}{{#defaultValue}} = {{{.}}}{{/defaultValue}}{{^defaultValue}} = null{{/defaultValue}}{{/required}}{{^required}} = null{{/required}};
{{#useJspecify}}{{>nullable_var_annotations}}{{/useJspecify}}protected {{>nullableDatatypeWithEnum}} {{name}}{{#required}}{{#defaultValue}} = {{{.}}}{{/defaultValue}}{{^defaultValue}} = null{{/defaultValue}}{{/required}}{{^required}} = null{{/required}};
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
{{/isContainer}}
{{^isContainer}}
protected {{{datatypeWithEnum}}} {{name}}{{#defaultValue}} = {{{.}}}{{/defaultValue}};
{{#useJspecify}}{{>nullable_var_annotations}}{{/useJspecify}}protected {{>nullableDatatypeWithEnum}} {{name}}{{#defaultValue}} = {{{.}}}{{/defaultValue}};
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
{{/isContainer}}
{{/vars}}
{{>additional_properties}}
Expand All @@ -67,7 +67,7 @@ public {{>sealed}}class {{classname}} {{#parent}}extends {{{.}}}{{/parent}}{{#ve
{{#jsonb}}@JsonbCreator{{/jsonb}}{{#jackson}}@JsonCreator{{/jackson}}
public {{classname}}(
{{#readOnlyVars}}
{{#jsonb}}@JsonbProperty(value = "{{baseName}}"{{^required}}, nillable = true{{/required}}){{/jsonb}}{{#jackson}}@JsonProperty(value = JSON_PROPERTY_{{nameInSnakeCase}}{{#required}}, required = true{{/required}}){{/jackson}} {{{datatypeWithEnum}}} {{name}}{{^-last}}, {{/-last}}
{{#jsonb}}@JsonbProperty(value = "{{baseName}}"{{^required}}, nillable = true{{/required}}){{/jsonb}}{{#jackson}}@JsonProperty(value = JSON_PROPERTY_{{nameInSnakeCase}}{{#required}}, required = true{{/required}}){{/jackson}} {{#useJspecify}}{{>nullable_var_annotations}}{{/useJspecify}}{{>nullableDatatypeWithEnum}} {{name}}{{^-last}}, {{/-last}}
{{/readOnlyVars}}
) {
{{#readOnlyVars}}
Expand Down Expand Up @@ -100,18 +100,18 @@ public {{>sealed}}class {{classname}} {{#parent}}extends {{{.}}}{{/parent}}{{#ve
{{#vendorExtensions.x-extra-annotation}}
{{{vendorExtensions.x-extra-annotation}}}
{{/vendorExtensions.x-extra-annotation}}
{{#useBeanValidation}}{{>beanValidation}}{{/useBeanValidation}}{{#jackson}}{{> jackson_annotations}}{{/jackson}} {{#withXml}}{{#isEnum}}{{^isArray}}{{^isMap}} public {{dataType}} {{getter}}() {
{{#useBeanValidation}}{{>beanValidation}}{{/useBeanValidation}}{{#jackson}}{{> jackson_annotations}}{{/jackson}} {{#withXml}}{{#isEnum}}{{^isArray}}{{^isMap}} public {{#useJspecify}}{{>nullable_var_annotations}}{{/useJspecify}}{{#lambda.jSpecifyDatatype}}{{{dataType}}}{{/lambda.jSpecifyDatatype}} {{getter}}() {
if ({{name}} == null) {
return null;
}
return {{name}}.value();
}{{/isMap}}{{/isArray}}{{/isEnum}}{{/withXml}}{{^withXml}}{{#isEnum}}{{^isArray}}{{^isMap}}public {{datatypeWithEnum}} {{getter}}() {
}{{/isMap}}{{/isArray}}{{/isEnum}}{{/withXml}}{{^withXml}}{{#isEnum}}{{^isArray}}{{^isMap}}public {{#useJspecify}}{{>nullable_var_annotations}}{{/useJspecify}}{{>nullableDatatypeWithEnum}} {{getter}}() {
return {{name}};
}{{/isMap}}{{/isArray}}{{/isEnum}}{{/withXml}}{{#isEnum}}{{#isArray}}public {{{datatypeWithEnum}}} {{getter}}() {
}{{/isMap}}{{/isArray}}{{/isEnum}}{{/withXml}}{{#isEnum}}{{#isArray}}public {{#useJspecify}}{{>nullable_var_annotations}}{{/useJspecify}}{{>nullableDatatypeWithEnum}} {{getter}}() {
return {{name}};
}{{/isArray}}{{/isEnum}}{{#isEnum}}{{#isMap}}public {{{datatypeWithEnum}}} {{getter}}() {
}{{/isArray}}{{/isEnum}}{{#isEnum}}{{#isMap}}public {{#useJspecify}}{{>nullable_var_annotations}}{{/useJspecify}}{{>nullableDatatypeWithEnum}} {{getter}}() {
return {{name}};
}{{/isMap}}{{/isEnum}}{{^isEnum}}public {{{datatypeWithEnum}}} {{getter}}() {
}{{/isMap}}{{/isEnum}}{{^isEnum}}public {{#useJspecify}}{{>nullable_var_annotations}}{{/useJspecify}}{{>nullableDatatypeWithEnum}} {{getter}}() {
return {{name}};
}{{/isEnum}}

Expand All @@ -120,11 +120,11 @@ public {{>sealed}}class {{classname}} {{#parent}}extends {{{.}}}{{/parent}}{{#ve
* Set {{name}}
*/
{{#vendorExtensions.x-setter-extra-annotation}} {{{vendorExtensions.x-setter-extra-annotation}}}
{{/vendorExtensions.x-setter-extra-annotation}}{{#jackson}}{{> jackson_annotations}}{{/jackson}} public void {{setter}}({{{datatypeWithEnum}}} {{name}}) {
{{/vendorExtensions.x-setter-extra-annotation}}{{#jackson}}{{> jackson_annotations}}{{/jackson}} public void {{setter}}({{#useJspecify}}{{>nullable_var_annotations}}{{/useJspecify}}{{>nullableDatatypeWithEnum}} {{name}}) {
this.{{name}} = {{name}};
}

public {{classname}} {{name}}({{{datatypeWithEnum}}} {{name}}) {
public {{classname}} {{name}}({{#useJspecify}}{{>nullable_var_annotations}}{{/useJspecify}}{{>nullableDatatypeWithEnum}} {{name}}) {
this.{{name}} = {{name}};
return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,13 @@
<version>${commons.lang3.version}</version>
</dependency>
{{/useReflectionEqualsHashCode}}
{{#useJspecify}}
<dependency>
<groupId>org.jspecify</groupId>
<artifactId>jspecify</artifactId>
<version>1.0.0</version>
</dependency>
{{/useJspecify}}
</dependencies>
<repositories>
<repository>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,13 @@
<version>${commons.lang3.version}</version>
</dependency>
{{/useReflectionEqualsHashCode}}
{{#useJspecify}}
<dependency>
<groupId>org.jspecify</groupId>
<artifactId>jspecify</artifactId>
<version>1.0.0</version>
</dependency>
{{/useJspecify}}
</dependencies>
<repositories>
<repository>
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{{#isQueryParam}}@QueryParam("{{baseName}}"){{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}} {{^isContainer}}{{#defaultValue}}@DefaultValue("{{{.}}}") {{/defaultValue}}{{/isContainer}}{{{dataType}}} {{paramName}}{{/isQueryParam}}
{{#isQueryParam}}@QueryParam("{{baseName}}"){{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}} {{^isContainer}}{{#defaultValue}}@DefaultValue("{{{.}}}") {{/defaultValue}}{{/isContainer}}{{#useJspecify}}{{>nullable_var_annotations}}{{/useJspecify}}{{>nullableDataType}} {{paramName}}{{/isQueryParam}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@org.jspecify.annotations.NullMarked
package {{apiPackage}};
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{{#isBodyParam}}{{#isDeprecated}}@Deprecated {{/isDeprecated}}{{#useBeanValidation}}@Valid {{#required}}{{^isNullable}}@NotNull {{/isNullable}}{{/required}}{{/useBeanValidation}}{{{dataType}}} {{paramName}}{{/isBodyParam}}
{{#isBodyParam}}{{#isDeprecated}}@Deprecated {{/isDeprecated}}{{#useBeanValidation}}@Valid {{#required}}{{^isNullable}}@NotNull {{/isNullable}}{{/required}}{{/useBeanValidation}}{{#useJspecify}}{{>nullable_var_annotations}}{{/useJspecify}}{{>nullableDataType}} {{paramName}}{{/isBodyParam}}
Loading
Loading