unable to pass map to restful method - java

I am trying to call this API via postman:
#POST
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public void printDetails(final MultivaluedMap<String, String> formParams) {
for(String key : formParams.keySet()) {
System.out.println(key + " " + formParams.get(key));
}
}
But the map turns out to be empty. Please help me with the same.
PS: This is the first time I am trying to pass variable number of parameters to the api. I have referred to
sending List/Map as POST parameter jersey and How to access parameters in a RESTful POST method.
I think my mistake is in the way I am passing the parameters in postman: postman image
Please help me with the same. Also please help with how to call this API via an ajax (in JS) call.

Set the request header as "application/x-www-form-urlencoded".
Request body - Select raw and provide values as mentioned below:-
{
"LOCATION": "Singapore"
}

I have found out one possible answer.
#POST
public void printDetails() {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
Map<String, String[]> mapp = request.getParameterMap();
for(String key : mapp.keySet()) {
System.out.println(key + " " + mapp.get(key)[0]);
}
}
Still not sure how to do it by passing "final MultivaluedMap" in the arguments

Related

Camel - how to add request parameter(throwExceptionOnFailure) to url?

I hav following route:
from("quartz2:findAll//myGroup/myTimerName?cron=" + pushProperties.getQuartz())
//.setBody().constant("{ \"id\": \"FBJDBFJHSDBFJSBDfi\" }")
.to("mongodb:mongoBean?database=" + mongoDataConfiguration.getDatabase()
+ "&operation=findAll&collection=" + mongoDataConfiguration.getDataPointCollection())
.process(exchange -> {
exchange.getIn().setBody(objectMapper.writeValueAsString(exchange.getIn().getBody()));
}).streamCaching()
.setHeader(Exchange.HTTP_METHOD, constant(pushProperties.getHttpMethod()))
.setHeader(Exchange.CONTENT_TYPE, constant(MediaType.APPLICATION_JSON_VALUE))
.to(pushProperties.getUrl() + "&throwExceptionOnFailure=false").streamCaching()
As you can see I use throwExceptionOnFailure=false
and I take my url from configuration. But we found out that it works if
pushProperties.getUrl() = localhost:8080/url?action=myaction
and doesn't work in case of
pushProperties.getUrl() = localhost:8080/url
Is there universla way in camel to add request parameter to URL?
something like:
private String buildUrl() {
String url = pushProperties.getUrl();
return url + (url.contains("?") ? "&" : "?") + "throwExceptionOnFailure=false";
}
inside Camel api
That is because in case of localhost:8080/url, after appending it becomes like this
localhost:8080/url&throwExceptionOnFailure=false
which is wrong
It should be
localhost:8080/url?throwExceptionOnFailure=false,
In the first case it works you already have a requestpatam(?action=myaction) so the next one can be added with ampersand(&)
I think you have to add your own logic to compose the endpoint to the http component at the runtime. This is because the CamelContext will process it during the route itself. The parameter throwExceptionOnFailure is a property from the http component.
I don't think that adding the parameter via .setHeader(Exchange.HTTP_QUERY, constant("throwExceptionOnFailure=false")) shoud work because these parameters will be evaluated after the http component get processed, e.g. into the URL destination. Please, take a look at "How to use a dynamic URI in to()":
.toD(pushProperties.getUrl() + "&throwExceptionOnFailure=false")
You could use the simple expression to write a logic to do what you want based on the result of pushProperties.getUrl().
I don't like how Camel configure HTTP component in this case, but this is what it is.
What I suggest is to create a map of config, and append your args to it, and do a manual join with "&", then append it to the main url.
I do it like:
public class MyProcessor {
/**
* Part of Camel HTTP component config are done with URL query parameters.
*/
private static final Map<String, String> COMMON_QUERY_PARAMS = Map.of(
// do not throw HttpOperationFailedException; we handle them ourselves
"throwExceptionOnFailure", "false"
);
#Handler
void configure(Exchange exchange, ...) {
...
Map<String, String> queryParams = new HashMap<>();
queryParams.put("foo", "bar");
message.setHeader(Exchange.HTTP_QUERY, mergeAndJoin(queryParams));
...
}
private String mergeAndJoin(Map<String, String> queryParams) {
// make sure HTTP config params put after event params
return Stream.concat(queryParams.entrySet().stream(), COMMON_QUERY_PARAMS.entrySet().stream())
.map(entry -> entry.getKey() + "=" + entry.getValue())
.collect(Collectors.joining("&"));
}
}
Note that toD needs optimization but in that case, HTTP_QUERY cannot be used.
When the optimised component is in use, then you cannot use the headers Exchange.HTTP_PATH and Exchange.HTTP_QUERY to provide dynamic values to override the uri in toD. If you want to use these headers, then use the plain to DSL instead. In other words these headers are used internally by toD to carry the dynamic details of the endpoint.
https://camel.apache.org/components/3.20.x/eips/toD-eip.html

Null token returned

I'm testing API endpoints. The problem is when I check on Swagger, it returns a valid token, but in my testing it returns NULL. Can you point out where I'm doing the wrong thing?
public static void createOrganization() {
Map<String, String> org = new HashMap();
org.put("directorName", "name");
org.put("email", "email#gmail.com");
org.put("website", "www.site.com");
org.put("phoneNumber", "000111");
String registrationToken = given().
contentType("application/json").
body(org).
when().
post("/v3/organizations").
then().
extract().path("registrationToken");
System.out.println("Token: "+ registrationToken);
Output: Token: null
UPDATE:
Maybe I'm using extract() incorrectly, maybe there's a different solution to use the generated values later. Since for registerDevice() I'm getting NULL as well.
public static void registerDevice(){
String clientDeviceId =
given().
param("phoneNumber", "000111").
param("model", "samsung").
param("platform", "0").
param("push_token",SenimEnvironmentVars.testPushToken).
param("uuid", SenimEnvironmentVars.testUUID).
param("version", "7.1").
when().
post("/v3/user-devices").
then().
contentType("application/json").
extract().path("clientDeviceId");
System.out.println("Device ID: "+ clientDeviceId); //also prints NULL
}
Is there any other ways to generate tokens, device IDs etc. and use them later?
As documentation says
You can extract values from the response or return the response
instance itself after you've done validating the response by using the
extract method
So try to write after then some validating method like contentType(JSON).

How to get the cookie value from a Rest Webservice

Which annotation from Jax-RS api was used to retrieve the cookie value?
I tried with the below code
public String getCookieValue(#Context HttpHeaders headers){
headers.getCookies()
}
above code snippet gives a Map. how to retrieve a specific cookie value from it..!
Thanks
According to javadoc, headers.getCookies() call retrieves you "a read-only map of cookie name (String) to Cookie".
Map<String, Cookie> cookies = hh.getCookies();
Cookie myCookie = cookies.get("your cookie name");
I believe you're looking for #CookieParam
Since you have mentioned to return String and you are returning a map object, it must not be working.
Try this:
public String getCookieValue(#Context HttpHeaders headers){
return headers.getCookies().toString;
}

Java : How to handle POST request without form?

I'm sending a http post request from javascript, with some json data.
Javascript
var data = {text : "I neeed to store this string in database"}
var xhr= new XMLHttpRequest();
xhr.open("POST","http://localhost:9000/postJson" , true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
xhr.send(data);
xhr.setRequestHeader("Connection", "close");
//Also, I've tried a jquery POST
//$.post('postJson', {'data=' : JSON.stringify(data)});
//But this doesn't make a request at all. What am I messing up here?
Route
POST /postJson controllers.Application.postJson()
Controller
public static Result postJson(){
//What should I write here to get the data
//I've tried the below but values is showing null
RequestBody rb=request().body();
final Map<String,String[]> values=rb.asFormUrlEncoded();
}
What is the way to parse the POST request body?
Much thanks!
Retreive the request body directly as JSON... no need to complicate your life.
public static Result postJson() {
JsonNode rb = request().body().asJson();
//manipulate the result
String textForDBInsertion = rb.get("text").asText(); //retreives the value for the text key as String
Logger.debug("text for insertion: " + textForDBInsertion
+ "JSON from request: " + rb);
return ok(rb);
}
Also, I recommend you use the AdvancedRestClient Chrome plugin for testing. This way you can eliminate from the equation client-side code errors.
Cheers!

Ajax calling a java Rest API

I am having ajax problems that I cannot figure out, and need some help... I am using Spring for my REST api and my ajax calls don't seem to work... I have searched the forums and haven't been able to find an answer:
My java Spring api is as follows:
#Controller
#RequestMapping("api")
public class RecentRestController {
RecentService recentService;
#Autowired
public void PersonRestController(RecentService recentService) {
this.recentService = recentService;
}
/**
* Add recent lake, then get recently viewed lakes and users ordered by timestamp
* #param handle
* #return
*/
#RequestMapping(value = "recent/weather/{auser}/{temp}/{windspeed}/{winddeg}/{laketag}", method = RequestMethod.GET)
#ResponseBody
public RecentlyViewedList getRecentlyViewedLakes(#PathVariable String auser, #PathVariable Integer temp,
#PathVariable Integer windspeed, #PathVariable Integer winddeg, #PathVariable String laketag) {
RecentlyViewedList rvl = recentService.getRecentlyViewedWeather(auser, temp, windspeed, winddeg, laketag);
return rvl;
}
When I use ajax to call this Java REST from ajax it doesn't seem to work. My ajax call looks as follows from html/php:
new $Ajax.Request('http://localhost:8080/server/api/weahter/lake/' + agruments.auser + '/' + arguments.windspeed +'/' + arguments.winddeg + '/' + arguments.laketag, {
type : "GET",
//:url : recenturl,
//cache : false,
async : false,
crossDomain: true,
dataType : 'jsonp',
//data: arguments,
success : function(recent) {
alert("SUCESS");
var i=0;
var lakecount = recent.lake.length;
var usercount = recent.user.length;
alert("lakecount:" + lakecount);
alert("usercount:" + usercount);
},
error : function(XMLHttpRequest, textStatus, errorThrown) {
alert("An error has occurred making the request: " + errorThrown);
},
});
It never seems to work. It never calls my REST api correct.. What am I doing incorrectly?
Something is wrong with how I calling my REST service..
Any help is greatly appreciated..
Thanks in advance.
As you are checking for a #GET request, the most obvious thing to do is to try to hit the API directly from a browser ( type in your URL field
http://localhost:8080/server/api/weahter/lake/' + agruments.auser + '/' + arguments.windspeed +'/' + arguments.winddeg + '/' + arguments.laketag
with the parameters resolved ).
Other thing you should be checking is that your context path is 'server' as that is where the URL is pointing.
Also you have and spelling error in the first parameter of the URL: 'agruments' instead of 'arguments'
Yeah, the request has recent in it. What I cannot figure out is that if I build it manualy:
url : 'http://localhost:8080/server/api/recent/lake/nightstalker/3/3/3/TXFORK'
it works. But when I build it with variables, it does not.

Categories