Custom Schema for Spring Boot 2 OpenAPI 3 Documentation - spring-boot

I have a requirement to integrate OpenAPI 3 documentation for my Spring Boot 2 project. We did not used modals/DTOs on controllers.
Here is the sample controller:
#RestController
#RequestMapping(value = "/pet")
public class PetController {
#RequestMapping(value = "/save", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public ResponseEntity<Map<String, Object>> savePet(
#RequestBody Map<String, Object> petObj, HttpServletRequest request)
throws Exception {
String petResponse = petDAO.savePet(petObj, request, true);
return new ResponseEntity<Map<String, Object>>(petResponse, HttpStatus.OK);
}
}
Request body:
{
"name":"Test",
"category":"school"
}
My response:
{
"petId":"1",
"petName":"Test",
"petCategory":"school",
"petStaus":"active"
}
I am not able to find a way to add the OpenAPI doc for my custom Map object. I want to add key, description, type, example(s) for each property in my Map manually.
Can anyone suggest how to do this?

This is the default behaviour of the springdoc-openapi library in order to ignore other injectable parameters supported by Spring MVC.
https://docs.spring.io/spring/docs/5.1.x/spring-framework-reference/web.html#mvc-ann-arguments
If you want to change this behaviour, you can just exlcude it as follow:
SpringDocUtils.getConfig().removeRequestWrapperToIgnore(Map.class);

Related

How to call Spring Boot RESt api using Spring MVC?

I have created REST api using Spring Boot.
So, that is the fragment of it:
#RestController
#RequestMapping("/api/employee")
public class EmployeeController {
#Autowired
private EmployeeService employeeService;
#GetMapping(value = "/all", produces = "application/json")
public ResponseEntity<List<Employee>> getAllEmployees() {
return ResponseEntity.ok(employeeService.findall());
}
Now, I would like to create more like MVC application part - simple view that shows all Employees using thymeleaf. (Just simple UI to use this app more convinient than sending curl requests)
#Controller
public class MainPageController {
#GetMapping("/employees")
public String showEmployees() {
// i don't know what to do here
return "employeesPage";
}
What is the appropriate way to do so? Is there a more simple way to do it?
Looking forward for your answers!
So you do exactly the same you did on your EmployeeController but instead of a JSON, you return a view.
Get your employes through EmployeeService and put them on a collection
Create your employee view under /templates folder (many tutorials of how to do it)
return this view with your collection of employees
Example:
#GetMapping(value = "employees")
public ModelAndView showEmployees() {
ModelAndView mav = new ModelAndView("employeesPage");
mav.addObject("employees", employeeService.findall());
return mav;
}
Check here for more detailed info:
https://www.thymeleaf.org/doc/articles/springmvcaccessdata.html

How to validate XML REST request in Springboot with Jaxb?

I thought this would be as easy as adding an annotation but I can't find a solution to this.
I have a simple endpoint that takes an XML request body:
#RequestMapping(value = "/import", method = RequestMethod.POST, consumes = MediaType.TEXT_XML_VALUE)
public ResponseEntity<Result> importReceipts(#Valid #RequestBody ImportRequest request) throws Exception {
Where ImportRequest is a JAXB class generated from an XSD. This works fine when a client sends a request, but if the request is not valid there is not error.
Please can anyone suggest the best way to validate this request body given the XSD?
Thanks
Thanks Alex,
I saw this response earlier but I looked again at my code and spotted the error :)
#Bean
public MarshallingHttpMessageConverter marshallingHttpMessageConverter()
{
MarshallingHttpMessageConverter marshallingHttpMessageConverter = new MarshallingHttpMessageConverter();
marshallingHttpMessageConverter.setMarshaller(jaxb2Marshaller());
marshallingHttpMessageConverter.setUnmarshaller(jaxb2Marshaller());
return marshallingHttpMessageConverter;
}
#Bean
public Jaxb2Marshaller jaxb2Marshaller()
{
Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
jaxb2Marshaller.setSchemas(new ClassPathResource("Import.xsd"), new ClassPathResource("BasicTypes.xsd"));
jaxb2Marshaller.setClassesToBeBound(Import.class);
return jaxb2Marshaller;
}
I had a typo but the main problem was I called jaxb2Marshaller.setSchemas more than once and the second call removed the first schemas.

How can I add textbox/textfield in my swagger page built in Spring boot?

I am trying to auto-generate the swagger page for a RestAPI in Spring Boot using annotations.
Code of Controller:
#RestController
#Api(value="UserManagementAPI", produces = MediaType.APPLICATION_JSON_VALUE)
public class UserManagementController {
#RequestMapping("/")
public String index() {
return "Greetings from Spring Boot!";
}
#ApiOperation(value="add a pro",consumes="application/json")
#RequestMapping(value = "/getUser", method = RequestMethod.GET, produces="application/json")
public static List<UserDetails> getUser(#PathVariable(name="id") String id) throws UserException
{
return UserHelper.getUserByEmail(id);
}
Application.java
#SpringBootApplication
#EnableSwagger2
#Configuration
#ComponentScan({ "userManagement"})
#EnableAutoConfiguration
public class Application {
#Bean
public Docket simpleDiffServiceApi() {
return new Docket(DocumentationType.SWAGGER_2).groupName("userManagement").apiInfo(apiInfo()).select()
.apis(RequestHandlerSelectors.any())
// .paths(PathSelectors.any())
// Will also include the basic error controllers by default
.paths(Predicates.not(PathSelectors.regex("/error")))
// Exclude basic error controllers
.build().pathMapping("/");
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder().title("Business Location Service")
.description("Spring Boot REST APIs for Business Location Service")
.contact(new Contact("EntSol-IoT (Niche Technology Delivery Group)", "http://somewebsite.com",
"some#mail.com"))
.version("1.0").build();
}
In the swagger page, I can see all my APIs. But there are more. It is showing all possible method type (e.g POST, GET, PUT etc.) though in Controller I only wrote GET method.
Another issue is that there is no Textbox in the swagger page under the API where I can search for the id. May be I am missing something. I have been trying to resolve it for past two days. But couldn't help myself. Thanks in advance.
I got the problem. Your getUser method is declared as static. Please remove static, for it to work.
public List<UserDetails> getUser(#PathVariable(name="id") String id) throws UserException { }

Postman Request to GET query with Multiple List<String> Parameters

I am trying to test a Multi Module Spring WebMVC API endpoint using Postman. This is Spring-MVC web app & using other frameworks too.
I want to know how to make a request to this URL.
My Controller File looks like this.
#Controller
#RequestMapping(value = "/xyz")
public class XyzWebController {
#CrossOrigin(origins = "*")
#RequestMapping(value = "", method = RequestMethod.GET)
#ResponseBody
public List<XyzChild> getProperties(#RequestParam XyzQueryDTO query) {
return childService.getAll(query);
}
...
}
XyzQueryDTO.java looks like this.
public class XyzQueryDTO {
List<String> properties;
List<String> applications;
public XyzQueryDTO() {
}
public XyzQueryDTO(List<String> properties,
List<String> applications) {
super();
this.properties = properties;
this.applications = applications;
}
...
}
Please assist me with the URL with which i can test this API.
Thanks in Advance.
It's more simple and correct to use RequestMethod.POST instead of RequestMethod.GET and #RequestBody instead of #RequestParam
#RequestMapping(value = "", method = RequestMethod.POST)
#ResponseBody
public List<XyzChild> getProperties(#RequestBody XyzQueryDTO query) {
return childService.getAll(query);
}
And you can use #RestController instead of #Controller and remove #ResponseBody
For data type conversion use jackson librairy.
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.8</version>
</dependency>
In Postman you can fill your XyzQueryDTO in the BODY as json

Spring 4 RestController - How to return jaxb object with ResponseEntity

I am using Spring #RESTController for my REST webservice. instead of returning the object of ModelAndView I am trying to return the object of ResponseEntity object in my rest method. for the Strgin type of response it is working ut when I am building ResponseEntity with a Jaxbobject it is giving me HTTP error 406
#RestController
#RequestMapping(value="/service")
public class MyController {
public #ResponseBody ResponseEntity<String> getDashBoardData() throws JAXBException {
// Some Operation
return new ResponseEntity<String>(myStringXML, responseHeaders, HttpStatus.OK);
}
}
Below is not working
#RestController
#RequestMapping(value="/service")
public class MyController {
public #ResponseBody ResponseEntity<MyJaxbClass> getDashBoardData() throws JAXBException {
// Some Operation
return new ResponseEntity<MyJaxbClass>(MyJaxbClassObject, HttpStatus.OK);
}
}
The #RestController annotation already implies the #ResponseBody annotation for all request handling methods, that is one of its purposes (it saves you from putting all those annotations there). So you can/should remove it.
Processing the return value of the method is done by a 'HandlerMethodReturnValueHandlerand the specific one which should handle this delegates to aHttpMessageConverter. It selects a specificHttpMessageConverterbased on the requested/supported response types for the current request and the support response types from theHandlerMethodReturnValueHandler`.
In general when using #EnableWebMvc or <mvc:annotation-driven /> everything should be setup automatically. The automatic setup does some detection on which libs are available (jaxb, json etc).
Based on the response code (406) you either have manually configured something wrong on the server side or the client doesn't support xml as a response type.

Resources