Skip to content

Commit 68732c2

Browse files
author
Malkeet Singh
committed
Added support for @JSONVIEW on ExceptionHandlers methods
1 parent c065481 commit 68732c2

File tree

8 files changed

+205
-0
lines changed

8 files changed

+205
-0
lines changed

springdoc-openapi-common/src/main/java/org/springdoc/core/GenericResponseService.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838

3939
import com.fasterxml.jackson.annotation.JsonView;
4040
import io.swagger.v3.core.util.AnnotationsUtils;
41+
import io.swagger.v3.core.util.ReflectionUtils;
4142
import io.swagger.v3.oas.models.Components;
4243
import io.swagger.v3.oas.models.Operation;
4344
import io.swagger.v3.oas.models.media.Content;
@@ -53,6 +54,7 @@
5354
import org.springframework.http.HttpStatus;
5455
import org.springframework.util.CollectionUtils;
5556
import org.springframework.web.bind.annotation.ExceptionHandler;
57+
import org.springframework.web.bind.annotation.RequestBody;
5658
import org.springframework.web.bind.annotation.RequestMapping;
5759
import org.springframework.web.bind.annotation.ResponseStatus;
5860
import org.springframework.web.method.ControllerAdviceBean;
@@ -165,6 +167,8 @@ public void buildGenericResponse(Components components, Map<String, Object> find
165167
ApiResponses apiResponsesOp = new ApiResponses();
166168
MethodAttributes methodAttributes = new MethodAttributes(methodProduces, springDocConfigProperties.getDefaultConsumesMediaType(),
167169
springDocConfigProperties.getDefaultProducesMediaType(), controllerAdviceInfoApiResponseMap);
170+
//calculate JsonView Annotation
171+
methodAttributes.setJsonViewAnnotation(AnnotatedElementUtils.findMergedAnnotation(method, JsonView.class));
168172
Map<String, ApiResponse> apiResponses = computeResponseFromDoc(components, methodParameter, apiResponsesOp, methodAttributes);
169173
buildGenericApiResponses(components, methodParameter, apiResponsesOp, methodAttributes);
170174
apiResponses.forEach(controllerAdviceInfoApiResponseMap::put);
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package test.org.springdoc.api.app157;
2+
3+
public class CustomException extends RuntimeException{
4+
public CustomException(String message) {
5+
super(message);
6+
}
7+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package test.org.springdoc.api.app157;
2+
3+
import com.fasterxml.jackson.annotation.JsonView;
4+
5+
public class FooBean {
6+
@JsonView(Views.View2.class)
7+
private String message;
8+
@JsonView(Views.View1.class)
9+
private int code;
10+
11+
public String getMessage() {
12+
return message;
13+
}
14+
15+
public void setMessage(String message) {
16+
this.message = message;
17+
}
18+
19+
public int getCode() {
20+
return code;
21+
}
22+
23+
public void setCode(int code) {
24+
this.code = code;
25+
}
26+
27+
public FooBean(String message, int code) {
28+
this.message = message;
29+
this.code = code;
30+
}
31+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package test.org.springdoc.api.app157;
2+
3+
import com.fasterxml.jackson.annotation.JsonView;
4+
import org.springframework.http.HttpStatus;
5+
import org.springframework.http.ResponseEntity;
6+
import org.springframework.web.bind.annotation.ControllerAdvice;
7+
import org.springframework.web.bind.annotation.ExceptionHandler;
8+
import org.springframework.web.bind.annotation.ResponseStatus;
9+
10+
@ControllerAdvice(assignableTypes = HelloController.class)
11+
public class FooErrorHandler {
12+
13+
@ExceptionHandler
14+
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
15+
@JsonView(Views.View1.class)
16+
public ResponseEntity<FooBean> storeAssignmentPublishingError(Exception e) {
17+
return new ResponseEntity<>(new FooBean("INTERNAL_SERVER_ERROR",500), HttpStatus.INTERNAL_SERVER_ERROR);
18+
}
19+
20+
@ExceptionHandler
21+
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
22+
@JsonView(Views.View2.class)
23+
public ResponseEntity<FooBean> storeAssignmentPublishingError(CustomException e) {
24+
return new ResponseEntity<>(new FooBean("BAD Request",400), HttpStatus.BAD_REQUEST);
25+
}
26+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package test.org.springdoc.api.app157;
2+
3+
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
4+
import io.swagger.v3.oas.annotations.info.Info;
5+
import io.swagger.v3.oas.annotations.tags.Tag;
6+
import org.springframework.web.bind.annotation.PostMapping;
7+
import org.springframework.web.bind.annotation.RequestBody;
8+
import org.springframework.web.bind.annotation.RequestMapping;
9+
import org.springframework.web.bind.annotation.RestController;
10+
11+
@RestController
12+
@RequestMapping("/api")
13+
@OpenAPIDefinition(info = @Info(title = "API Examples", version = "1.0"), tags = @Tag(name = "Operations"))
14+
public class HelloController {
15+
16+
@PostMapping("/foo")
17+
public String create(@RequestBody String foo) {
18+
return "foo";
19+
}
20+
}
21+
22+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package test.org.springdoc.api.app157;
2+
3+
import org.springframework.boot.autoconfigure.SpringBootApplication;
4+
import test.org.springdoc.api.AbstractSpringDocTest;
5+
6+
7+
public class SpringDocApp157Test extends AbstractSpringDocTest {
8+
9+
@SpringBootApplication
10+
static class SpringDocTestApp {}
11+
12+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package test.org.springdoc.api.app157;
2+
3+
public class Views {
4+
public static class View1 {
5+
}
6+
public static class View2 extends View1 {
7+
}
8+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
{
2+
"openapi":"3.0.1",
3+
"info":{
4+
"title":"API Examples",
5+
"version":"1.0"
6+
},
7+
"servers":[
8+
{
9+
"url":"http://localhost",
10+
"description":"Generated server url"
11+
}
12+
],
13+
"tags":[
14+
{
15+
"name":"Operations"
16+
}
17+
],
18+
"paths":{
19+
"/api/foo":{
20+
"post":{
21+
"tags":[
22+
"hello-controller"
23+
],
24+
"operationId":"create",
25+
"requestBody":{
26+
"content":{
27+
"application/json":{
28+
"schema":{
29+
"type":"string"
30+
}
31+
}
32+
},
33+
"required":true
34+
},
35+
"responses":{
36+
"500":{
37+
"description":"Internal Server Error",
38+
"content":{
39+
"*/*":{
40+
"schema":{
41+
"$ref":"#/components/schemas/FooBean_View1"
42+
}
43+
}
44+
}
45+
},
46+
"400":{
47+
"description":"Bad Request",
48+
"content":{
49+
"*/*":{
50+
"schema":{
51+
"$ref":"#/components/schemas/FooBean_View2"
52+
}
53+
}
54+
}
55+
},
56+
"200":{
57+
"description":"OK",
58+
"content":{
59+
"*/*":{
60+
"schema":{
61+
"type":"string"
62+
}
63+
}
64+
}
65+
}
66+
}
67+
}
68+
}
69+
},
70+
"components":{
71+
"schemas":{
72+
"FooBean_View1":{
73+
"type":"object",
74+
"properties":{
75+
"code":{
76+
"type":"integer",
77+
"format":"int32"
78+
}
79+
}
80+
},
81+
"FooBean_View2":{
82+
"type":"object",
83+
"properties":{
84+
"message":{
85+
"type":"string"
86+
},
87+
"code":{
88+
"type":"integer",
89+
"format":"int32"
90+
}
91+
}
92+
}
93+
}
94+
}
95+
}

0 commit comments

Comments
 (0)