kotlin data class HttpMessageNotReadableException - json

I'm trying this code with postman, but nothing works, why ?
What i send :
{
"name":"front_msel",
"gitlabId": "83",
"fichierVersion":"VERSION"
}
My spring controller :
#RestController
#RequestMapping("/projects")
class ProjectController(val projectRepository: ProjectRepository) {
private val log = LoggerFactory.getLogger(ProjectController::class.java)
#PostMapping()
fun saveProject(#RequestBody payload: Project): String {
log.info("project: '{}'", payload.toString())
return projectRepository.save(payload).gitlabId?:"-1"
}
}
What i get :
{
"timestamp": 1505917417221,
"status": 400,
"error": "Bad Request",
"exception": "org.springframework.http.converter.HttpMessageNotReadableException",
"message": "JSON parse error: Can not construct instance of com.......model.Project: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of com.......model.Project: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?)\n at [Source: java.io.PushbackInputStream#66ba61d9; line: 2, column: 2]",
"path": "/projects"
}
My project data class :
data class Project(val name:String?, val gitlabId: String?, val fichierVersion: String?)
I doubled check params, it's not a wording mistake, what does this things doesn't works ?
EDIT :
Thanks to Todd, the problem was resolve by adding null value to my param, to generate a zero argument constructor. Thanks !
data class Project(val name:String? = null, val gitlabId: String? = null, val fichierVersion: String? = null)

I got this to work by making two slight changes.
First, since all your Project fields are nullable, provide default values so the compiler will generate a zero argument constructor:
data class Project(val name:String? = null, val gitlabId: String? = null, val fichierVersion: String? = null)
Second, it seems that Spring wants your fields to be in snakey_case rather than camelCase, so change your payload to this:
{
"name":"front_msel",
"gitlab_id": "83",
"fichier_version":"VERSION"
}

Related

Unexpected end-of-input: expected close marker for Object while consuming messages from Kafka topic

I am trying to consume messages from kafka-topic in which json contents are not serialized. The topic has been produced with actual JSON without serialization like below.
JSON:
{
"guests": [
{
"guest_ref_id": "000000012331202",
"ids": {
"profile_ids": [
"1234"
]
}
}
],
"case_id": "500g000000Tw5ggAAB",
"case_creation_ts": 1580512345,
"state_of_origin": "CA"
}
Now, when I try to consume the message from the topic using below configuration and listener-code, I am getting serialization exception as Unexpected end-of-input: expected close marker for Object
application.yml
topics:
input:
datasource: test-topic
---
kafka:
bootstrap:
servers: localhost:9092
consumers:
consumer:
key:
deserializer: org.apache.kafka.common.serialization.StringDeserializer
value:
deserializer: org.apache.kafka.connect.json.JsonDeserializer
Listener Code:
#Topic(value = ["\${topics.input.datasource}"])
fun receiveNotifications(
#Suppress("UNUSED_PARAMETER") #KafkaKey keys: List<String?>,
#MessageBody notifications: List<GuestDTO>,
topics: List<String>,
partitions: List<Int>,
offsets: List<Long>,
kafkaConsumer: Consumer<String, GuestDTO>
) = runBlocking {
notifications.forEach { notification ->
// business logic
}
logger.info("Delete Request Processed -> Commiting Offset")
kafkaConsumer.commitSync()
}
#JsonIgnoreProperties(ignoreUnknown = true)
#JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy::class)
data class GuestDTO(
var guests: List<Guest>? = null,
var caseId: String = ""
)
#JsonIgnoreProperties(ignoreUnknown = true)
#JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy::class)
data class Guest(
var guestRefId: String = "",
var ids: Map<String, List<String>>? = null
)
I am not sure exactly how to handle this, the above setup works when the json messages are serialized and produced to the topic without any issues.
But the catch is there is no control over for me to produce the serialized JSON message. So, looking for a way to consume non-serialized JSON messages from kafka topics. Thanks in advance for the help to be provided!
If the data isn't valid JSON, then you must use StringDeserializer, then try-catch the JSON parsing yourself.
Your other option is to introduce a Schema Registry, but if you don't control the producers, then it won't fully solve the problem

how to get value from json via variable in typescript?

supposing I have to read some data from some json files(i18n), every json file may look like:
{
"foo": "1",
"bar": "2",
...
}
I don't know how many fields this json have(it can be expanded), but it's fields look like
{
[prop: string]: string
}
besides, all the json files share the same fields.
when I try to read a value from this json via:
//a can be expanded, I'm not sure how many fileds does it have
let a = {
name: "dd",
addr: "ee",
}
//I'm confident a has a field "name"
let b = "name";
console.log(a[b]);
the error message is:
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type
how could I fix it?
The error you're encountering is because the keys in a is not just any string (in fact, it can only be "name" or "add"), but b can be a string of any arbitrary value. If you are very sure that b represents a key found in the object a, you can hint TypeScript as such:
let b: keyof typeof a = "name";
Attempting to assign any arbitrary string value to b will lead to an error:
// This will cause an error
let b: key typeof a = "foobar";
See proof-of-concept on TypeScript Playground.

WCF REST JSON request: Formatter exception

I have a enum as one of the parameters in my Rest API.
End Point contract:
List<Transaction> GetTransactions(int employeeID, int recordOffset, int recordLimit, TransactionType transactionType = TransactionType.All);
InputJSON Request:
{
"employeeID":"123",
"recordOffset": 0,
"recordLimit": 80,
"transactionType":"All"
}
I'm getting a 400 bad request, when i pass this input JSON with transactionType key.
Please let me know how, i should be passing an ENUM value in the json request.
public enum TransactionType
{
All = 0,
Incoming = 1,
Outgoing = 2
}
Exception Message:
The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://Services/2015/03:transactionType. The InnerException message was 'There was an error deserializing the object of type Entities.TransactionType. The value 'All' cannot be parsed as the type 'Int64'.'. Please see InnerException for more details
The parameter expected is an int.
You should be passing an int value of 0, 1 or 2 in the JSON request here.
Depending on how you build up your JSON request, you could add the value of the Enum you want, e.g transactionType = TransactionType.All
This way, you can actually use your Enum when building up your request to ensure you use viable values.

'_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Iterable<dynamic>' in type cast

I am trying to use built_value and json_serializable together for parsing json response coming from server to model classes.
Following are the dependencies:
built_collection: ^4.0.0
built_value: ^6.1.4
dev_dependencies:
build_runner: ^1.0.0
built_value_generator: ^6.1.4
json_serializable: ^1.4.0
Following is the code that I have written
abstract class UserData implements Built<UserData, UserDataBuilder>{
String get user_first_name;
String get user_last_name;
String get user_mobile;
String get email;
String get user_type;
Company get company;
UserType get type;
UserData._();
factory UserData([updates(UserDataBuilder b)]) = _$UserData;
static Serializer<UserData> get serializer => _$userDataSerializer;
}
abstract class Company implements Built<Company, CompanyBuilder>{
String get id;
Company._();
factory Company([updates(CompanyBuilder b)]) = _$Company;
static Serializer<Company> get serializer => _$companySerializer;
}
abstract class UserType implements Built<UserType, UserTypeBuilder>{
String get id;
UserType._();
factory UserType([updates(UserTypeBuilder b)]) = _$UserType;
static Serializer<UserType> get serializer => _$userTypeSerializer;
}
Serializers class code :
#SerializersFor(const [
UserData
])
Serializers serializers = _$serializers;
Serializers standardSerializers =
(serializers.toBuilder()..addPlugin(StandardJsonPlugin())).build();
Following is the response that I am getting from server.
{
"user": {
"id": "505d27b0-acaa-11e8-b916-21359608417b",
"email": "example#gmail.com",
"user_first_name": "Pankaj",
"user_last_name": "P",
"user_dob": null,
"active_status": 1,
"user_region_id": null,
"user_base_currency": "USD",
"user_address": null,
"is_god_user": 0,
"is_super_user": 0,
"profile": null,
"advanced_search": 0,
"region": null,
"company": {
"id": "24e311f0-acaa-11e8-8750-8de299c7797b",
"company_name": "SHPR A",
"company_address": null,
"company_logo": "",
"company_constitution": "pvt_ltd",
"company_email": "shpra#mail.com",
"state": null,
"country": null,
"postal_code": null,
"date_of_establishment": null,
"number_of_employees": null,
"company_turnover": null,
"vendor_id": null
},
"type": {
"id": "5eeebe55-fdf4-11e7-81f1-ac7ba173bed6",
"user_type_code": "11",
"user_type_name": "ADMIN",
"user_category": "SHIPPER"
}
}
}
Finally I am trying to parse using the following line of code
serializers.deserializeWith(UserData.serializer, json.decode(response.body))
However I am getting following error
failed due to: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Iterable<dynamic>' in type cast
Please throw some light into what might be causing this issue.
I was also facing the same issue, replace
serializers.deserializeWith(UserData.serializer, json.decode(response.body))
with
standardSerializers.deserializeWith(UserData.serializer, json.decode(response.body))
The stack trace could tell you where the error is, so if you have one, it might be useful.
At some point, you are assigning a Map<String, dynamic> value to a variable typed Iterable<dynamic>. That sounds like JSON decoding going wrong, something is assuming a list and getting a map.
There is nothing in the provided code that assumes Iterable<dynamic>, so it's most likely in the json_serializable package that things blow up.
So, are you certain that the JSON input text you have is the correct format for the json_serializable decoder? (I'm not familiar with that package, so I can only guess).

Golang Error Types are empty when encoded to JSON

I'm trying to encode some JSON for a REST api, everything is working fine except for some errors. For example, with this struct:
type TemplateResponse struct {
Message string
Error error
Template Template
}
Encoded with this data:
res := TemplateResponse{"Template not found.", fmt.Errorf("There is no template on this host with the name " + vars["name"]), Template{}}
json.NewEncoder(w).Encode(res)
Returns:
{
"Message": "Template not found.",
"Error": {},
"Template": {
"Name": "",
"Disabled": false,
"Path": "",
"Version": ""
}
}
I'm getting this seemingly randomly across my application, where 'error' types are being returned as empty. Any ideas?
Thanks!
Because error is just an interface. It may hold a value of any concrete type that implements it.
In your example you used fmt.Errorf() to create an error value. That calls errors.New() which returns a pointer to a value of the unexported errors.errorString struct. Its definition is:
type errorString struct {
s string
}
This struct value will be marshaled, but since it has no exported fields (only exported fields are marshaled), it will be an empty JSON object: {}.
The "fix" is: don't marshal values of "general" interfaces, relying on that the dynamic values can be marshaled into JSON meaningfully. Instead you should add a field that stores the error string (the result of error.Error()), and omit the Error error field from marshaling, e.g.:
type TemplateResponse struct {
Message string
Error error `json:"-"`
ErrorMsg string
Template Template
}
Of course then you also need to set / fill the ErrorMsg field before marshaling.
Or if you don't need to store the error value in the struct, remove that field completely:
type TemplateResponse struct {
Message string
ErrorMsg string
Template Template
}
If you still want to keep the Error error field (and not the ErrorMsg field), then you need to implement a custom marshaling logic by implementing the json.Marshaler interface where you can "convert" the error value to a meaningful string for example (or into another value that can be marshaled properly).