I am creating a Jersey web service with dropwizard. The client is using JsonP for cross domain ajax messages.
I got a resource method which looks like this:
#Path("/addUser")
#GET
#UnitOfWork
public String registerPortalUser(#Context HttpServletRequest req, #QueryParam("callback") String callback, #QueryParam("thedata") MyClass recordData) throws Throwable
{ .. }
I get the callback parameter as I expect, but instead of receiving a single Json string which is supposed to be injected to the MyClass member, I get many parameters which are all the MyClass member names and its values. Meaning, instead of receiving everything as a single Json string, I get all the members apart.
What can cause this?
The issue was with the client.
The client sent a json like this:
var thedata =
{
member1 = "value1",
member2 = "value2"
}
What solved it was sending it like this:
var thedata=
[ thedata:
{
member1 = "value1",
member2 = "value2"
}
]
After changing it, Jersey recognized it as the requested parameter
You're apparently sending a null MyClass object to the server. Your client code might look like
MyClass myC = new MyClass();
//populate MyClass fields
WebTarget target = client.target(UriBuilder.fromUri("http://localhost:8088/YourWebApp").build());
String res =(String) target.path("addUser").queryParam("thedata", myC).request().accept(MediaType.TEXT_PLAIN).get(String.class);
Related
I am trying to pass a String array from my typescript
tmp : Array<string> = [];
So I have a function which takes in this array as a parameter input
passValues(test : Array<string>) {
........
// some method to call post method from service
}
So in service
public passingOfValues( test : Array<string> ) : Observable<Array<string>> {
let headers = new Headers({ 'Content-Type': 'application/json'} );
let options = new RequestOptions({ headers: headers);
let response = this.http.post(this.basePath + this.modulePath + '/getArrayValue', {'test' : test }, options)
.map(this.extractData)
.catch(this.handleError);
return response;
}
But I am getting errors such as System property [org.owasp.esapi.devteam] is not set
And I read on other posts that I have to stringify the array before passing to backend.
Is there a reason why I need to stringify / also can I just pass the raw array?
EDIT 1 :
including backend controller codes
public ResponseEntity<?> getArrayValues( ArrayList<String> test ) {
logger.debug("### Test if array has a size ###" + test.size());
}
Apparently size already shows 0 from here.
EDIT 2 :
While debugging, i realised that the SQL at the back is receiving
say
HOME CHARACTER(20 OCTETS)
does this make any difference?
Like passing of string into octets or do I have to do some conversion?
Sorry if I have alot of questions am also working hard on debugging and learning more about it!
Most of the developers like JSON data as request and it's good practice in RESTful apis. why?
JSON format is {key1: value1, key2: value 2,....}
You are passing
this.http.post(this.basePath + this.modulePath + '/getArrayValue',{'test' : YOUR_ACTUAL_ARRAY})
form the front-end. The httpClient.post(url,body,options?) has url and body as mandatory. How can you get it in back-end? Since you have body only,
public ResponseEntity<?> getArrayValues(#RequestBody List<String> test) {
// codes
}
Key of passed parameter from front-end test and variable which
listens in back-end should be in same name. Otherwise
#RequestBody("KEY_NAME") List<String> any_variable
As you asked from comment, you may have two key value pairs. Eg : { "test" : value1, "tmp": value2}. Assume value1 and value2 both are String array.
this.http.post(this.basePath + this.modulePath + '/getArrayValue',{'myJson' : YOUR_JSON})
There are lot of way(Eg : Gson,ObjectMapper etc). I use another way.
Create a class called TestTmpConverter
class TestTmpConverter{
List<String> test;
List<String> tmp;
//No-argument constructors & Argument constructors
//Getters
}
In controller
public ResponseEntity<?> getArrayValues(#RequestBody List<TestTmpConverter> myJson ) {
List<TestTmpConverter> test=myJson.getTest();
List<TestTmpConverter> tmp=myJson.getTmp();
// Do your work
}
I only showed one way.There are a lot of way to pass data to back-end like #RequestParam, #PathVariable etc. I feel now you get something how you can pass the data.
For your client put your data directly on POST's body:
public passingOfValues( test : Array<string> ) : Observable<Array<string>> {
let headers = new Headers({ 'Content-Type': 'application/json'} );
let options = new RequestOptions({ headers: headers);
let response = this.http.post(this.basePath + this.modulePath + '/getArrayValue',
test, options)
.map(this.extractData)
.catch(this.handleError);
return response;
}
On your REST service use the #RequestBody annotation:
public ResponseEntity<?> getArrayValues(#RequestBody String[] test ) {
logger.debug("### Test if array has a size ###" + test.size());
}
I am facing an issue while making a request body to do an API call in Java.
Required Body
{
"id" : [1,2]
}
I have an integer array with me lets say arr, I am creating the request something like:-
JSONObject jsonObject = new JSONObject();
jsonObject.put("id",Arrays.toString(arr));
String stringBody = jsonObject.toJSONString();
RequestSpecification specification = RestAssured.with();
specification.body(stringBody);
Response response = specification.post(endpoint);
What it actually does is make the request body as something like below.
{
"id" : "[1,2]"
}
As it sends the value as String so my server throws an error, Expected a list of items but got type \"unicode\".
Can somebody help me in here. How do I send it in raw format instead of String.
Use
jsonObject.put("id",Arrays.asList(arr));
to build the json body.
At client side I use the following code:
HashMap<String, String> paramMap = new HashMap<>();
paramMap.put("userId", "1579533296");
paramMap.put("identity", "352225199101195515");
paramMap.put("phoneNum", "15959177178");
HttpClient client = new HttpClient();
PostMethod method = new PostMethod("http://localhost:8088/requestTest");
HttpMethodParams p = new HttpMethodParams();
for (Map.Entry<String, String> entry : paramMap.entrySet()) {
p.setParameter(entry.getKey(), entry.getValue());
}
method.setParams(p);
client.executeMethod(method);
And the code of my server-side is like this:
#RequestMapping("/requestTest")
public void requestTest(HttpServletRequest request) throws IOException {
String userId = request.getParameter("userId");
String identity= request.getParameter("identity");
String phoneNum= request.getParameter("phoneNum");
System.out.println(userId+identity+phoneNum);
}
but I got the null value of userId,identity,and phoneNum,so how can I get the value of them? I know I can use method.setParameter(key,value) to set the parameter at client-side and use getParameter(key) to get the parameter value, but I just curious if there any way to get the value at server-side set by HttpMethodParams.
I think , you are getting confused between user defined parameters set in HttpServletRequest and HttpMethodParams .
As per JavaDoc of - HttpMethodParams ,
This class represents a collection of HTTP protocol parameters
applicable to HTTP methods.
These are predefined parameters specific to that HTTP method (see this)and has nothing to do with - HttpServletRequest parameters.
Request parameters need to be set as illustrated here
You have to also note that all these classes (HttpClient, PostMethod, HttpMethodParams etc ) that you are using on client side are from Apache to just be a convenient way to generate and call a HTTP end point but eventually what you will have on server side is a HttpServletRequest and there system is not Apache HttpClient specific.
So all you got on server side is to extract a named header or headers using - getHeaders() , getIntHeader() , getHeaderNames() , getDateHeader() , getProtocol() etc . Server side is standardized so you shouldn't see anything like - HttpMethodParams there.
You have to send your parameters using HttpServletRequest.
HttpMethodParams represent a collection of HTTP protocol parameters applicable to HTTP methods. List of Http method parameter can be found here.
But if you want to send it forcibly by HttpMethodParams you can set the JSON representation of your parameter in one of the variables of HttpMethodParameter and retrieve its value using that variable name.
Sample Code:
HttpMethodParams p = new HttpMethodParams();
p.setCredentialCharset("{userId":1579533296}");
//for loop not required
//your code
Now you can parse that JSON using ObjectMapper and get your required value.
Sample Code:
HttpMethodParams p = new HttpMethodParams();
JSONObject jsonObj = new JSONObject(p.getCredentialCharset());
jsonObj.get("userdId");
Note: This may work but not the recommended way.
So I have in my code POST method :
#POST
#Path("/send/{userPost}")
#Consumes(MediaType.APPLICATION_JSON)
#Produces("application/json")
public Response sendUser(#PathParam("userPost") String userPost ) {
List<Post>userPosts = new ArrayList();
Post post = new Post(99,userPost,"Bartek Szlapa");
userPosts.add(post);
User user = new User(99,"Bartek","Szlapa",userPosts);
String output = user.toString();
return Response.status(200).entity(output).build();
}
unfortunately its not working. I'm getting 404 error. Server is configured correctly because other methods work perfectly. Funny thing is that when I remove {userPost} , parameter : #PathParam("userPost") String userPost and send empty request : http://localhost:8080/JavaAPI/rest/api/send it works - I'm getting new User object with null at some fields. Do you know why I cannot send parameter ? Thanks in advance for help! :)
What you are sending is not a path parameter to send your value as a path parameter based on your api , let us say you are trying to send "test"
http://localhost:8080/JavaAPI/rest/api/send/test
if you want to use query params
#POST
#Path("/send")
#Consumes(MediaType.APPLICATION_JSON)
#Produces("application/json")
public Response sendUser(#QueryParam("userPost") String userPost ) {
and your request should be
http://localhost:8080/JavaAPI/rest/api/send?userPost=test
Your "userPost" parameter is not in the Path : localhost:8080/JavaAPI/rest/api/send?=test
You defined this path :
#Path("/send/{userPost}")
So, your URI should be :
localhost:8080/JavaAPI/rest/api/send/test
I have a rest method which takes two parameters one map parameter, and the other is a String variable
#POST
public returnValue postMethod( Map<String,String> anotherMap,
#QueryParam("name") String name
) {}
It is easy to pass each parameter by itself where
the map parameter can be passed using XML as follow :
ClientResponse response = service
.type(MediaType.APPLICATION_XML)
.accept(MediaType.APPLICATION_XML)
.post(ClientResponse.class, map).getEntity(ClientResponse.class).
and the QueryParam can be passed as usual :
service.type(MediaType.APPLICATION_FORM_URLENCODED_TYPE)
.accept(MediaType.APPLICATION_JSON_TYPE)
.post(ClientResponse.class, f)
where f is a Form ,
the question is : how can we pass both parameter together from the same Java client ?
So you're asking - how do I POST a Map and pass a String as a query param? With sending and receiving XML.
Here's how I'd do it:
ClientBuilder clientBuilder = ClientBuilder.newBuilder();
//Do some building code
Client client = clientBuilder.build();
WebTarget target = client.target(endPoint);
Response response = target
.queryParam("name", "value")
.request(MediaType.APPLICATION_XML_TYPE)
.post(Entity.entity(map), MediaType.APPLICATION_XML_TYPE);
Hope this helps.