Rest Client gives Bad Request for HTTP PUT request - rest

I'm new to Rest Client development. Need your help in figuring out how to get a proper response for below rest service.
curl --location --request PUT 'sandbox-url/TokenGeneratorAPI/v1/update_pay_status' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic {{token}' \
--data-raw '{
"pay_id":000000000,
"status":1,
"amount":0.00,
"pay_method":0,
"pay_sys_ref":"test"
}'
I created a class in client side for request object like below.
public class PaymentRqBean {
#XmlElement(name="pay_id")
String pay_id;
#XmlElement(name="status")
String status;
#XmlElement(name="amount")
String amount;
#XmlElement(name="pay_method")
String pay_method;
#XmlElement(name="pay_sys_ref")
String pay_sys_ref;
public String getPay_id() {
return pay_id;
}
public void setPay_id(String pay_id) {
this.pay_id = pay_id;
}
}
......and getters setters for other attributes
And created a method for calling the web service in another class like below.
public PaymentRsBean callWS(PaymentRqBean pReq) {
PaymentRsBean prs = new PaymentRsBean();
Client client = ClientBuilder.newClient();
client.register(new Authenticator(com.boc.conf.Configurations.objProperty.getProperty("ikUserName"), com.boc.conf.Configurations.objProperty.getProperty("ikPassword")));
WebTarget webTarget = client.target(url);
Invocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_JSON);
Response response = invocationBuilder.accept(MediaType.APPLICATION_JSON).put(Entity.json(pReq));
I'm getting HTTP 400 BAD REQUEST for above. I would be so thankful for any help given in solving this.
(Is it because #XmlRootElement? )

The problem is the way you are defining the attributes of your PaymentRqBean class.
The variables 'pay_id', 'status', 'amount' and 'pay_method' must be of numeric type (int, double...), since the request you launch indicates that they are numeric, not Strings.
"pay_id":000000000,
"status":1,
"amount":0.00,
"pay_method":0

Related

Use groovy-wslite make a post request from CURL request

Hi i have the following CURL request that i'd like to include in a groovy script using the groovy-wslite library put struggling to get the request working.
curl -s -X POST -k -u user:password https://artifactory_url/api/search/aql -H 'Content-Type: text/plain' -d 'items.find({"type":"file","repo":{"$eq": "my-repo-name"},"path":{"$match":"com/mycompany/product1/subcat/mob/*"},"name":{"$match":"*apk"}}).sort({"$desc":["path"]}).limit(1)'
You can use http-builder-ng and your code could look like
compile 'io.github.http-builder-ng:http-builder-ng-CLIENT:1.0.4'
HttpBuilder.configure {
request.uri = 'https://artifactory_url/api/search/aql'
request.auth.basic 'un', 'pw'
request.contentType = 'text/plain'
}.post {
request.body = 'items.find({"type":"file","repo":{"$eq": "my-repo-name"},"path":{"$match":"com/mycompany/product1/subcat/mob/*"},"name":{"$match":"*apk"}}).sort({"$desc":["path"]}).limit(1)'
response.success { FromServer fs, Object body ->
println body
}
}

Missing request header 'authToken' calling RestAPI method

I have this RestAPI method
#GetMapping(path = "/menus",
consumes = "application/json",
produces = "application/json")
public ResponseEntity<List<MenuPriceSummary>> allMenus(HttpServletRequest request, #RequestHeader(value="Authorization: Bearer") String authToken) {
String username = jwtTokenUtil.getUsernameFromToken(authToken);
User user = userService.findByUserName(username);
return ResponseEntity.ok(menuService.allMenus(user));
}
which I call from curl
curl -X GET -H "Content-Type: application/json" -H "Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJsb3Blei5hbnRvbmlvODVAZ21haWwuY29tIiwiZXhwIjoxNTk0MTkzNDYwLCJpYXQiOjE1MzM3MsM0NjB9.9pXvdiRMM5fjE4Ur5nqKvwvRLmNWyn6tY6y5fPXOg_BWEW2sJ8vnrLTXPfiA-Sc6Qk2XTwi6FhlIhFEQKip4aQ" "http://127.0.0.1:1133/canPeris/api/v1/users/menus"
But I got this error:
"status":400,"error":"Bad Request","message":"Missing request header 'Authorization: Bearer' for method parameter of type String"'authToken' for method parameter of type String","tr....
You can't use #RequestHeader that way. The values from the headers get split up by : and added to a Map, so every value containing a : is impossible.
You will have to change your annotation to #RequestHeader(value="Authorization") and then remove the Bearer from the authToken.
Spring MVC provides annotation #RequestHeader that can be used to map controller parameter to request header value .
Can you please change your method to
#GetMapping(path = "/menus",
consumes = "application/json",
produces = "application/json")
public ResponseEntity<List<MenuPriceSummary>> allMenus(
#RequestHeader(value="Authorization") String authToken,
HttpServletRequest request) {
String username = jwtTokenUtil.getUsernameFromToken(authToken);
User user = userService.findByUserName(username);
return ResponseEntity.ok(menuService.allMenus(user));
}
You can also make use of Interceptors to validate headers so that other rest endpoints in your application can make use of it .

Translating curl into Matlab/Webwrite

I have the following curl command I need to sent to a web server using Matlab and webwrite using POST. My problem is that I always get a "Bad request" answer so my syntax must be wrong somehow. Does anybody have an idea how this curl command, sending the body could look like in Matlab using webwrite in a correct way ?
body=$(cat << EOF
{
"order": {
"units": "100",
"instrument": "EUR_USD",
"timeInForce": "FOK",
"type": "MARKET",
"positionFill": "DEFAULT"
}
}
EOF
)
curl \
-X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <AUTHENTICATION TOKEN>" \
-d "$body" \
"https://api-fxtrade.oanda.com/v3/accounts/<ACCOUNT>/orders"
I have just asked a potentially similar question so this may not work first time. However I cannot test without knowing some login details so I can but hope this helps.
data_InputValues = struct ('units',100,'instrument','EUR_USD','timeInForce','FOK','type','MARKET','positionFill','DEFAULT');
MyBody = matlab.net.http.MessageBody(struct('order',data_InputValues));
MyHTTPOptions = matlab.net.http.HTTPOptions(); % use this to change the options if necessary (e.g. extend timeout)
Request = matlab.net.http.RequestMessage;
Request.Method = 'POST';
Request.Header = matlab.net.http.HeaderField('Content-Type','application/json','Authorization: Bearer',AUTHENTICATION TOKEN);
Request.Body = MyBody;
uri = matlab.net.URI('https://api-fxtrade.oanda.com/v3/accounts/<ACCOUNT>/orders');
[response a ~] = Request.send(uri,MyHTTPOptions);
The part I struggle with is generating the MyBody part (in your case this is parsing the order variable's sub-variables). If you get this to work I would be keen to know how! P.S. my question in case it helps: Matlab RESTful PUT Command - net.http - nesting body values
The correct format for the body is as follows:
body = struct('units',100,'instrument','EUR_USD','timeInForce','FOK',...
'type','MARKET','positionFill','DEFAULT');
As for the HTTP headers that you require you can specify them with weboptions when using webwrite.
The syntax for an additional header:
options = weboptions('KeyName','Name','KeyValue','Value')
Where Name and Value are the name of the header and its value respectively.
You must add the headers that you require in weboptions.
For the code you provided, the correct syntax would be as follows:
options = weboptions('MediaType','application/json',...
'KeyName','Authorization: Bearer','KeyValue','Token');
You can then perform the POST request at the URL of interest.
response = webwrite(url,body,options);

Can't able to view a transform in browser using REST in Marklogic 9?

I tried to install below Server-Side JavaScript using this documentation and saved below as rest-sjs
function insertTimestamp(context, params, content)
{
if (context.inputType.search('json') >= 0) {
var result = content.toObject();
if (context.acceptTypes) { /* read */
result.readTimestamp = fn.currentDateTime();
} else { /* write */
result.writeTimestamp = fn.currentDateTime();
}
return result;
} else {
/* Pass thru for non-JSON documents */
return content;
}
};
exports.transform = insertTimestamp;
I tried to push this using below curl cmd:
curl --anyauth --user public\admin:admin -X PUT -i --data-binary #"C:/Users/name/Desktop/rest.sjs" -H "Content-type: application/vnd.marklogic-javascript" 'http://localhost:9963/v1/config/transforms/js-example'
When I used localhost:9963 and went to /v1/config/transforms I can see:
<rapi:transforms xmlns:rapi="http://marklogic.com/rest-api">
<rapi:transform>
<rapi:name>rest-tsm</rapi:name>
<rapi:source-format>javascript</rapi:source-format>
<rapi:transform-parameters/>
<rapi:transform-source>/v1/config/transforms/rest-tsm</rapi:transform-source>
</rapi:transform>
</rapi:transforms>
But when I went though the module /v1/config/transforms/rest-tsm I am seeing an error response:
<error-response xmlns="http://marklogic.com/xdmp/error">
<status-code>406</status-code>
<status>Unacceptable Type</status>
<message-code>REST-UNACCEPTABLETYPE</message-code>
<message>
REST-UNACCEPTABLETYPE: (err:FOER0000) No acceptable content type: None of the requested types text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 can be provided
</message>
</error-response>
I can see the the module in Modules db. Which worked fine when I try to insert a document by using the transform.
Why can't I view the transform in the browser?
Unfortunately, that rest endpoint isn't very browser friendly. The required/acceptable Accept header values do not match what browsers will normally send.
When you made the GET request through your browser, it was sending the following Accept header:
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept
This field contains a semicolon-separated list of representation schemes ( Content-Type metainformation values) which will be accepted in the response to this request.
Unfortunately, the v1/config/transform/{name} (GET) REST endpoint is strict in what it will accept for the Accept header and expects a specific value:
The MIME type of the data expected in the response, either application/xslt+xml or application/xquery.
If you use the example CURL command from the documentation, and customize for your transform URI, it will return the expected response.
curl --anyauth --user public\admin:admin -X GET -i \
-H "Accept: application/xquery" \
http://localhost:9963/v1/config/transforms/rest-tsm

How to get a paypal access token using REST request

I'm trying to get this working https://developer.paypal.com/webapps/developer/docs/integration/direct/make-your-first-call/
Using Java + Jersey application. It seems like I'm missing something in POST params.
public String getPaypalToken() {
Client client = Client.create();
WebResource webResource = client.resource("https://api.sandbox.paypal.com/v1/oauth2/token");
MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl();
queryParams.add("username", CLIENT_ID + ":" + SECRET );
queryParams.add("grant_type", "client_credentials");
ClientResponse response = webResource.accept("application/json").acceptLanguage("en_US").type("application/x-www-form-urlencoded").post(ClientResponse.class, queryParams);
return response.toString();
}
Using previous code I got: POST https://api.sandbox.paypal.com/v1/oauth2/token returned a response status of 401 Unauthorized.
This CURL command line option just works fine:
curl -X POST https://api.sandbox.paypal.com/v1/oauth2/token -H "Accept: application/json" -H "Accept-Language: en_US" -u "EOJ2S-Z6OoN_le_KS1d75wsZ6y0SFdVsY9183IvxFyZp:EClusMEUk8e9ihI7ZdVLF5cZ6y0SFdVsY9183IvxFyZp" -d "grant_type=client_credentials"
Any suggestions will be appreciated.
J.
The -u option in curl sends a base64 encoded "username:password" string. I don't think adding client id / secret to the queryParams map does the same (unless Jersey treats the 'username' key differently which I don't think it does).
You should instead try
webResource.header("Authorization", "Basic " + Base64.encode(CLIENT_ID + ":" + SECRET.getBytes()))
Just sharing my solution:
Dictionary<string, string> sdkConfig = new Dictionary<string, string>();
sdkConfig.Add("mode", "sandbox");
string clientid = "<your client id>";
string secretid = "<your secret id>";
string accessToken = new OAuthTokenCredential(clientid, secretid, sdkConfig).GetAccessToken();
I previously encountered unauthorized response using RestSharp, then found this. I'm using paypal .net sdk from nuget package.
Reference.