SpringDoc app-doc.yaml don't show the swagger doc - spring-boot

I have a API with swagger. Endpoint example:
#ApiOperation(value = "Returns a list of Pix transactions.",httpMethod = "POST",response = DResponse.class)
#PostMapping("/transactions")
public ResponseEntity<DResponse> getTransactions(#RequestBody PixTransactionRequest pixTransactionRequest) {
return ResponseEntity.ok(pixService.getTransactionsPix(pixTransactionRequest));
}
My swagger page show me all the info correctly:
But when I tryed generate a yaml doc this description don't works. I dont see the description of the endpoint (Returns a list of Pix transactions.) in my yaml doc:
/api/pix/transactions:
post:
tags:
- pix-controller
operationId: getTransactions
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PixTransactionRequest'

The issue is because you're using Swagger 1.x annotation #ApiOperation with Springdoc while the supported Swagger specification is Swagger 2.x (aka the OpenAPI Specification)
As for the solution to this, use the #Operation annotation to get the expected output.
Note that it's not possible to speicify the return type with the new annotation. Thus to achieve the same functionality you need to re-write your swagger annotation as below
// Describe the Operation
#Operation(summary = "Returns a list of Pix transactions.", description = "Any long description about the endpoint that you want")
// Describe the Response of the Operation. Use the below way if only 1 type of response will be returned by the endpoint
#ApiResponse(responseCode = "200", description = "OK", content = {#Content(mediaType = "application/json", schema = #Schema(DResponse.class))})
If the endpoint can return more than 1 response, use the below approach
#ApiResponses(value = {
#ApiResponse(responseCode = "201", description = "Created", content = {#Content(mediaType = "application/json", schema = #Schema(DResponse.class))}),
#ApiResponse(responseCode = "500", description = "Internal Server Error", content = {#Content(mediaType = "application/json", schema = #Schema(implementation = MyErrorResponse.class))})
})
And there's no alternative for httpMethod = "POST" of the #ApiOperation. Swagger 2.x infers the type of operation by the type of request annotation placed on the method, i.e #PostMapping will give a POST request and so on. This rule still holds when you use #RequestMapping to specify the type of request method.

Related

Chilkat2-Python - HTTP Form Authentication problem

Trying to convert from python request to chilkat2.HttpRequest :
import requests
data = {"username": "user","password": "pass","remember": "on"}
sign_in_url = 'https://www.tradingview.com/accounts/signin/'
signin_headers = {'Referer': 'https://www.tradingview.com'}
response = requests.post(url=sign_in_url, data=data, headers=signin_headers)
token = response.json()['user']['auth_token']
P.S. Cause no right username and password - will return status_code:200
b'{"error":"Invalid username or password","code":"invalid_credentials"}'
I have this:
http = chilkat2.Http()
req = chilkat2.HttpRequest()
req.AddParam("username","user")
req.AddParam("password","pass")
req.AddParam("remember","on")
req.Path = '/accounts/signin/'
req.HttpVerb = "POST"
http.FollowRedirects = True
http.SendCookies = True
http.SaveCookies = True
http.CookieDir = "memory"
resp = http.SynchronousRequest('www.tradingview.com',443,True,req)
print(http.LastErrorText)
But response - statusCode: 403 Forbidden
What am I doing wrong?
See the tradingview.com API documentation: https://www.tradingview.com/rest-api-spec/#section/Authentication
You can see that an application/x-www-form-urlencoded POST is required.
It's easy to do with Chilkat. See this documentation showing how to send common HTTP request types: https://www.chilkatsoft.com/http_tutorial.asp
You'll want to send a request like this: https://www.chilkatsoft.com/http_post_url_encoded.asp

application/json not supported when passing multipart files and json together

I have a REST controller method which will take multipart files and JSON object to save as a product with images.
Here is my controller method.
#PostMapping(value = "/{username}/saveProduct", consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.MULTIPART_FORM_DATA_VALUE, MediaType.APPLICATION_OCTET_STREAM_VALUE})
public void saveProduct(#PathVariable("username") String username,
#RequestPart("multipartFiles") List<MultipartFile> multipartFiles,
#RequestPart("product") Product product)
{
Users user = userService.findUserByUsername(username);
List<Images> listOfImages = productService.getBLOBfromFile(multipartFiles, product);
product.setImages(listOfImages);
product.setUser(user);
user.setProducts(product);
userService.saveUser(user);
}
For some reason I am getting this error:
"timestamp": "2021-01-18T20:05:32.409+00:00",
"status": 415,
"error": "Unsupported Media Type",
"trace": "org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json' not supported\r\n\tat org.
From postman I am sending
I tried using #RequestParam and #ModelAttribute as well. Did not work for me.
Also, this method was working when I was writing MVC app.

Spring Boot Content Type Error even when specified in Kotlin

I have an issue in Spring Boot with Kotlin
I have a function that accepts all major Content Types as defined below:
#PostMapping(
value = ["/users/new"],
consumes = [
MediaType.APPLICATION_JSON_VALUE,
MediaType.APPLICATION_XML_VALUE,
MediaType.MULTIPART_FORM_DATA_VALUE,
MediaType.APPLICATION_FORM_URLENCODED_VALUE]
)
fun registerNewUser(
#RequestHeader("X-Forward-For") ipAddress: String?,
newUser: NewUser,
request: HttpServletRequest
): ResponseEntity<ObjectNode> {
var realIPAddress = ipAddress
if (realIPAddress == null) {
realIPAddress = request.remoteAddr
}
return userService.registerUser(realIPAddress!!, newUser)
}
Here is how my NewUser class is defined in kotlin
data class NewUser(val email: String?, val password: String?)
Here is how I am doing the check in the registration function
if (!StringUtils.hasText(newUser.email)) {
return responseHandler.errorResponse(
HttpStatus.BAD_REQUEST,
"Please provide an email address"
)
}
Now when I sent a post request with postman and even axios I keep getting the error as shown in the screenshot below
That error message should only be displayed if email address is not provided. But as you can see clearly, the email address is provided in the JSON Payload.
What could be wrong?
Note: This works when the Content-Type is application/x-www-form-urlencoded but doesn't work when the Content-Type is application/json
put #RequestBody before newUser parameter to specify that input should be inside http body part. by default function parameters in spring are considered to be url parameters which can be further clarified with #RequestParam.
there are 2 ways to insert request parameters into http request. one is to attach request parameters to end of the url and the other is to put in http body with application/x-www-form-urlencoded as the content-type.

form data is not getting posted to spring controller

Form data:
form dat from UI developer tools
user.username:SS
user.email:SGFG#GMAIL.COM
user.firstName:WWW
user.lastName:FF
ext-gen1170:ENV_DEV
ext-gen1171:false
ext-gen1172:false
user.password:
userGroupPermissions:[{"userName":"SS","groupName":"ENV_DEV","permission":"*"}]
Web.xml for the dispatcher servlet:
<servlet-mapping>
<servlet-name>user</servlet-name>
<url-pattern>/spring/</url-pattern>
</servlet-mapping>
Controller:
#RequestMapping(value ="/createUser/", method = RequestMethod.POST)
#Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
#ResponseBody
public String createUser(#RequestParam(value = "user.username", required = true) String username,
#RequestParam(value = "user.email", required = true) String email,
#RequestParam(value = "user.firstName", required = true) String firstName,
#RequestParam(value = "user.lastName", required = true) String lastName,
#RequestParam(value = "userGroupPermissions", required = true) UserGroupPermission userGroupPermissions,
#RequestParam(value = "password", required = false) String password) throws IOException {
Above details will be added to handle the request
There are no errors in console but the breakpoint is not hit when I keep the break point in controller.
I am getting 404 for this code.
Extjs:
var url = '/spring/createUser';
There are two ways to resolve this -- change the way you are sending parameters to Java or change the way you are receiving parameters.
Just change Java
To keep things simple you should change Java.
GET requests should use #RequestParam arguments in Spring controllers in a way you specified.
POST/PUT requests should use #RequestBody argument in Spring controllers.
So the Spring controller should look like this:
#RequestMapping(value ="/createUser/", method = RequestMethod.POST)
#ResponseBody
public String createUser(#RequestBody UserParams params)
Obviously if you need the #Transactional part you should also leave it.
Sending various requests with ExtJS
Here are some examples on how to use Ext.Ajax.request to send various types of requests.
I've used Polish in values so you can also see how encoding of UTF-8 text works.
Query string
Sending in query string means things get encoded directly in URL after ?. E.g. /test?firstName=Imi%C4%99&lastName=Nazwisko.
// (Java/Spring can get this with `#RequestParam`)
Ext.Ajax.request({
url: '/test',
method: 'GET',
params: {
firstName: 'Imię',
lastName: 'Nazwisko'
}
});
Form data
This is used when sending forms in a standard way. Things get encoded in the body of the request, but the format is actually the same as for the query string (e.g. firstName=Imi%C4%99&lastName=Nazwisko).
// (Java/Spring can get this with `#RequestBody`)
Ext.Ajax.request({
url: '/test',
method: 'PUT',
params: {
firstName: 'Imię',
lastName: 'Nazwisko'
}
});
Request payload
This is a JSON communication. Things get encoded in the body of the request, but in a JSON format (e.g. {"firstName":"Imi\u0119","lastName":"Nazwisko"}).
// (Java/Spring can get this with `#RequestBody`)
Ext.Ajax.request({
url: '/test',
method: 'PUT',
jsonData: {
firstName: 'Imię',
lastName: 'Nazwisko'
}
});
Query string in PUT/POST request
You can trick ExtJS to pass parameters in the URL rather then request body. When both params and jsonData are present in the Ext.Ajax.request one of them has to be put in the URL.
So to pass params in the query string use this:
Ext.Ajax.request({
url: '/test',
method: 'PUT',
params: {
firstName: 'Imię',
lastName: 'Nazwisko'
},
jsonData: {}
});
Note the empty jsonData. This will be encoded in request body as {} and can simply be omitted on the receiving end. In this case Java/Spring.
So this way you would receive all params as #RequestParam arguments in your Spring controller.

Oracle MAF-MCS API call

I have created a custom POST api for getting login information in MCS. when i check in SOAPUI it works perfectly fine. the parameters passed are
1. header
Oracle-Mobile-Backend-Id: ********************
2. Authentocation
Username:****************
password: **************
and basic login info username and password as "User1" and "user1" respectively.
Step2:
when i call the API from MAF i am getting an error 400
the post method used is
public static Response callPost(String restURI, String jsonRequest) {
String responseJson = "";
Response response = new Response();
RestServiceAdapter restServiceAdapter = Model.createRestServiceAdapter();
restServiceAdapter.clearRequestProperties();
//restServiceAdapter.setConnectionName("MiddlewareAPI");
// restServiceAdapter.setConnectionName("");
restServiceAdapter.setRequestType(RestServiceAdapter.REQUEST_TYPE_POST);
restServiceAdapter.addRequestProperty("Content-Type", "application/json");
restServiceAdapter.addRequestProperty("Accept", "application/json; charset=UTF-8");
restServiceAdapter.addRequestProperty("Oracle-Mobile-Backend-Id", "**********");
restServiceAdapter.addRequestProperty("Domain", "mcsdem0001");
restServiceAdapter.addRequestProperty("Username", "******");
restServiceAdapter.addRequestProperty("Password", "*****");
//restServiceAdapter.addRequestProperty("Authorization", "Basic "+new String(encodedBytes));
System.out.println("**** Authorization String ****=>"+new String(encodedBytes));
System.out.println("**** RestURI ******=>"+restURI);
System.out.println("**** jsonRequest ******=>"+jsonRequest);
restServiceAdapter.setRequestURI(restURI);
restServiceAdapter.setRetryLimit(0);
try {
responseJson = restServiceAdapter.send(jsonRequest);
int responseCode = restServiceAdapter.getResponseStatus();
response.setResponseCode(responseCode);
response.setResponseMessage(responseJson);
response.setHeader(restServiceAdapter.getResponseHeaders());
} catch (Exception e) {
int responseCode = restServiceAdapter.getResponseStatus();
response.setResponseCode(responseCode);
response.setResponseMessage(responseJson);
}
System.out.println("Response:" + responseJson);
return response;
}
Could anyone please tell me is there any error in the post method??
This can be due to the version conflict. Try to use HttpUrlConnection instead of RestServiceAdapter and let me know if it works.
actually this bit
restServiceAdapter.addRequestProperty("Username", "******");
restServiceAdapter.addRequestProperty("Password", "*****");
doesn't work because you attempt to pass username and password as a HTTP header. Instead it should be passed as you were trying here
restServiceAdapter.addRequestProperty("Authorization", "Basic "+new String(encodedBytes));
However, these should not be encoded bytes but a base64 encoded string in the form
Basis (without the < abd >)
Note that user identity domains only need to be provided in multi-tenant environments. In MCS, the user domain is defined through the mobile backend you connect to.
Frank
Use the MAF MCS Utility library to make it allot easier.
The developer guide can be found here: http://download.oracle.com/otn_hosted_doc/maf/mafmcsutility-api-doc-082015.pdf
Example code:
MBEConfiguration mbeConfiguration =
new MBEConfiguration(
<mbe rest connection>,<mobileBackendId>,
<anonymous key string>,<application key string>,
MBEConfiguration.AuthenticationType.BASIC_AUTH);
mbeConfiguration.setEnableAnalytics(true);
mbeConfiguration.setLoggingEnabled(false)
mbeConfiguration.setMobileDeviceId(
DeviceManagerFactory.getDeviceManager().getName());
MBE mobileBackend = MBEManager.getManager().
createOrRenewMobileBackend(<mobile backend Id>, mbeConfiguration);
CustomAPI customApiProxy = mbe.getServiceProxyCustomApi();
MCSRequest request = new MCSRequest(mobileBackend.getMbeConfiguration());
request.setConnectionName(<Rest connection name>);
request.setRequestURI("/moile/custom/mockup/employees");
request.setHttpMethod(MCSRequest.HttpMethod.POST);
request.setPayload("{\"id\":\"1\"\"name\":\"nimphius\",\"firstName\":\"frank\"}");
request.setRetryLimit(0);
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Content-Type","application/json");
request.setHttpHeaders(headers);
MCSResponse response = customApiProxy .sendForStringResponse(request);
String jsonResponse = (String) response.getMessage();

Resources