Spring RestTemplate get raw json - java

I am using spring restTemplate to consume some rest service which gives me json response. My problem is that when I get the response, it consists of all weird characters instead of simple json response which server is providing. Initially I thought its simple charcter encoding problem but even after setting correct converters I am getting problem. My code -
RestTemplate restTemplate1 = new RestTemplate();
restTemplate1.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
responseEntity = restTemplate1.exchange(uri, request.getMethod(),
new HttpEntity<String>(body, requestHeaders), String.class);
Request headers are created as follows -
private MultiValueMap<String, String> getHeadersInfo(HttpServletRequest request) {
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.put("Accept", Arrays.asList("text/plain, text/plain, application/json, application/*+json, */*, */*"));
map.put("Content-Type", Arrays.asList("application/json; charset=UTF-8"));
return map;
}
Also, if I use getForObject instead of exchange method (as following), then I get the correct result but I can't use this as I need to add some headers.
String a = restTemplate.getForObject(uri, String.class);
I have checked many blogs and stackoverflow questions but they all have suggested the techniques which I have already tried here.
Any suggestions?
Type of response I am getting -
???Oo7???x???4?K\???[?Ð??H??v? ??K?????^\?y???/M???vw???Y?0?6???U???Q????????K?=N{?rZ??n-??8????-?l????????7C?l?????~"???a???Z????U3???3?9???)?J?+???n???d?????? ???\??\o?????? ?????????n????t??2` ???8KLK?R?IJ1????t?\k?û?????j??^#???n??????{??aUV?g\?Q???p? ?V?z???w?R?????? >(IsL,?)?&?TH??.+/LU?Eq??????)??m????n??,4?9hn?{?f18??Z?jW ??5x?JOH%#0$?"?-Ra/??QA;.??*fN#?U?(?????~????s???#??X=W?l?????????Y?T??AR?R???WC=?L^A"t$?R4]J?m]M]???J??my ??ic?,;7OH??}?????'^J????????"'?R????X?X???&???"?`?2^y?-?? i???M??A??ljWu?/|!?qs?v{i?N?'?r?L??3???e??PNV'-.? SN?Y?????:d[#?]?????Wg?,???????????vdq6e?????#Yb??=pM??#<)$ ?8W\???ItQ?P/?R??P?7????:???

Related

How do I return Http Response Content Length for ResponseEntity<List<Object>> without formatting issues or losing data from my response body?

I'm trying to set the content length of my ResponseEntity<List> but the full list isn't returned in the response. I tried something like
long contentLength = staticMethodGetsContentLength(List<Object> objectList);
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Length", String.valueOf(contentLength));
return Response.ok().headers(headers).body(objectList);
and then what is returned is a JSON list like
[
{
"data": "data"
without closing brackets or the full list of objects. Is there an easy fix for this or an alternative to what I'm doing?

how to insert hashtag to request link

i need to insert # symbol in the api request. official documentation transforms https://api.brawlstars.com/v1/players/#2JV9PR99Y to https://api.brawlstars.com/v1/players/%232JV9PR99Y.
so if i send request with %23 i will get 404 Not Found: [{"reason":"notFound","message":"Not found with tag %232JV9PR99Y"}] but with postman i can send requests with %23 replace #. if if send request with # it just returns null json body.
my code:
public Player showPlayerInfo(String playerTag) {
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization","Bearer " + bearerToken);
HttpEntity<String> request = new HttpEntity<String>(headers);
String url = "https://api.brawlstars.com/v1/players/%232JV9PR99Y"; // testing
System.out.println(url);
ResponseEntity<Player> response = restTemplate.exchange(url, HttpMethod.GET, request, Player.class);
return response.getBody();
}
tried to transform link using java.lang URI and URL. also just delete # or %23 from url. api doesnt get it

SpringBoot: How to send and access HashMap <String,String> passed through a RestTemplate HttpGet Request?

I am new to SpringBoot and trying to figure out few things. I am sending HashMap as a part of the RestTemplate HttpMethod.GET call. My question, Is the way I am sending the HashMap as part of the request is correct and if so how do we access the HashMap values from the MicroService2?
MicroService 1
Map<String, String> map=new HashMap<>();
map.put("name", "abc");
HttpEntity<Map<String, String>> entity=new HttpEntity<>(map, headers);
restTemplate.exchange("http:localhost:8080/getdata", HttpMethod.GET, entity , Object.class);
Now how to get the values of the HashMap passed from the MicroService 1.
MicroService 2
#GetMapping("/getdata")
Object getData(#RequestParam HashMap<String,String> user){
sysout(user) // Null
}
I have tested below solution on my machine and its working. You need to pass information in query params as shown in below example:
RestTemplate restTemplate = new RestTemplate();
HttpHeaders header = new HttpHeaders();
header.add("headerName", "headerValue");
HttpEntity<String> entity = new HttpEntity<>(header);
UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUriString("http://localhost:8080/getdata");
//add data as a query params
uriComponentsBuilder.queryParam("name", "abc");
restTemplate.exchange(uriComponentsBuilder.toUriString(), HttpMethod.GET, entity , Object.class);
It's not correct. In controller method you should pass Map interface instead of HashMap implementation, also you should use the same approach when you declare variables I mean:
Map<String,String> map=new HashMap<>() instead of HashMap<String,String> map=new HashMap<>();

Post multipart file and JSON in Rest Assured

I need to send a video file and JSON object in Rest Assured post call.
Structure is like the following:
{ "sample" : {
"name" : "sample-name",
"kind" : "upload",
"video_file" : multipart file here } }
So I did like the following
Code:
given()
.header("Accept", "application/json")
.header(auth)
.config(rConfig)
.body(body)
.multiPart("sample[video_file]", new File("path"), "video/mp4")
.formParam("sample[name]", "Video Upload")
.formParam("sample[kind]", "upload")
.log().all().
expect()
.statusCode(expectedStatusCode)
.post(url);
I can't use application/JSON while using multipart in Rest Assured. I explicitly hardcoded the value in the form param and sent the media file in multipart and now it is working fine.
How can I send all the form param data in a single inner object.
You can do this by using RequestSpecBuilder. It supports all the request parameters and you can easily create multipart request.
Sample code taken from https://github.com/rest-assured/rest-assured/wiki/Usage
RequestSpecBuilder builder = new RequestSpecBuilder();
builder.addParam("parameter1", "parameterValue");
builder.addHeader("header1", "headerValue");
RequestSpecification requestSpec = builder.build();
given().
spec(requestSpec).
param("parameter2", "paramValue").
when().
get("/something").
then().
body("x.y.z", equalTo("something"));
Thanks for your response rohit. I was post this question for handling inner object with formParams. I've completed by creating a Hash Map for formParams. Because formParams method of rest assured can accept Hash map.
Form params map creation:
private static Map<String, String> createFormParamsMap(VideoTagInput videoTag) {
Map<String, String> formParams = new HashMap<>();
formParams.put(createFormParamKey("name"), "name");
formParams.put(createFormParamKey("kind"), "kind");
return formParams;
}
private static String createFormParamKey(String paramKey) {
return "sample[" + paramKey + "]";
// output is like "sample[name]" - I'm forming inner object here for my purpose.
}
Finally send the map to Rest Assured post call function
given()
.header("Accept", "application/json")
.header(auth)
.config(rConfig)
.multiPart("sample[video_file]", new File("path"), "video/mp4")
.formParams(requestParamsMap) // requestParamsMap here.
.log().all().
expect()
.statusCode(expectedStatusCode)
.post(url);
Your approach is definitely not standard.
You cannot have a multipart request and a JSON body, you need to pick one over the 2 approaches: multipart/form-data or application/json request.
The standard way is to have a multipart request with a "json" param containing the serialized JSON payload, and a "file" param with the multipart file.
given()
.contentType(MediaType.MULTIPART_FORM_DATA_VALUE)
.multiPart(file)
.param("json", "{\"sample\":{\"name\":\"sample- name\",\"kind\":\"upload\",\"video_file\":<this is not needed>}}")
But this involves changing your server-side logic.
If you cannot change your server-side logic, you need to serialize your file as (for instance as an array of bytes, or as base64 string) to be set as video_file in your JSON payload. In which case you'll have an application/json content type request, not a 'multipart/form-data'.

Jersey client: How do I POST nested JSON data?

I'm using a Jersey (v 1.17.1) client to communicate with a remote server that I don't have under my control (so I can't see the incomming requests).
I like to issue a POST request with JSON data, that has a structure similar to this example:
{"customer":"Someone",
"date":"2013-09-12",
"items":[{
"sequenceNo":1,
"name":"foo",
"quantity":2,
"price":42,
"tax":{"percent":7,"name":"vat 7%"}
},
{
"sequenceNo":2,
"name":"bar",
"quantity":5,
"price":23,
"tax":{"percent":7,"name":"vat 7%"}
}
]
}
That's my code:
final Client c = Client.create();
final WebResource service = c.resource(SERVER);
final Form form = new Form();
form.add("customer", "Someone");
form.add("date", "2013-09-12");
form.add("items", XXX); // how do I do that?
final ClientResponse response = service.path("aPath").queryParam("param", "value").cookie(new Cookie("token", token))
.type(MediaType.APPLICATION_JSON)
.post(ClientResponse.class, form);
final String raw = response.getEntity(String.class);
System.out.println("Response " + raw);
I tried several approaches (like nesting another Form object), but I always get the same result: The server returns 400 - Bad Request ("The request sent by the client was syntactically incorrect (Bad Request).") I assume because the mandatory parameter items isn't sent correctly.
Does somebody know how I nest JSON data like described? I think it is a common case, but I found no examples in the web.
Form is essentially a Map that limits your values to Strings. What you need is a simple Map (e.g. a HashMap). Every nested element will also be a map. So you will have something like this.
Map<String, Object> data = new HashMap<String, Object>();
data.put("customer", "Someone");
data.put("date", "2013-09-12");
Map<String, Object> item1 = new HashMap<String, Object>();
item1.put("sequenceNo", 2);
item1.put("name", "foo");
data.put("items", Arrays.asList(item1));
This way you can do as much nesting as you need.
Alternatively you can create a few classes that represent your data structures. Jersey will know how to serialize it.
class Item {
String name;
int sequenceNo;
// getters & setters
}
class Data {
String customer;
String date;
List<Item> items;
// getters & setters
}

Categories