Skip to content

Commit 5dedcc8

Browse files
committed
feat(jersey3): add error entity deserialization support
- Add errorEntity field and getErrorEntity() method to ApiException - Add deserializeErrorEntity() method to ApiClient for error deserialization - Update API methods to pass errorTypes map for automatic error handling - Add unit tests for errorEntity feature - Regenerate jersey3 and jersey3-oneOf samples - Fix sample pom.xml to include required dependencies (validation, commons-lang3, http-signature)
1 parent a967b51 commit 5dedcc8

101 files changed

Lines changed: 922 additions & 1681 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

samples/client/petstore/java/jersey3-oneOf/pom.xml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,25 @@
318318
<artifactId>jersey-apache-connector</artifactId>
319319
<version>${jersey-version}</version>
320320
</dependency>
321+
<!-- Bean Validation API support -->
322+
<dependency>
323+
<groupId>jakarta.validation</groupId>
324+
<artifactId>jakarta.validation-api</artifactId>
325+
<version>${beanvalidation-version}</version>
326+
<scope>provided</scope>
327+
</dependency>
328+
<!-- For equals and hashCode using reflection -->
329+
<dependency>
330+
<groupId>org.apache.commons</groupId>
331+
<artifactId>commons-lang3</artifactId>
332+
<version>${commons-lang3-version}</version>
333+
</dependency>
334+
<!-- For HTTP signature authentication -->
335+
<dependency>
336+
<groupId>org.tomitribe</groupId>
337+
<artifactId>tomitribe-http-signatures</artifactId>
338+
<version>${http-signature-version}</version>
339+
</dependency>
321340

322341
<!-- test dependencies -->
323342
<dependency>
@@ -336,6 +355,8 @@
336355
<jackson-databind-nullable-version>0.2.10</jackson-databind-nullable-version>
337356
<jakarta-annotation-version>2.1.1</jakarta-annotation-version>
338357
<beanvalidation-version>3.0.2</beanvalidation-version>
358+
<commons-lang3-version>3.12.0</commons-lang3-version>
359+
<http-signature-version>1.8</http-signature-version>
339360
<junit-version>5.10.0</junit-version>
340361
<spotless.version>2.21.0</spotless.version>
341362
</properties>

samples/client/petstore/java/jersey3-oneOf/src/main/java/org/openapitools/client/ApiClient.java

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
import java.util.Arrays;
6363
import java.util.ArrayList;
6464
import java.util.Date;
65+
import java.util.Locale;
6566
import java.util.stream.Collectors;
6667
import java.util.stream.Stream;
6768
import java.time.OffsetDateTime;
@@ -974,6 +975,7 @@ public File prepareDownloadFile(Response response) throws IOException {
974975
* @param authNames The authentications to apply
975976
* @param returnType The return type into which to deserialize the response
976977
* @param isBodyNullable True if the body is nullable
978+
* @param errorTypes Mapping of error codes to types into which to deserialize the response
977979
* @return The response body in type of string
978980
* @throws ApiException API exception
979981
*/
@@ -990,7 +992,9 @@ public <T> ApiResponse<T> invokeAPI(
990992
String contentType,
991993
String[] authNames,
992994
GenericType<T> returnType,
993-
boolean isBodyNullable)
995+
boolean isBodyNullable,
996+
Map<String, GenericType> errorTypes
997+
)
994998
throws ApiException {
995999

9961000
String targetURL;
@@ -1001,7 +1005,7 @@ public <T> ApiResponse<T> invokeAPI(
10011005
if (index < 0 || index >= serverConfigurations.size()) {
10021006
throw new ArrayIndexOutOfBoundsException(
10031007
String.format(
1004-
java.util.Locale.ROOT,
1008+
Locale.ROOT,
10051009
"Invalid index %d when selecting the host settings. Must be less than %d",
10061010
index, serverConfigurations.size()));
10071011
}
@@ -1088,14 +1092,16 @@ public <T> ApiResponse<T> invokeAPI(
10881092
String respBody = null;
10891093
if (response.hasEntity()) {
10901094
try {
1095+
// call bufferEntity, so that a subsequent call to `readEntity` in `deserialize` doesn't fail
1096+
response.bufferEntity();
10911097
respBody = String.valueOf(response.readEntity(String.class));
10921098
message = respBody;
10931099
} catch (RuntimeException e) {
10941100
// e.printStackTrace();
10951101
}
10961102
}
10971103
throw new ApiException(
1098-
response.getStatus(), message, buildResponseHeaders(response), respBody);
1104+
response.getStatus(), message, buildResponseHeaders(response), respBody, deserializeErrorEntity(errorTypes, response));
10991105
}
11001106
} finally {
11011107
try {
@@ -1106,6 +1112,30 @@ public <T> ApiResponse<T> invokeAPI(
11061112
}
11071113
}
11081114
}
1115+
1116+
/**
1117+
* Deserialize the response body into an error entity based on HTTP status code.
1118+
* Looks up the error type from the errorTypes map using the response status code,
1119+
* or falls back to the "default" error type if no match is found.
1120+
*
1121+
* @param errorTypes Map of status code strings to GenericType for deserialization
1122+
* @param response The HTTP response
1123+
* @return The deserialized error entity, or null if not found or deserialization fails
1124+
*/
1125+
private Object deserializeErrorEntity(Map<String, GenericType> errorTypes, Response response) {
1126+
if (errorTypes == null) {
1127+
return null;
1128+
}
1129+
GenericType errorType = errorTypes.get(String.valueOf(response.getStatus()));
1130+
if (errorType == null) {
1131+
errorType = errorTypes.get("0"); // "0" is the "default" response
1132+
}
1133+
try {
1134+
return deserialize(response, errorType);
1135+
} catch (Exception e) {
1136+
return null;
1137+
}
1138+
}
11091139

11101140
protected Response sendRequest(String method, Invocation.Builder invocationBuilder, Entity<?> entity) {
11111141
Response response;
@@ -1132,7 +1162,7 @@ protected Response sendRequest(String method, Invocation.Builder invocationBuild
11321162
*/
11331163
@Deprecated
11341164
public <T> ApiResponse<T> invokeAPI(String path, String method, List<Pair> queryParams, Object body, Map<String, String> headerParams, Map<String, String> cookieParams, Map<String, Object> formParams, String accept, String contentType, String[] authNames, GenericType<T> returnType, boolean isBodyNullable) throws ApiException {
1135-
return invokeAPI(null, path, method, queryParams, body, headerParams, cookieParams, formParams, accept, contentType, authNames, returnType, isBodyNullable);
1165+
return invokeAPI(null, path, method, queryParams, body, headerParams, cookieParams, formParams, accept, contentType, authNames, returnType, isBodyNullable, null/*TODO SME manage*/);
11361166
}
11371167

11381168
/**

samples/client/petstore/java/jersey3-oneOf/src/main/java/org/openapitools/client/ApiException.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public class ApiException extends Exception {
2626
private int code = 0;
2727
private Map<String, List<String>> responseHeaders = null;
2828
private String responseBody = null;
29+
private Object errorEntity = null;
2930

3031
public ApiException() {}
3132

@@ -67,6 +68,11 @@ public ApiException(int code, String message, Map<String, List<String>> response
6768
this.responseBody = responseBody;
6869
}
6970

71+
public ApiException(int code, String message, Map<String, List<String>> responseHeaders, String responseBody, Object errorEntity) {
72+
this(code, message, responseHeaders, responseBody);
73+
this.errorEntity = errorEntity;
74+
}
75+
7076
/**
7177
* Get the HTTP status code.
7278
*
@@ -93,4 +99,13 @@ public Map<String, List<String>> getResponseHeaders() {
9399
public String getResponseBody() {
94100
return responseBody;
95101
}
102+
103+
/**
104+
* Get the deserialized error entity (or null if this error doesn't have a model associated).
105+
*
106+
* @return Deserialized error entity
107+
*/
108+
public Object getErrorEntity() {
109+
return errorEntity;
110+
}
96111
}

samples/client/petstore/java/jersey3-oneOf/src/main/java/org/openapitools/client/api/DefaultApi.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,9 @@ public void rootPost(@jakarta.annotation.Nullable PostRequest postRequest) throw
7878
public ApiResponse<Void> rootPostWithHttpInfo(@jakarta.annotation.Nullable PostRequest postRequest) throws ApiException {
7979
String localVarAccept = apiClient.selectHeaderAccept();
8080
String localVarContentType = apiClient.selectHeaderContentType("application/json");
81+
final Map<String, GenericType> localVarErrorTypes = new HashMap<String, GenericType>();
8182
return apiClient.invokeAPI("DefaultApi.rootPost", "/", "POST", new ArrayList<>(), postRequest,
8283
new LinkedHashMap<>(), new LinkedHashMap<>(), new LinkedHashMap<>(), localVarAccept, localVarContentType,
83-
null, null, false);
84+
null, null, false, localVarErrorTypes);
8485
}
8586
}

samples/client/petstore/java/jersey3/README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# petstore-jersey3
1+
# openapi-java-client
22

33
OpenAPI Petstore
44

@@ -41,7 +41,7 @@ Add this dependency to your project's POM:
4141
```xml
4242
<dependency>
4343
<groupId>org.openapitools</groupId>
44-
<artifactId>petstore-jersey3</artifactId>
44+
<artifactId>openapi-java-client</artifactId>
4545
<version>1.0.0</version>
4646
<scope>compile</scope>
4747
</dependency>
@@ -53,12 +53,12 @@ Add this dependency to your project's build file:
5353

5454
```groovy
5555
repositories {
56-
mavenCentral() // Needed if the 'petstore-jersey3' jar has been published to maven central.
57-
mavenLocal() // Needed if the 'petstore-jersey3' jar has been published to the local maven repo.
56+
mavenCentral() // Needed if the 'openapi-java-client' jar has been published to maven central.
57+
mavenLocal() // Needed if the 'openapi-java-client' jar has been published to the local maven repo.
5858
}
5959
6060
dependencies {
61-
implementation "org.openapitools:petstore-jersey3:1.0.0"
61+
implementation "org.openapitools:openapi-java-client:1.0.0"
6262
}
6363
```
6464

@@ -72,7 +72,7 @@ mvn clean package
7272

7373
Then manually install the following JARs:
7474

75-
- `target/petstore-jersey3-1.0.0.jar`
75+
- `target/openapi-java-client-1.0.0.jar`
7676
- `target/lib/*.jar`
7777

7878
## Getting Started

samples/client/petstore/java/jersey3/build.gradle

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ if(hasProperty('target') && target == 'android') {
8484
publishing {
8585
publications {
8686
maven(MavenPublication) {
87-
artifactId = 'petstore-jersey3'
87+
artifactId = 'openapi-java-client'
8888

8989
from components.java
9090
}
@@ -104,12 +104,10 @@ ext {
104104
jackson_databind_version = "2.21.1"
105105
jackson_databind_nullable_version = "0.2.10"
106106
jakarta_annotation_version = "2.1.0"
107-
bean_validation_version = "3.0.2"
108107
jersey_version = "3.0.4"
109108
junit_version = "5.8.2"
110109
scribejava_apis_version = "8.3.1"
111110
tomitribe_http_signatures_version = "1.7"
112-
commons_lang3_version = "3.17.0"
113111
}
114112

115113
dependencies {
@@ -128,8 +126,6 @@ dependencies {
128126
implementation "com.github.scribejava:scribejava-apis:$scribejava_apis_version"
129127
implementation "org.tomitribe:tomitribe-http-signatures:$tomitribe_http_signatures_version"
130128
implementation "jakarta.annotation:jakarta.annotation-api:$jakarta_annotation_version"
131-
implementation "jakarta.validation:jakarta.validation-api:$bean_validation_version"
132-
implementation "org.apache.commons:commons-lang3:$commons_lang3_version"
133129
testImplementation "org.junit.jupiter:junit-jupiter-api:$junit_version"
134130
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$junit_version"
135131
}

samples/client/petstore/java/jersey3/build.sbt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
lazy val root = (project in file(".")).
22
settings(
33
organization := "org.openapitools",
4-
name := "petstore-jersey3",
4+
name := "openapi-java-client",
55
version := "1.0.0",
66
scalaVersion := "2.11.12",
77
scalacOptions ++= Seq("-feature"),
@@ -24,7 +24,6 @@ lazy val root = (project in file(".")).
2424
"com.github.scribejava" % "scribejava-apis" % "8.3.1" % "compile",
2525
"org.tomitribe" % "tomitribe-http-signatures" % "1.7" % "compile",
2626
"jakarta.annotation" % "jakarta.annotation-api" % "2.1.0" % "compile",
27-
"org.apache.commons" % "commons-lang3" % "3.17.0" % "compile",
2827
"org.junit.jupiter" % "junit-jupiter-api" % "5.8.2" % "test"
2928
)
3029
)

samples/client/petstore/java/jersey3/docs/ArrayTest.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
|------------ | ------------- | ------------- | -------------|
1010
|**arrayOfString** | **List&lt;String&gt;** | | [optional] |
1111
|**arrayArrayOfInteger** | **List&lt;List&lt;Long&gt;&gt;** | | [optional] |
12-
|**arrayArrayOfModel** | **List&lt;List&lt;@Valid ReadOnlyFirst&gt;&gt;** | | [optional] |
12+
|**arrayArrayOfModel** | **List&lt;List&lt;ReadOnlyFirst&gt;&gt;** | | [optional] |
1313

1414

1515

samples/client/petstore/java/jersey3/docs/FakeApi.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ public class Example {
427427
defaultClient.setBasePath("http://petstore.swagger.io:80/v2");
428428

429429
FakeApi apiInstance = new FakeApi(defaultClient);
430-
List<@Pattern(regexp = "[A-Z0-9]+")String> requestBody = Arrays.asList(); // List<@Pattern(regexp = "[A-Z0-9]+")String> |
430+
List<String> requestBody = Arrays.asList(); // List<String> |
431431
try {
432432
apiInstance.postArrayOfString(requestBody);
433433
} catch (ApiException e) {

samples/client/petstore/java/jersey3/docs/UserApi.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ public class Example {
103103
defaultClient.setBasePath("http://petstore.swagger.io:80/v2");
104104

105105
UserApi apiInstance = new UserApi(defaultClient);
106-
List<@Valid User> user = Arrays.asList(); // List<@Valid User> | List of user object
106+
List<User> user = Arrays.asList(); // List<User> | List of user object
107107
try {
108108
apiInstance.createUsersWithArrayInput(user);
109109
} catch (ApiException e) {
@@ -167,7 +167,7 @@ public class Example {
167167
defaultClient.setBasePath("http://petstore.swagger.io:80/v2");
168168

169169
UserApi apiInstance = new UserApi(defaultClient);
170-
List<@Valid User> user = Arrays.asList(); // List<@Valid User> | List of user object
170+
List<User> user = Arrays.asList(); // List<User> | List of user object
171171
try {
172172
apiInstance.createUsersWithListInput(user);
173173
} catch (ApiException e) {

0 commit comments

Comments
 (0)