JSON.registerObjectMarshaller doesn't work in bootstrap - json

When I want to test a customized "render as JSON " method, I used the following code
class BootStrap{
def init = { servletContext ->
....
println "change the json before format"
JSON.registerObjectMarshaller(Date) {
println "JSON DATE MARSHAL"
return it.format("yyyy-MM-dd HH:mm:ss")
}
println "change the json after format"
}
}
but what printed in the console is like this:
| Compiling 1 source files
| Running Grails application
Active MQ start. ConsumerURL is failover:ssl://xxx.
change the json before format
change the json after format
|Server running. Browse to http://xxx
the strange thing is that the "JSON DATE MARSHAL"didn't be printed.
But it worked when I put the code in a controller.
I don't know what happened.
Any suggestion will be appretiated.
Update:
Like railsdog said, it seems the closure in the init didn't work.
What I supposed the date format in JSON is like this:2016-12-15 16:44:21
But what I get is 2016-12-15T08:44:21Z.
When I put the marshaller in controller, it worked, and the date format in JSON is as expected:
2016-12-15 16:44:21.
I also get the console output:"JSON DATE MARSHAL".

I would assume that registering the object marshaller doesn't actually execute/invoke the closure, hence no debug is emitted.

Instead of registering marshaller check out property grails.databinding.dateformats in your grails application config. You can add there more different date formats which should be handled by your app.

Related

Camel - json body is consumed after have used jsonpath

i'm using camel in a rest context and i've to manipulate a json got from a request . It's something like:
{
'field1':'abc',
'field2':'def'
}
All i've to do is to extract field1 and field2 and put them in 2 properties, so i tried something like that
<setProperty propertyName="Field1">
<jsonpath>$.field1</jsonpath>
</setProperty>
<setProperty propertyName="Field2">
<jsonpath>$.field2</jsonpath>
</setProperty>
but i get this error:
org.apache.camel.ExpressionEvaluationException:
com.jayway.jsonpath.PathNotFoundException: Expected to find an object with property ['field2'] in path $ but found 'java.lang.String'. This is not a json object according to the JsonProvider: 'com.jayway.jsonpath.spi.json.JsonSmartJsonProvider'.
and after some tests i found out my body was empty after the first use of jsonpath.
The same process applied to an XML using xpath doesn't give any error, and i'm wondering if it's possible to do the same with jsonpath instead to create a mapper object in java. thank you in advance
If the processed Camel message is of type InputStream, this stream can obviously be read only once.
To solve this:
either enable Camel stream caching (http://camel.apache.org/stream-caching.html)
or insert a step (before jsonpath queries) in your route to convert message body to a string (so that it can be read multiple times:
(eg <convertBodyTo type="java.lang.String" charset="ISO-8859-1">) )

Matching the Json schema with the response getting from the API in rest-assured

I have a post API , i want methods of JsonSchemaValidator to be used as I want the whole reponse to be validated rather than selected reponse by performing assertion
I have tried to use
matchesJsonSchemaInClasspath("my file name") and
matchesJsonSchema(my file object)
my reposne is coming to be true, method is getting passed but there is no checking or validation with my schema file
public void directLoginWihSchemaValiadtor(){
File file = new File("C:/Users/abeey/git/SlingAppWebService/Configurations/JsonSchemaValidator_DirectLogin_AWS.json");
jsonasmap.put("contactNo", "some number");
jsonasmap.put("loginType","0");
jsonasmap.put("appid","2");
jsonasmap.put("co*****ode","IN");
JsonSchemaFactory jsonSchemaFactory = JsonSchemaFactory.newBuilder().
setValidationConfiguration(ValidationConfiguration.newBuilder().freeze()).freeze();
given().contentType(ContentType.JSON).body(jsonasmap).when().
post("https://60i*****.execute-api.us-west-2.amazonaws.com/some-api").
then().assertThat().
body(JsonSchemaValidator.matchesJsonSchema(file))).
log().all();
jsonasmap.clear();
}
//body(JsonSchemaValidator.matchesJsonSchemaInClasspath("JsonSchemaValidator_DirectLogin_AWS.json").using(jsonSchemaFactory))
I tried to use jsonSchemaFactory to do this but i didnt get that either on what to set as the draftversion or from where to get it
I am new to this , please bear with me if you found this question too simple to be asked
For such case usually I do following:
use schema generator and create the schema for json body (I use this tool json-schema-generator)
put generated json schemas in the classpath (for example test/resources)
use this code as part of REST Assured test:
.body(matchesJsonSchemaInClasspath("your_schema_name.json"))
If you want to make sure that schema validation is working, you can edit schema file and change the type of any required field to something else and see that your test will fail.
You can refer to this post of mine to see some code samples.

Verify whole json response in jmeter by value or sort Json

I'm not using JMeter too often, and I've run into very specific issue.
My REST response is always "the same", but nodes are not in the same order due to various reasons. As well, I can't put here whole response due to sensitive data, but let's use these dummy one:
First time response might be:
{
"properties":{
"prop1":false,
"prop2":false,
"prop3":165,
"prop4":"Audi",
"prop5":true,
"prop6":true,
"prop7":false,
"prop8":"1",
"prop9":"2.0",
"prop10":0
}
}
Then other time it might be like this:
{
"properties":{
"prop2":false,
"prop1":false,
"prop10":0,
"prop3":165,
"prop7":false,
"prop5":true,
"prop6":true,
"prop8":"1",
"prop9":"2.0",
"prop4":"Audi"
}
}
As you can see, the content it self is the same, but order of nodes it's not. I have 160+ nodes and thousand of possible response orders.
Is there an easy way to compare two JSON responses comparing matching key - values, or at least to sort the response, and then compare it with sorted one in assertion patterns?
I'm not using any plugins, just basic Apache JMeter.
Thanks
I've checked using Jython, you need to download the Jython Library and save to your jmeter lib directory.
I've checked 2 JSONs with Sampler1 and Sampler2, on Sampler1 I've add a BeanShell PostProcessor with this code:
vars.put("jsonSampler1",prev.getResponseDataAsString());
On Sampler2 I've add a BSF Assertion, specifying jython as the language and with the following code:
import json
jsonSampler1 = vars.get("jsonSampler1")
jsonSampler2 = prev.getResponseDataAsString()
objectSampler1 = json.loads(jsonSampler1)
objectSampler2 = json.loads(jsonSampler2)
if ( objectSampler1 != objectSampler2 ):
AssertionResult.setFailure(True)
AssertionResult.setFailureMessage("JSON data didn't match")
Yoy can find the whole jmx in this GistHub
You will most probably have to do this with a JSR223 Assertion and Groovy.
http://jmeter.apache.org/usermanual/component_reference.html#JSR223_Assertion
http://docs.groovy-lang.org/latest/html/api/groovy/json/JsonSlurper.html
Note that if you know Python, you might look at using Jython + JSR223.
I would just set up 10 jp#gc - JSON Path Assertions. Documentation for figuring out JSON Path format is here and you can test how it would work here.
For your example you would the assertion (Add > Assertion > jp#gc - JSON Path Assertions), then to test the prop 1 put:
$.properties.prop1
in the JSON Path field, click the Validate Against Expected Value checkbox, and put
false
in the expected value field. Repeat those steps for the other 9 changing the last part of the path to each key and the value you expected back in the expected value field.
This extractor is jmeter add on found here.

How to include time zone in Web API 2 JSON dates?

How do I configure the JSON dates produced by my Web API 2 Controller to include the time zone?
Data type used for dates in SQL Server are datetime and I don’t have the option of changing the Legacy database.
Breeze uses Json.NET to serialize/deserialize json. You can configure the serializer settings that Breeze uses by creating a custom class that inherits from Breeze.ContextProvider.BreezeConfig. Breeze will automatically discover this class and create an instance of it for all configuration tasks.
Something like this:
public class CustomBreezeConfig : Breeze.ContextProvider.BreezeConfig
{
protected override Newtonsoft.Json.JsonSerializerSettings CreateJsonSerializerSettings()
{
var ret = base.CreateJsonSerializerSettings();
ret.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc;
// ret.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Local;
return ret;
}
}
But before you go down this path please read this (the response specifically):
breezejs: date is not set to the right time
Try returning your DateTime formatted with .ToString() and use a custom date and time format like "K". See: http://msdn.microsoft.com/en-us/library/8kb3ddd4(v=vs.110).aspx#KSpecifier for more information.

java.util.Date unmarshalling form grails json request

I'm facing following error while trying unmarshal java.util.Date from JSON in grails controller.
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object '2011-10-07 10:24:40' with class 'java.lang.String' to class 'java.util.Date'**
Also, I've tried the following method but still no luck, actually I've doubt wether I've implemented following in right way or not because when i put println statements in following method:
public CustomDateBinder(List formats)
Nothing prints on console.
Grails Date unmarshalling
According to the description of your error message you are trying to convert a String to Date, if you want to do it manually you can use the following method in your Controller (since Grails 2)
def val = params.date('myDate', 'dd-MM-yyyy') //Obviously you need to change the format
Check the following post for more info: http://mrhaki.blogspot.com/2012/01/grails-goodness-date-request-parameter.html