0

I am trying to convert a map value to String. I tried toString() method but it still returns an Object instead of String

response = WS.sendRequest(findTestObject('api/test/TD-4_01_01-Valid'))

Map parsed = response.getHeaderFields()

String messageId = parsed.get('x-message-id').toString();

println messageId

Actual Output:

[C5yZC5hcy5sb2NhbC0xMjgyNi05MzE1LTE=] 

Expected Output:

C5yZC5hcy5sb2NhbC0xMjgyNi05MzE1LTE=
Hakan Dilek
  • 2,178
  • 2
  • 23
  • 35
Sachin Singh
  • 383
  • 3
  • 10
  • 4
    Could you please print the result of `parsed.get('x-message-id').getClass()` – Hakan Dilek Jun 16 '20 at 11:54
  • 1
    Probably `x-message-id` value is an array and that result with `[]`. – KunLun Jun 16 '20 at 11:55
  • 1
    @KunLun Arrays don't override `toString` method so that method would return similar result as Object which is `ArrayType@hexHash` not `[value0, value1, ..]`. It is probably some Collection like List or Set. – Pshemo Jun 16 '20 at 11:58
  • 1
    I was talking about Collection. But thanks for correcting me. – KunLun Jun 16 '20 at 12:03
  • 1
    What is type of `response` variable? Is it `HttpURLConnection`? If yes then its `.getHeaderFields()` should return `Map>` and that should be type of `parsed` variable (see: [What is a raw type and why shouldn't we use it?](https://stackoverflow.com/q/2770321)). This would allow you to use `parsed.get('x-message-id').get(0);`. – Pshemo Jun 16 '20 at 12:05
  • This is supposed to be https://docs.katalon.com/javadoc/com/kms/katalon/core/testobject/ResponseObject.html#getHeaderFields() – Hakan Dilek Jun 16 '20 at 12:08

2 Answers2

4

According to the API, the Map is a Map<String, List<String>> mapping. This is why you get the wrapping with brackets [].

If you want to access the first element in this list, you should call parsed.get('x-message-id').get(0) to access the element with index 0.

Here is the full solution:

response = WS.sendRequest(findTestObject('api/test/TD-4_01_01-Valid'))
Map parsed = response.getHeaderFields()
String messageId = parsed.get('x-message-id').get(0);
println messageId
Hakan Dilek
  • 2,178
  • 2
  • 23
  • 35
  • Almost, but your code will not `.get(0);` method be used on `parsed.get('x-message-id')`. – Pshemo Jun 16 '20 at 12:08
  • You are partially correct. But `x-message-id` can be any type(even a simple string). The creator of question don't tell us the type of `x-message-id`. At first look seems like it's Collection. `Set` is a `Collection` which don't have `get` method, because don't use index. – KunLun Jun 16 '20 at 12:09
  • Why a minus vote? Is this not the correct solution? You're mean. >:{ – Hakan Dilek Jun 16 '20 at 12:09
  • @Pshemo where do you see the compilation problem? – Hakan Dilek Jun 16 '20 at 12:13
  • hey @HakanDilek messageId is a base64 encoded string. – Sachin Singh Jun 16 '20 at 12:16
  • Wait, now I noticed that OP used `groovy` as language tag (which I am not familiar with) so I may be wrong if groovy handles generics little different than Java. In Java when we have raw type map like `Map map = ...;` and we use `map.get(key)` we would get as result reference of type `Object` which means we can't use on it methods which don't belong to Object class like `map.get(key).get(index)`. We would need to properly declare `map` as `Map>` to make it work. Does groovy allow `parsed.get('x-message-id').get(0);` on `Map map`? – Pshemo Jun 16 '20 at 12:20
  • Yes, the map is explicitly defined as a `Map>` according to the api-doc. – Hakan Dilek Jun 16 '20 at 12:23
  • Yes, it but this is definition of *return type* of a method, but variable you used to store result *from* that method in your code is defined as `Map parsed = response.getHeaderFields()` not `Map> parsed = response.getHeaderFields()`. In `Java` this would cause problem because *raw* types make method use Object where generic type is missing so `parsed.get('x-message-id')` would return value of `Object` type which doesn't have `get()` method. Does this problem not exist in `groovy`? Does it automatically adds generics to `Map parsed`? – Pshemo Jun 16 '20 at 12:31
  • Using a raw `Map` this way is ok in Groovy. Generic type specification are not required. – Hakan Dilek Jun 16 '20 at 13:05
3

ResponseObject#getHeaderFields returns a Map of String keys to a List of String objects as vales. You simply need to get the List of String objects for the key x-message-id and since you expect it to return a single result, find any.

ResponseObject response = WS.sendRequest(findTestObject('api/test/TD-4_01_01-Valid'));

Map<String, List<String>> parsed = response.getHeaderFields();

List<String> messageIdList = parsed.get("x-message-id");

String messageId = messageIdList.stream().findAny().orElseThrow(IllegalStateException::new);
Jason
  • 5,154
  • 2
  • 12
  • 22