I have a project in Springboot and MongoDB, i want to serialize for the api get result the Money result with currency and amount and same when creating object but when i use the classic converter this is my json of my catalog and product list
[
{
"_id": "652274dc3f9cb11dc1118d3d",
"products": [
{
"_id": null,
"name": "ECW",
"description": "new carbon wheel",
"category": null,
"variations": null,
"price": {
"currency": {
"context": {
"providerName": "java.util.Currency",
"empty": false
},
"currencyCode": "AED",
"defaultFractionDigits": 2,
"numericCode": 784
},
"number": 4000,
"factory": {
"defaultMonetaryContext": {
"precision": 0,
"fixedScale": false,
"maxScale": 63,
"amountType": "org.javamoney.moneta.Money",
"providerName": null,
"empty": false
},
"minNumber": null,
"maxNumber": null,
"amountType": "org.javamoney.moneta.Money",
"maximalMonetaryContext": {
"precision": 0,
"fixedScale": false,
"maxScale": -1,
"amountType": "org.javamoney.moneta.Money",
"providerName": null,
"empty": false
}
},
"context": {
"precision": 256,
"fixedScale": false,
"maxScale": -1,
"amountType": "org.javamoney.moneta.Money",
"providerName": null,
"empty": false
},
"zero": false,
"negative": false,
"positive": true,
"negativeOrZero": false,
"positiveOrZero": true,
"numberStripped": 4000
},
"vat": 5,
"active": true
}
],
"date": "2023-10-08T09:22:36.473+00:00",
"publicationDate": null,
"active": true,
"current": true
}
]
As you can see the price serialization is awful so i a, trying to serialize to display only currency and amount
this my dto
@Data
@Builder
public class ProductDto {
@Id
private String id;
private String name;
private String description;
private Category category;
private List<Variation> variations;
private MonetaryAmount price;
private Double vat;
private boolean active;
}
converters for mongo
@Configuration
public class MongoConfiguration {
@Bean
public MongoCustomConversions mongoCustomConversions() {
return new MongoCustomConversions( List.of( new MoneyReadConverter(), new MoneyWriteConverter() ) );
}
}
reader
package com.www.converter;
import javax.money.MonetaryAmount;
import org.javamoney.moneta.Money;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.convert.ReadingConverter;
@ReadingConverter
public class MoneyReadConverter implements Converter<String, MonetaryAmount> {
@Override
public MonetaryAmount convert(String moneyString) {
return Money.parse(moneyString);
}
}
and writer
package com.www.converter;
import javax.money.MonetaryAmount;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.convert.WritingConverter;
@WritingConverter
public class MoneyWriteConverter implements Converter<MonetaryAmount, String> {
@Override
public String convert(MonetaryAmount money) {
return money.toString();
}
}
then in controller
@GetMapping
Flux<CatalogDto> getCatalogs() {
return catalogService.getAll();
}
and in my service
@Override
public Flux<CatalogDto> getAll() {
Flux<Catalog> catalogFlux = catalogRepository.findAll();
return catalogFlux
.map( CatalogMapper::mapToCatalogDto )
.switchIfEmpty( Flux.empty());
}
pom.xml
<dependency>
<groupId>org.javamoney</groupId>
<artifactId>moneta</artifactId>
<version>1.1</version>
</dependency>
i tried to use some lib as jackson but it crashes application like use of ambigus configuration any idea ? like using a json deserializer just for this field in annotation?
So finally i listened chatGpt and added a jackson serializer with a module class
import com.fasterxml.jackson.databind.module.SimpleModule; import org.javamoney.moneta.Money;
then module registrer
then serializer
then in DTO
and finally the output looks alike