I am using restassured framework, and inside it, it has JsonPath class.
JsonPath has a method signature of getList(String path, Class T);
I have attempt to do something like this:
List<JsonPath> myList = myJsonPathObject.getList("mypath", JsonPath.class);
And I get a runtime casting exception. So what would be the correct format in calling this.
I also attempted:
List<JsonPath> myList = myJsonPathObject.getList("mypath", new ArrayList<JsonPath>().getClass());
And that also failed. Actually that failed compilation.
JsonPath is used to extract values out of a JSON document. You cannot get a list of "JsonPath" out of JSON document.
I know this is an old threat, but someone commented and reminded me of this. I actually found an answer to this question.
What I had to do was cast it into a Map<String, Object> and while iterating through the objects, I have to cast the object into the appropriate class.
Map<String, Object> myMap = (Map<String, Object>) myJsonPathObject.get("mypath");
for (String key : myMap.getKeySet()) {
Map<String, Object> subMyMap = (Map<String, Object>) myMap.get(key);
}
So now I can continue to get additional mockup, json within a json.
Related
Is there any Java API for DynamoDB to convert from Item to Map<String, AttributeValue> without implementing it on my own?
EDIT
item.asMap() will return Map<String, Object>, not Map<String, AttributeValue>. Just wondering is there any direct API for this?
Yeah, but I've managed to find it:
// Item item
InternalUtils.toAttributeValues(item)
However, above API is deprecated in newer DynamoDB library which basically delegates the call to ItemUtils which is not deprecated fortunately. So I ended up using this:
ItemUtils.toAttributeValues(item)
Hope this will help others in future!
You can use the method asMap:
Returns all attributes of the current item as a map.
Updated answer:
To get a Map<String, AttributeValue> you can use ItemUtils.toAttributeValue:
Converts an Item into the low-level representation; or null if the input is null.
as follow
Map<String, AttributeValue> map = ItemUtils.toAttributeValue(item);
When running the following line:
Request<Map<String, Object>> requestMap = JsonUtils.fromJson(eventContext.getMessage().getPayloadAsString(), Request.class);
I got this Java exception:
Root Exception stack trace:
org.codehaus.jackson.map.JsonMappingException: Can not instantiate value of type [simple type, class ***.objectmodel.Request] from JSON floating-point number; no one-double/Double-arg constructor/factory method
It looks, for me, that you are trying to turn the String (JSON) into a Request, but you are not specifying which kind of Request (generic parameters) you are trying to parse.
I would try to extract that JSON into a Map like this:
Map<String, Object> actual = JsonUtil.fromJson(encoded, new TypeReference<Map<String, Object>>(){});
Once you are receiving a JSON and wants to deserialize it, I believe it have information and you must create a specific entity to map it, then it would be like this:
Map<String, YourEntity> actual = JsonUtil.fromJson(encoded, new TypeReference<Map<String, YourEntity>>(){});
More details about this solution you can find here.
I found the problem while debugging.
The JSON string was actually not a JSON (particulary only an ip address string "192.168.1.1". So it was not a deserialization mapping issue with the target class (as I supposed initially).
Moral of the fable: The exception is too complicated. A "Not a JSON string" would have been enough.
Is it possible to send map as parameter in a GET call.? i searched and i could find for list and set collection. But did not find anything for map collection.
I tried the following,
My controller method looks like this.
#GetMapping("/test")
public ResponseEntity<?> mapTest(#RequestParam Map<String,String> params) {
LOG.info("inside test with map "+ params );
return new ResponseEntity<String>("MAP", HttpStatus.OK);
}
And i sent the following request from postman
http://localhost:8080/test?params={a:abc,b:bcd}
Everything works without errors and exceptions. But the map which i received looks like key=params , value={a:abc,b:bcd}
I expected the received map to be like key1="a" value1=abc ,key2="b" value2="bcd"
This is documented in the Spring MVC guide:
When an #RequestParam annotation is declared as Map<String, String> or MultiValueMap<String, String> argument, the map is populated with all request parameters.
This means that the response you currently get is the expected result. The Map contains a list of all parameters, and in your case, you only have a single parameter called param.
If you need a custom parameter mapping, you'll have to implement it by yourself. Since you're not using JSON either, you probably have to manually parse the parameter.
However, if your goal is to have a dynamic map of parameters, you can still use the Map<String, String>, but you'll have to change your request into:
http://localhost:8080/test?a=abc&b=bcd
I have Map declared as following:
Map<String, Object> data
I put a String in it and verify its value like this:
assertEquals("value", data.get("key"));
Now, I'd like to rewrite the verification to use assertThat instead of assertEquals. I've tried the following:
assertThat(data.get("key"), equalTo("value"));
And of course it didn't work because of type mismatch:
Wrong 2nd argument type. Found: 'org.hamcrest.Matcher<java.lang.String>', required: 'org.hamcrest.Matcher<? super java.lang.Object>' less...
Explicit type cast of the first argument to String helps, but I'd like to avoid it. For example assertEquals doesn't require type cast.
So, how can I check that the value, which was put into Map object, declared above, is equal to particular String, using the assertThat method?
The "more assertThat" way of doing things would be:
Map<String, Object> expectedData = Collections.singletonMap("key", "value");
asssertThat(data, is(expectedData));
Please note:
Maybe you need type hints for the call to singletonMap
Besides the is matcher, there are other matchers that would allow you to check that data contains your "expected" map data
For your specific problem: that is caused because how generics come into play here; it might be sufficient to use (String) data.get("key") - to tell the compiler that the "actual" argument is of type String.
In the end - I have no idea what your problem is. I wrote down this piece of code:
public void test() {
Map<String, Object> data = new HashMap<>();
data.put("key", "value");
assertThat(data.get("key"), is("value"));
Map<String, Object> expectedData = Collections.singletonMap("key", "value");
assertThat(data, is(expectedData));
}
It compiles fine, and the unit test runs and passes. In other words: actually I am unable to repro your problem.
try this
assertThat(data.get("key"), equalTo("value"))
or
assertThat(data.get("key"), CoreMatchers.equalTo("value"))
I have a Map<String, Object> which I am using as a mapping for a JSON document, however want to create and maintain Java type information at the same time as retaining the structure of the document.
I'm attempting to use Jackson to create the document and it seems to work fine but I'm seeing something strange when attempting to deserialize it. A very simple serialization example:
final ObjectMapper mapper = new ObjectMapper().enableDefaultTyping(ObjectMapper.DefaultTyping.OBJECT_AND_NON_CONCRETE, JsonTypeInfo.As.EXTERNAL_PROPERTY);
final Map<String, Object> map = Maps.newHashMap();
map.put("test", new Date());
final String ser = mapper.writeValueAsString(map);
final Map<String, Object> deser = mapper.readValue(ser, new TypeReference<HashMap<String, Object>>(){});
System.err.println(deser.get("test").getClass());
Gives the serialized form {"test":1410721662084,"#class":"java.util.Date"} which seems fine but when deserializing returns the type of "test" to be Long.
If I change the type serialization to use WRAPPER_ARRAY rather than EXTERNAL_PROPERTY then the type of "test" is correctly returned as Date, but doing this alters the structure of the JSON document so is not something I'm allowed to do. How do I retain the structure of the document as well as allow deserialization back to the correct types?
This is against Jackson 2.4.2.
Deserialization with maps is always tricky as maps don't preserve type information, which makes Jackson resort to #class and that not something you usually want. Instead, you can create a simple class:
public class TestClass {
private Date test;
//getters and setters omitted
}
This class has concrete structure and JSON will serialize it as
{ "test" : 1410721662084}
which is much cleaner and type-safe representation of your object. Then you just need to pass TestClass.class to readValue() method and your test attribute will be magically converted to proper type (Date)