Using DataContractJsonSerializer - json

I am trying to host a WCF service that responds to incoming requests by providing a json output stream. I have the following type
[DataContract]
[KnownType(typeof(List<HubCommon>))]
[KnownType(typeof(Music))]
[KnownType(typeof(AppsAndPlugins))]
[KnownType(typeof(Notifications))]
[KnownType(typeof(Scenes))]
[KnownType(typeof(Skins))]
[KnownType(typeof(Ringtones))]
[KnownType(typeof(Alarms))]
[KnownType(typeof(Widgets))]
[KnownType(typeof(Wallpapers))]
[KnownType(typeof(Soundsets))]
public class HubCommon{}
In my *.svc.cs file I do the following
List<HubCommon> hubContent = _ldapFacade.GetResults(query);
MemoryStream stream = new MemoryStream();
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(HubCommon));
serializer.WriteObject(stream,hubContent);
So essentially I am trying to serialize a List to Json but I get the following error on the "WriteObject" execution:-
The server encountered an error processing the request. The exception message is 'Type 'System.Collections.Generic.List`1[[HubContentCore.Domain.HubCommon, HubContentCore, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' with data contract name 'ArrayOfHubCommon:http://schemas.datacontract.org/2004/07/HubContentCore.Domain' is not expected. Add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.'
What am I missing here ?
Thanks in advance.

The type of your DataContractJsonSerializer is HubCommon but you are writing an object of type List<HubCommon> and HubCommon is not added to the KnownTypAttribute

Related

How to handle JSON in a Kafka topic?

I'm building a Java application in which there are some JSON objects (in particular AnyJson objects from com.satori.rtm.model.AnyJson) and I want to send these objects in a Kafka Topic. Should I send them in AnyJson o String type? I'm asking this because the constructor KafkaProducer<K, V> seems to have some problem to handle JSON values when (de)serialization.
This in my producer configuration
Properties props= new Properties();
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaBrokerEndpoint);
props.put(ProducerConfig.CLIENT_ID_CONFIG, "KafkaProducer");
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, IntegerSerializer.class);
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class);
kafkaProducer= new KafkaProducer<Integer, AnyJson>(props);
where JsonSerializer.class is from org.springframework.kafka.support.serializer.JsonSerializer;
I have seen there are multiple packages that handle the JSON objects (as kafka.utils.json, com.google.gson.JsonObject;, etc).
Then when running
ProducerRecord<Integer, AnyJson> record= new ProducerRecord<Integer, AnyJson>(topic, json);
kafkaProducer.send(record);
I have the following exception
No serializer found for class com.satori.rtm.connection.GsonSerializer$JsonElementWrapper
Any help?
You may want to use org.apache.kafka.common.serialization.ByteArraySerializer for key and value serializations.
Now you should configure your producer record with byte[].
Then use ObjectMapper from Jackson (http://www.baeldung.com/jackson-object-mapper-tutorial ) to convert any json object to byte array.

Spring integration, How to use #Transformer to convert from/to JSON?

My question is how to pass object between SI endpoints?
Almost every example I found is using XML settings, I am using Annotation and don't know how to solve this exception
Caused by: java.lang.IllegalArgumentException: Could not resolve 'json__TypeId__' in 'javaTypes'.
at org.springframework.integration.support.json.AbstractJacksonJsonObjectMapper.createJavaType(AbstractJacksonJsonObjectMapper.java:68)
at org.springframework.integration.support.json.Jackson2JsonObjectMapper.extractJavaType(Jackson2JsonObjectMapper.java:116)
at org.springframework.integration.support.json.Jackson2JsonObjectMapper.extractJavaType(Jackson2JsonObjectMapper.java:52)
at org.springframework.integration.support.json.AbstractJacksonJsonObjectMapper.fromJson(AbstractJacksonJsonObjectMapper.java:61)
at org.springframework.integration.json.JsonToObjectTransformer.doTransform(JsonToObjectTransformer.java:87)
at org.springframework.integration.transformer.AbstractTransformer.transform(AbstractTransformer.java:33)
... 18 more
People suggest using xml to fix this, for example
<bean class="org.springframework.amqp.support.converter.DefaultClassMapper">
<property name="defaultType" value="foo.MyObject" />
</bean>
But I am using annotation to create transformer to process messages receive from channel, like this
#Bean
#Transformer(inputChannel="fromTcp", outputChannel="toHandler")
JsonToObjectTransformer jsonToObjectTransformer() {
ObjectMapper mapper = new ObjectMapper();
JsonObjectMapper<JsonNode, JsonParser> jm = new Jackson2JsonObjectMapper(mapper);
return new JsonToObjectTransformer(jm);
}
Actually I have no clue how to pass object between SI endpoints. I could only pass String and SI use default serialize to handle String to byte[], and byte[] to String.
The converter needs to know what type to convert to; the error you are getting is because you haven't provided a type so it falls back to looking for a header containing type information.
The equivalent of the xml is:
#Bean
#Transformer(inputChannel="fromTcp", outputChannel="toHandler")
JsonToObjectTransformer jsonToObjectTransformer() {
return new JsonToObjectTransformer(MyObject.class);
}

java.lang.UnsupportedOperationException: Attempted to serialize java.lang.Class: org.hibernate.proxy.HibernateProxy

I'm using a Restful web service (Jersy implementation) with a JSF application and used Json to get the data as follows:
carObjectDao = new GenericDAO<carObject>(carObject.class);
List<carObject> allCars = carObjectDao.readAll();
Gson gson = new Gson();
String carString = gson.toJson(allCars);
System.err.println(carString );
return carString ;
i run the application in debug mode and allCars is filled with the data correctly, but after that an exception is thrown :
java.lang.UnsupportedOperationException: Attempted to serialize java.lang.Class: org.hibernate.proxy.HibernateProxy. Forgot to register a type adapter?
i don't know the root cause of the exception
This is a known problem: Could not serialize object cause of HibernateProxy
JSon can't deserialize HibernateProxy objects, so you either unproxy or remove em.
Or, you can eager fetch the lazy data.
Try parsing through ObjectMapper as
carObjectDao = new GenericDAO<carObject>(carObject.class);
List<carObject> allCars = carObjectDao.readAll();
String carString = new ObjectMapper().writeValueAsString(allCars);
System.err.println(carString );
return carString ;

Error when using Message class as return type in WCF service

I am having a WCF service. The service is so that it returns the result as string. When I run the application, I am getting this error message.
The operation 'GetTemplate' could not be loaded because it has a parameter or return type of type System.ServiceModel.Channels.Message or a type that has MessageContractAttribute and other parameters of different types. When using System.ServiceModel.Channels.Message or types with MessageContractAttribute, the method must not use any other types of parameters.
My corresponding code is like this:
Interface:-
[OperationContract]
[WebGet(
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Wrapped,
UriTemplate = "GetTemplate/templateid={templateID}"
)]
Message GetTemplate(string templateID);
Implementation:-
public Message GetTemplate(string templateID)
{
string jsonText = TemplateManager.GetJSONTemplate(templateID);
return WebOperationContext.Current.CreateTextResponse(jsonText,
"application/json; charset=utf-8", Encoding.UTF8);
}
When I googled t I got to know that, we can't use any serializable object as parameter or return type when using Message. I want to accept the templateid as parameter, in order to get the corresponding template. Is there any way to accept a parameter without having this error?
Thanks in advance.
Vipin Menon
The error message basically translates into this: using the Message type is an all or nothing proposition, if you have a Message type output then you must either have a single Message parameter for the operation or no parameter at all. You should read this old but good MSDN article on the using the WCF Message type and what it can do for you. The Message class drops the level of coding abstraction from using standard .NET classes down to the WCF "plumbing" level where you manipulate the soap XML message your operation is receiving and manually create the soap XML message the operation will be sending out.
It's not clear why you are trying to use Message as a return type but you cannot use it in the manner of your sample code in the question.

How to serialize this JSON Array String using Jackson Annotations?

[{"ID":"hzQ8ll","CreationDate":"Thu, 24 Feb 2011 12:53:31 GMT","Count":6,"Name":"SOMETAG"}]
The inside is of type Tag so I just wrote this Java class:
public class Tags {
public List <Tag>tags;
}
But I get com.sun.jersey.api.client.ClientHandlerException:
org.codehaus.jackson.map.JsonMappingException: Can not deserialize instance of com.test.Tags out of START_ARRAY token
I am using Jersey with the JacksonJsonProvider like this:
ClientConfig config = new DefaultClientConfig();
config.getClasses().add(JacksonJsonProvider.class);
Then I just do a simple Jersey client call:
ClientResponse response = builder.get(ClientResponse.class);
Tags tags = response.getEntity(Tags.class);
Any ideas? Most of the time my outermost elements had a name associated to it so this is new to me. Thanks for any help
You possibly have to declare a Tag[] instead of a List<Tag>.
I had a similar issue with a different JSON library.
It seems to have to do with difficulties introspecting generic containers.
You have a strange usage of get().
http://jersey.java.net/nonav/apidocs/1.5/jersey/com/sun/jersey/api/client/UniformInterface.html#get%28java.lang.Class%29
Return and argument type should be the same.
Either:
ClientResponse resp = builder.get(ClientResponse.class);
or
Tag[] resp = builder.get(Tag[].class);
Anyway, it seems tha the problem is that your JSON data is an array and it is being deserialized into something that is not (Tags).
Try this directly:
Tag[] tags = response.getEntity(Tag[].class);