Jackson xml (de)serialization with custom boolean format - jackson-dataformat-xml

I have xml file:
<?xml version="1.0" encoding="UTF-8"?>
<ADDRESSOBJECTS>
<OBJECT ID="1802267" NAME="SomeName" ISACTIVE="1" />
</ADDRESSOBJECTS>
and correponding classes in kotlin:
#JacksonXmlRootElement(localName = "ADDRESSOBJECTS")
class AddressingObjectCollection {
#JacksonXmlProperty(localName = "OBJECT")
#JacksonXmlElementWrapper(useWrapping = false)
open lateinit var objects: List<AddressingObject>
}
and
class AddressingObject : Serializable {
#JacksonXmlProperty(isAttribute = true, localName = "ID")
open var id: Long = 0
#JacksonXmlProperty(isAttribute = true, localName = "NAME")
open lateinit var name: String
#JacksonXmlProperty(isAttribute = true, localName = "ISACTIVE")
open var isActive: Boolean = false
}
when I try to deserialize I get error:
val deserialized = mapper.readValue(File(file).readText(), AddressingObjectCollection::class.java)
error:
Cannot deserialize value of type `boolean` from String "1": only "true"/"True"/"TRUE" or "false"/"False"/"FALSE" recognized
How to tell jackson to (de)serialize this format properly?

For this purpose I use Json attributes:
#JsonProperty("ISACTIVE")
#JacksonXmlProperty(isAttribute = true, localName = "ISACTIVE")
#JsonDeserialize(using = CustomBooleanDeserializer::class)
open var isActive: Boolean = false
And CustomBooleanDeserializer:
class CustomBooleanDeserializer : JsonDeserializer<Boolean>() {
override fun deserialize(p: JsonParser?, ctxt: DeserializationContext?): Boolean {
if (p?.currentTokenId() == JsonTokenId.ID_STRING){
var text = p.text
if (text == "1") return true
}
return false;
}
}
It works for me.

Related

Load section of config file into dictionary in net 5.0

I have to work on an application in net 5.0 not developed by me, that I don't know.
I would like to add a section in the config file and load it into a dictionary.
this is the section in config file:
{
"MyApp": {
"ServiceExceptions": [
{ "Key1": "Value1" },
{ "Key2": "Value2" }
]
}
}
this code load the configuration:
public static IConfiguration GetConfiguration(string name)
{
IConfiguration oConfiguration = null;
string basePath = Path.GetDirectoryName(typeof(SharedHelper).Assembly.Location);
string configPath = Path.Combine(basePath, "Config");
string fileConfig = string.Format("{0}.{1}.json", name, Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"));
oConfiguration = new ConfigurationBuilder()
.SetBasePath(configPath)
.AddJsonFile(fileConfig, optional: false, reloadOnChange: true)
.Build();
return oConfiguration;
}
this is the code to load to bind the dictionary, but myExceptions is null:
_Configuration = GetConfiguration("BD.Authentication.DWA");
Dictionary<string, string> myExceptions = null;
_Configuration.GetSection("MyApp:ServiceExceptions").Bind(myExceptions);
Debug.WriteLine(myExceptions.Count); // throws exception null reference
somewhere are loaded the data, but i dont know how to pull out
Just move the config file in:
{
"MyApp": {
"ServiceExceptions":
{ "Key1": "Value1" },
{ "Key2": "Value2" }
}
}
and retrive the values:
var serviceTypeExceptions = _Configuration.GetSection("MyApp:ServiceExceptions").Get<Dictionary<string, string>>();

Save String Array With #AppStorage

In the following example I am saving a String with #AppStorage:
struct ContentView: View {
#AppStorage("text") private var text = ""
var body: some View {
Button("Append text: \(text)") {
text.append("APPEND")
}
}
}
But I want to save a String array, something like this:
#AppStorage("text") private var text = [
"APPEND",
"APPEND"
]
class Storage: NSObject {
static func archiveStringArray(object : [String]) -> Data {
do {
let data = try NSKeyedArchiver.archivedData(withRootObject: object, requiringSecureCoding: false)
return data
} catch {
fatalError("Can't encode data: \(error)")
}
}
static func loadStringArray(data: Data) -> [String] {
do {
guard let array = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? [String] else {
return []
}
return array
} catch {
fatalError("loadWStringArray - Can't encode data: \(error)")
}
}}
VIEW_
struct ContentView: View {
#State var TempTextArray: [String] = []
#AppStorage("textArray", store: UserDefaults(suiteName: "group.de.domain.MyApp")) var items: Data = Data()
var body: some View {
VStack(spacing: 30){
Button("Append text:") {
TempTextArray.append("Append")
items = Storage.archiveStringArray(object: TempTextArray)
}
Button("GET String Array"){
print(Storage.loadStringArray(data: items))
}
}
}}

Bad Request with 400 status code in Spring boot

Recently I am using Spring boot framework with Kotlin. Every thing is all okey with GET method. But when registering a new user with POST method I go faced some problem having Bad Request with status code 400.
Here is my code associate with my spring boot project
User.kt
#Entity
#Table(name = "user_info")
data class User(
#Id
#SequenceGenerator(
name = "user_seq",
sequenceName = "user_seq",
allocationSize = 1
)
#GeneratedValue(
strategy = SEQUENCE,
generator = "user_seq"
)
#Column(
name = "id",
updatable = false
)
val id: Long = -1,
#Column(
name = "first_name",
nullable = false,
length = 50,
updatable = true
)
val firstName: String,
#Column(
name = "last_name",
nullable = false,
length = 50,
updatable = true
)
val lastName: String,
#Column(
name = "email",
nullable = true,
length = 150,
updatable = true
)
val email: String,
#Column(
name = "gender",
nullable = false,
length = 2,
updatable = true
)
val gender: String,
#Column(
name = "date_of_birth",
nullable = false,
updatable = true
)
val dateOfBirth: LocalDate,
#Column(
name = "country",
nullable = false,
length = 50,
updatable = true
)
val country: String
)
UserController.kt
#RestController
#RequestMapping(
path = [
"/api/v1/"
]
)
class UserController(
#Autowired private val userService: UserService
) {
#PostMapping("register")
fun registerUser(#RequestBody user: User) {
userService.registerUser(user)
}
#GetMapping("users")
fun getUsers(): List<User> {
return userService.getUsers()
}
#GetMapping("user/{id}")
fun getUsers(#PathVariable("id") id: Long): User {
return userService.getUserInfo(id)
}
}
My Request Payload is
POST http://localhost:8080/api/v1/register
Content-Type: application/json
{
"first_name" : "Abid",
"last_name" : "Affan",
"email" : "aminul15-5281#diu.edu.bd",
"gender" : "M",
"date_of_birth" : "2019-05-03",
"country" : "Bangladesh"
}
and my response payload is
POST http://localhost:8080/api/v1/register
HTTP/1.1 400
Content-Type: application/json
Transfer-Encoding: chunked
Date: Mon, 01 Mar 2021 05:52:03 GMT
Connection: close
{
"timestamp": "2021-03-01T05:52:03.634+00:00",
"status": 400,
"error": "Bad Request",
"message": ""JSON parse error: Instantiation of [simple type, class com.example.demo.user.User] value failed for JSON property firstName due to missing (therefore NULL) value for creator parameter firstName which is a non-nullable type; nested exception is com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException: Instantiation of [simple type, class com.example.demo.user.User] value failed for JSON property firstName due to missing (therefore NULL) value for creator parameter firstName which is a non-nullable type\n at [Source: (PushbackInputStream); line: 8, column: 1] (through reference chain: com.example.demo.user.User[\"firstName\"])",
"path": "/api/v1/register"
}
Response code: 400; Time: 214ms; Content length: 119 bytes
Add following property in your spring boot configuration
logging.level.org.springframework.web=DEBUG you will get the exact reason for getting 400 Bad requests on console logs.
You used camelCase in your entity - User and snake_case in your request payload. It is recommended not to mix syntax for object mapping. Can you try with this request poayload:
{
"firstName" : "Abid",
"lastName" : "Affan",
"email" : "aminul15-5281#diu.edu.bd",
"gender" : "M",
"dateOfBirth" : "2019-05-03",
"country" : "Bangladesh"
}

Creating a JSON String from a Swift object in Xcode 7+

I have the following class that I need to convert into a JSON String using Xcode 7 and above. In the previous version of Xcode there was a JSONSerelization.toJson(AnyObject) function available, however does not appear in Xcode7 .
I need to convert the following class :
struct ContactInfo
{
var contactDeviceType: String
var contactNumber: String
}
class Tradesmen
{
var type:String = ""
var name: String = ""
var companyName: String = ""
var contacts: [ContactInfo] = []
init(type:String, name:String, companyName:String, contacts [ContactInfo])
{
self.type = type
self.name = name
self.companyName = companyName
self.contacts = contacts
}
I Have set up my test data as follows
contactType =
[
ContactInfo(contactDeviceType: "Home", contactNumber: "(604) 555-1111"),
ContactInfo(contactDeviceType: "Cell", contactNumber: "(604) 555-2222"),
ContactInfo(contactDeviceType: "Work", contactNumber: "(604) 555-3333")
]
var tradesmen = Tradesmen(type: "Plumber", name: "Jim Jones", companyName: "Jim Jones Plumbing", contacts: contactType)
Any help or direction would be appreciated.
I do not think that there is any direct way, even in previous Xcode. You will need to write your own implementation. Something like below:
protocol JSONRepresenatble {
static func jsonArray(array : [Self]) -> String
var jsonRepresentation : String {get}
}
extension JSONRepresenatble {
static func jsonArray(array : [Self]) -> String {
return "[" + array.map {$0.jsonRepresentation}.joinWithSeparator(",") + "]"
}
}
And then implement JSONRepresentable in your modals like below:
struct ContactInfo: JSONRepresenatble {
var contactDeviceType: String
var contactNumber: String
var jsonRepresentation: String {
return "{\"contactDeviceType\": \"\(contactDeviceType)\", \"contactNumber\": \"\(contactNumber)\"}"
}
}
struct Tradesmen: JSONRepresenatble {
var type:String = ""
var name: String = ""
var companyName: String = ""
var contacts: [ContactInfo] = []
var jsonRepresentation: String {
return "{\"type\": \"\(type)\", \"name\": \"\(name)\", \"companyName\": \"\(companyName)\", \"contacts\": \(ContactInfo.jsonArray(contacts))}"
}
init(type:String, name:String, companyName:String, contacts: [ContactInfo]) {
self.type = type
self.name = name
self.companyName = companyName
self.contacts = contacts
}
}

Link to foreign key in JQGrid

I have designed my jqgrid viewmodel as follows,
public class DomainJQGrid
{
public JQGrid DomainsGrid { get; set; }
public DomainJQGrid()
{
DomainsGrid = new JQGrid
{
Columns = new List<JQGridColumn>()
{
new JQGridColumn
{
DataField = "DomainId",
PrimaryKey = true,
Editable = false,
HeaderText = "Domain ID",
Visible = false
},
new JQGridColumn
{
DataField = "ClientId",
Editable = false,
Width = 150,
HeaderText = "Client"
},
new JQGridColumn
{
DataField = "DomainName",
Editable = false,
Width = 150,
HeaderText = "Domain Name"
},
new JQGridColumn
{
DataField = "Registered",
Editable = true,
Width = 100,
DataFormatString = "{0:d}",
HeaderText = "Registered",
}
},
AutoWidth = true,
};
DomainsGrid.ToolBarSettings.ShowRefreshButton = true;
}
}
And I am binding the datasource to using my controller as follows.
return gridModel.DomainsGrid.DataBind(hmEntity.DomainProducts);
in the above model, instead of my ClientId, how can I bring ClientName from my Client table?
If I am understanding correctly, you'd like to be able to define a column that uses a property of an object property.
Assuming you have a property of type Client, named Client, you'd want to be able to do something like:
DataField = "Client.ClientName"
Unfortunately, that doesn't seem to work. There may be a different notation that can be used for this, but I couldn't find any documentation when I ran into this scenario.
For the sake of getting past the issue, and at the cost of dirtying up the model, I chose to add a property to support the grid. It's on my 'technical debt' list and am hoping to find a better solution when I pay that back.
If you want to suffer that same burden :), add this to your DomainProduct class (again, assuming you have a Client property):
[NotMapped]
public string ClientName
{
get { return Client == null ? "" : Client.ClientName; }
}
And then just use ClientName for the DataField value.

Resources